diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index 645ac692..7f3b1e1e 100644 --- a/src/ch7xxx/Makefile.am +++ b/src/ch7xxx/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index df66d03d..5bfb7c5b 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -25,6 +25,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include "xf86.h" #include "xf86_OSproc.h" @@ -32,6 +37,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" +#include "i830_xf86Crtc.h" +#define DPMS_SERVER +#include #include "../i2c_vid.h" #include "ch7xxx.h" @@ -41,151 +49,179 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * driver for the Chrontel 7xxx DVI chip over DVO. */ -static void ch7xxxSaveRegs(I2CDevPtr d); +static struct ch7xxx_id_struct { + int vid; + char *name; +} ch7xxx_ids[] = { + { CH7011_VID, "CH7011" }, + { CH7009A_VID, "CH7009A" }, + { CH7009B_VID, "CH7009B" }, +}; + +#define ID_ARRAY_SIZE (sizeof(ch7xxx_ids) / sizeof(ch7xxx_ids[0])) + +struct ch7xxx_reg_state { + CARD8 regs[CH7xxx_NUM_REGS]; +}; + +struct ch7xxx_priv { + I2CDevRec d; + struct ch7xxx_reg_state SavedReg; + struct ch7xxx_reg_state ModeReg; + CARD8 save_TCTL, save_TPCP, save_TPD, save_TPVT; + CARD8 save_TLPF, save_TCT, save_PM, save_IDF; +}; + +static void ch7xxx_save(I2CDevPtr d); static CARD8 ch7xxxFreqRegs[][7] = { { 0, 0x23, 0x08, 0x16, 0x30, 0x60, 0x00 }, { 0, 0x23, 0x04, 0x26, 0x30, 0x60, 0x00 }, { 0, 0x2D, 0x07, 0x26, 0x30, 0xE0, 0x00 } }; - -static Bool ch7xxxReadByte(CH7xxxPtr ch7xxx, int addr, unsigned char *ch) +static char *ch7xxx_get_id(int vid) { - if (!xf86I2CReadByte(&(ch7xxx->d), addr, ch)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, - X_ERROR, "Unable to read from %s Slave %d.\n", - ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); - return FALSE; + int i; + + for (i = 0; i < ID_ARRAY_SIZE; i++) { + if (ch7xxx_ids[i].vid == vid) + return ch7xxx_ids[i].name; } - return TRUE; -} - -static Bool ch7xxxWriteByte(CH7xxxPtr ch7xxx, int addr, unsigned char ch) -{ - if (!xf86I2CWriteByte(&(ch7xxx->d), addr, ch)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); - return FALSE; - } - - return TRUE; -} - -static void *ch7xxxDetect(I2CBusPtr b, I2CSlaveAddr addr) -{ - /* this will detect the CH7xxx chip on the specified i2c bus */ - CH7xxxPtr ch7xxx; - unsigned char ch; - - xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting ch7xxx\n"); - - ch7xxx = xcalloc(1, sizeof(CH7xxxRec)); - if (ch7xxx == NULL) - return NULL; - - ch7xxx->d.DevName = "CH7xxx TMDS Controller"; - ch7xxx->d.SlaveAddr = addr; - ch7xxx->d.pI2CBus = b; - ch7xxx->d.StartTimeout = b->StartTimeout; - ch7xxx->d.BitTimeout = b->BitTimeout; - ch7xxx->d.AcknTimeout = b->AcknTimeout; - ch7xxx->d.ByteTimeout = b->ByteTimeout; - ch7xxx->d.DriverPrivate.ptr = ch7xxx; - - if (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_VID, &ch)) - goto out; - - ErrorF("VID is %02X", ch); - if (ch!=(CH7xxx_VID & 0xFF)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); - goto out; - } - - - if (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_DID, &ch)) - goto out; - - ErrorF("DID is %02X", ch); - if (ch!=(CH7xxx_DID & 0xFF)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); - goto out; - } - - - if (!xf86I2CDevInit(&(ch7xxx->d))) { - goto out; - } - - return ch7xxx; - -out: - xfree(ch7xxx); return NULL; } - -static Bool ch7xxxInit(I2CDevPtr d) +/** Reads an 8 bit register */ +static Bool +ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch) { - CH7xxxPtr ch7xxx = CH7PTR(d); + if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, + X_ERROR, "Unable to read from %s Slave %d.\n", + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + return FALSE; + } - /* not much to do */ return TRUE; } -static ModeStatus ch7xxxModeValid(I2CDevPtr d, DisplayModePtr mode) +/** Writes an 8 bit register */ +static Bool +ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch) { - CH7xxxPtr ch7xxx = CH7PTR(d); + if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + return FALSE; + } + + return TRUE; +} + +static void * +ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr) +{ + /* this will detect the CH7xxx chip on the specified i2c bus */ + struct ch7xxx_priv *dev_priv; + CARD8 vendor, device; + unsigned char ch; + char *name; + + dev_priv = xcalloc(1, sizeof(struct ch7xxx_priv)); + if (dev_priv == NULL) + return NULL; + + dev_priv->d.DevName = "CH7xxx TMDS Controller"; + dev_priv->d.SlaveAddr = addr; + dev_priv->d.pI2CBus = b; + dev_priv->d.StartTimeout = b->StartTimeout; + dev_priv->d.BitTimeout = b->BitTimeout; + dev_priv->d.AcknTimeout = b->AcknTimeout; + dev_priv->d.ByteTimeout = b->ByteTimeout; + dev_priv->d.DriverPrivate.ptr = dev_priv; + + if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor)) + goto out; + + name = ch7xxx_get_id(vendor); + if (!name) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, + "ch7xxx not detected; got 0x%02x from %s slave %d.\n", + vendor, dev_priv->d.pI2CBus->BusName, + dev_priv->d.SlaveAddr); + goto out; + } + + + if (!ch7xxx_read(dev_priv, CH7xxx_REG_DID, &device)) + goto out; + + if (device != CH7xxx_DID) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, + "ch7xxx not detected; got 0x%02x from %s slave %d.\n", + device, dev_priv->d.pI2CBus->BusName, + dev_priv->d.SlaveAddr); + goto out; + } + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, + "Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", + name, vendor, device); + + if (!xf86I2CDevInit(&dev_priv->d)) { + goto out; + } + + return dev_priv; + +out: + xfree(dev_priv); + return NULL; +} + +static xf86OutputStatus +ch7xxx_detect(I2CDevPtr d) +{ + return XF86OutputStatusUnknown; +} + +static ModeStatus +ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) +{ + if (mode->Clock > 165000) + return MODE_CLOCK_HIGH; return MODE_OK; } -static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode) +static void +ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode) { - CH7xxxPtr ch7xxx = CH7PTR(d); - int ret; - unsigned char pm, idf; - unsigned char tpcp, tpd, tpf, cm; - CARD8 *freq_regs; - int i; + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; + CARD8 tvco, tpcp, tpd, tlpf, idf; - ErrorF("Clock is %d\n", mode->Clock); - - if (mode->Clock < 75000) - freq_regs = ch7xxxFreqRegs[0]; - else if (mode->Clock < 125000) - freq_regs = ch7xxxFreqRegs[1]; - else - freq_regs = ch7xxxFreqRegs[2]; - - for (i = 0x31; i < 0x37; i++) { - ch7xxx->ModeReg.regs[i] = freq_regs[i - 0x31]; - ch7xxxWriteByte(ch7xxx, i, ch7xxx->ModeReg.regs[i]); - } - -#if 0 - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx idf is 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - idf, tpcp, tpd, tpf); - - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx pm is %02X\n", pm); - - if (mode->Clock < 65000) { + if (mode->Clock <= 65000) { + tvco = 0x23; tpcp = 0x08; tpd = 0x16; - tpf = 0x60; + tlpf = 0x60; } else { + tvco = 0x2d; tpcp = 0x06; tpd = 0x26; - tpf = 0xa0; + tlpf = 0xa0; } + ch7xxx_write(dev_priv, CH7xxx_TCTL, 0x00); + ch7xxx_write(dev_priv, CH7xxx_TVCO, tvco); + ch7xxx_write(dev_priv, CH7xxx_TPCP, tpcp); + ch7xxx_write(dev_priv, CH7xxx_TPD, tpd); + ch7xxx_write(dev_priv, CH7xxx_TPVT, 0x30); + ch7xxx_write(dev_priv, CH7xxx_TLPF, tlpf); + ch7xxx_write(dev_priv, CH7xxx_TCT, 0x00); + + ch7xxx_read(dev_priv, CH7xxx_IDF, &idf); + idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP); if (mode->Flags & V_PHSYNC) idf |= CH7xxx_IDF_HSP; @@ -193,87 +229,69 @@ static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode) if (mode->Flags & V_PVSYNC) idf |= CH7xxx_IDF_HSP; - /* setup PM Registers */ - pm &= ~CH7xxx_PM_FPD; - pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP; - - /* cm |= 1; */ - - ch7xxxWriteByte(ch7xxx, CH7xxx_CM, cm); - ch7xxxWriteByte(ch7xxx, CH7xxx_TPCP, tpcp); - ch7xxxWriteByte(ch7xxx, CH7xxx_TPD, tpd); - ch7xxxWriteByte(ch7xxx, CH7xxx_TPF, tpf); - ch7xxxWriteByte(ch7xxx, CH7xxx_TPF, idf); - ch7xxxWriteByte(ch7xxx, CH7xxx_PM, pm); -#endif + ch7xxx_write(dev_priv, CH7xxx_IDF, idf); } /* set the CH7xxx power state */ -static void ch7xxxPower(I2CDevPtr d, Bool On) +static void +ch7xxx_dpms(I2CDevPtr d, int mode) { - CH7xxxPtr ch7xxx = CH7PTR(d); - int ret; - unsigned char ch; + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - ret = ch7xxxReadByte(ch7xxx, CH7xxx_PM, &ch); - if (ret == FALSE) - return; - - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx pm is %02X\n", ch); - -#if 0 - ret = ch7xxxReadByte(ch7xxx, CH7xxx_REG8, &ch); - if (ret) - return; - - if (On) - ch |= CH7xxx_8_PD; + if (mode == DPMSModeOn) + ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); else - ch &= ~CH7xxx_8_PD; - - ch7xxxWriteByte(ch7xxx, CH7xxx_REG8, ch); -#endif + ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_FPD); } -static void ch7xxxPrintRegs(I2CDevPtr d) +static void +ch7xxx_dump_regs(I2CDevPtr d) { - CH7xxxPtr ch7xxx = CH7PTR(d); + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; int i; - ch7xxxSaveRegs(d); - for (i = 0; i < CH7xxx_NUM_REGS; i++) { if (( i % 8 ) == 0 ) ErrorF("\n %02X: ", i); - ErrorF("%02X ", ch7xxx->ModeReg.regs[i]); + ErrorF("%02X ", dev_priv->ModeReg.regs[i]); } } -static void ch7xxxSaveRegs(I2CDevPtr d) +static void +ch7xxx_save(I2CDevPtr d) { - CH7xxxPtr ch7xxx = CH7PTR(d); - int ret; - int i; + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - for (i = 0; i < CH7xxx_NUM_REGS; i++) { - ret = ch7xxxReadByte(ch7xxx, i, &ch7xxx->SavedReg.regs[i]); - if (ret == FALSE) - break; - } + ch7xxx_read(dev_priv, CH7xxx_TCTL, &dev_priv->save_TCTL); + ch7xxx_read(dev_priv, CH7xxx_TPCP, &dev_priv->save_TPCP); + ch7xxx_read(dev_priv, CH7xxx_TPD, &dev_priv->save_TPD); + ch7xxx_read(dev_priv, CH7xxx_TPVT, &dev_priv->save_TPVT); + ch7xxx_read(dev_priv, CH7xxx_TLPF, &dev_priv->save_TLPF); + ch7xxx_read(dev_priv, CH7xxx_PM, &dev_priv->save_PM); + ch7xxx_read(dev_priv, CH7xxx_IDF, &dev_priv->save_IDF); +} - memcpy(ch7xxx->ModeReg.regs, ch7xxx->SavedReg.regs, CH7xxx_NUM_REGS); +static void +ch7xxx_restore(I2CDevPtr d) +{ + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - return; + ch7xxx_write(dev_priv, CH7xxx_TCTL, dev_priv->save_TCTL); + ch7xxx_write(dev_priv, CH7xxx_TPCP, dev_priv->save_TPCP); + ch7xxx_write(dev_priv, CH7xxx_TPD, dev_priv->save_TPD); + ch7xxx_write(dev_priv, CH7xxx_TPVT, dev_priv->save_TPVT); + ch7xxx_write(dev_priv, CH7xxx_TLPF, dev_priv->save_TLPF); + ch7xxx_write(dev_priv, CH7xxx_IDF, dev_priv->save_IDF); + ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM); } I830I2CVidOutputRec CH7xxxVidOutput = { - ch7xxxDetect, - ch7xxxInit, - ch7xxxModeValid, - ch7xxxMode, - ch7xxxPower, - ch7xxxPrintRegs, - ch7xxxSaveRegs, - NULL, + .init = ch7xxx_init, + .detect = ch7xxx_detect, + .mode_valid = ch7xxx_mode_valid, + .mode_set = ch7xxx_mode_set, + .dpms = ch7xxx_dpms, + .dump_regs = ch7xxx_dump_regs, + .save = ch7xxx_save, + .restore = ch7xxx_restore, }; diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h index e24e9a6b..c626e1fc 100644 --- a/src/ch7xxx/ch7xxx_reg.h +++ b/src/ch7xxx/ch7xxx_reg.h @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define CH7xxx_REG_VID 0x4a #define CH7xxx_REG_DID 0x4b -#define CH7011_VID 0x83 +#define CH7011_VID 0x83 /* 7010 as well */ #define CH7009A_VID 0x84 #define CH7009B_VID 0x85 #define CH7301_VID 0x95 @@ -39,18 +39,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define CH7xxx_NUM_REGS 0x4c -typedef struct _CH7xxxSaveRec { - CARD8 regs[CH7xxx_NUM_REGS]; -} CH7xxxSaveRec; - -typedef struct { - I2CDevRec d; - CH7xxxSaveRec SavedReg; - CH7xxxSaveRec ModeReg; -} CH7xxxRec, *CH7xxxPtr; - -#define CH7PTR(d) ((CH7xxxPtr)(d->DriverPrivate.ptr)) - #define CH7xxx_CM 0x1C #define CH7xxx_CM_XCM (1<<0) #define CH7xxx_CM_MCP (1<<2) @@ -65,11 +53,12 @@ typedef struct { #define CH7301_DAC_CNTL 0x21 #define CH7301_HOTPLUG 0x23 #define CH7xxx_TCTL 0x31 +#define CH7xxx_TVCO 0x32 #define CH7xxx_TPCP 0x33 #define CH7xxx_TPD 0x34 #define CH7xxx_TPVT 0x35 -#define CH7xxx_TPF 0x36 -#define CH7301_TCT 0x37 +#define CH7xxx_TLPF 0x36 +#define CH7xxx_TCT 0x37 #define CH7301_TEST_PATTERN 0x48 #define CH7xxx_PM 0x49 diff --git a/src/i2c_vid.h b/src/i2c_vid.h index 5a743d29..3be394d7 100644 --- a/src/i2c_vid.h +++ b/src/i2c_vid.h @@ -3,14 +3,14 @@ #define I2C_VID_H typedef struct _I830I2CVidOutputRec { - void *(*Detect)(I2CBusPtr b, I2CSlaveAddr addr); - Bool (*Init)(I2CDevPtr d); - ModeStatus (*ModeValid)(I2CDevPtr d, DisplayModePtr mode); - void (*Mode)(I2CDevPtr d, DisplayModePtr mode); - void (*Power)(I2CDevPtr d, Bool On); - void (*PrintRegs)(I2CDevPtr d); - void (*SaveRegs)(I2CDevPtr d); - void (*RestoreRegs)(I2CDevPtr d); + void *(*init)(I2CBusPtr b, I2CSlaveAddr addr); + xf86OutputStatus (*detect)(I2CDevPtr d); + ModeStatus (*mode_valid)(I2CDevPtr d, DisplayModePtr mode); + void (*mode_set)(I2CDevPtr d, DisplayModePtr mode); + void (*dpms)(I2CDevPtr d, int mode); + void (*dump_regs)(I2CDevPtr d); + void (*save)(I2CDevPtr d); + void (*restore)(I2CDevPtr d); } I830I2CVidOutputRec, *I830I2CVidOutputPtr; #endif diff --git a/src/i830_display.c b/src/i830_display.c index f87aadca..e3fdf6d2 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -962,7 +962,6 @@ void i830DisableUnusedFunctions(ScrnInfoPtr pScrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); int o, pipe; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n"); @@ -970,54 +969,27 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn) for (o = 0; o < xf86_config->num_output; o++) { xf86OutputPtr output = xf86_config->output[o]; - if (!output->crtc) + if (!output->crtc) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling output %s\n", + output->name); (*output->funcs->dpms)(output, DPMSModeOff); + } } - /* Now, any unused plane, pipe, and DPLL (FIXME: except for DVO, i915 - * internal TV) should have no outputs trying to pull data out of it, so - * we're ready to turn those off. - */ for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) { xf86CrtcPtr crtc = xf86_config->crtc[pipe]; I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipe = intel_crtc->pipe; - int dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF; - int dpll_reg = pipe == 0 ? DPLL_A : DPLL_B; - CARD32 dspcntr, pipeconf, dpll; char *pipe_name = pipe == 0 ? "A" : "B"; - if (crtc->enabled) - continue; - - dspcntr = INREG(dspcntr_reg); - if (dspcntr & DISPLAY_PLANE_ENABLE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane %s\n", + if (!crtc->enabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling CRTC %s\n", pipe_name); - - OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); + crtc->funcs->dpms(crtc, DPMSModeOff); - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); + memset(&crtc->curMode, 0, sizeof(crtc->curMode)); } - - pipeconf = INREG(pipeconf_reg); - if (pipeconf & PIPEACONF_ENABLE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe %s\n", - pipe_name); - OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); - } - - dpll = INREG(dpll_reg); - if (dpll & DPLL_VCO_ENABLE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL %s\n", - pipe_name); - OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - } - - memset(&crtc->curMode, 0, sizeof(crtc->curMode)); } } @@ -1041,6 +1013,7 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) TRUE); if (!ok) goto done; + crtc->desiredMode = *pMode; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", diff --git a/src/i830_driver.c b/src/i830_driver.c index 79d4a00e..41bd0678 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1841,8 +1841,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) #endif pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ - if (pScrn->displayWidth * pI830->cpp > 8192) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support frame buffer stride > 8K > DRI.\n"); + if (!IS_I965G(pI830) && pScrn->displayWidth * pI830->cpp > 8192) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot support DRI with frame buffer stride > 8K.\n"); pI830->disableTiling = TRUE; pI830->directRenderingDisabled = TRUE; } @@ -3178,6 +3179,8 @@ I830EnterVT(int scrnIndex, int flags) ResetState(pScrn, FALSE); SetHWOperatingState(pScrn); + i830DisableUnusedFunctions(pScrn); + for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; @@ -3193,8 +3196,6 @@ I830EnterVT(int scrnIndex, int flags) i830PipeSetBase(crtc, crtc->x, crtc->y); } - i830DisableUnusedFunctions(pScrn); - i830DumpRegs (pScrn); i830DescribeOutputConfiguration(pScrn); diff --git a/src/i830_dvo.c b/src/i830_dvo.c index ed8d1c74..97453ded 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -62,12 +62,13 @@ i830_dvo_dpms(xf86OutputPtr output, int mode) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; + void * dev_priv = intel_output->i2c_drv->dev_priv; if (mode == DPMSModeOn) { OUTREG(DVOC, INREG(DVOC) | DVO_ENABLE); - (*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, TRUE); + (*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode); } else { - (*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, FALSE); + (*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode); OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE); } } @@ -78,6 +79,7 @@ i830_dvo_save(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; + void * dev_priv = intel_output->i2c_drv->dev_priv; /* Each output should probably just save the registers it touches, but for * now, use more overkill. @@ -86,7 +88,7 @@ i830_dvo_save(xf86OutputPtr output) pI830->saveDVOB = INREG(DVOB); pI830->saveDVOC = INREG(DVOC); - (*intel_output->i2c_drv->vid_rec->SaveRegs)(intel_output->i2c_drv->dev_priv); + (*intel_output->i2c_drv->vid_rec->save)(dev_priv); } static void @@ -95,28 +97,27 @@ i830_dvo_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; + void * dev_priv = intel_output->i2c_drv->dev_priv; OUTREG(DVOA, pI830->saveDVOA); OUTREG(DVOB, pI830->saveDVOB); OUTREG(DVOC, pI830->saveDVOC); - (*intel_output->i2c_drv->vid_rec->RestoreRegs)(intel_output->i2c_drv->dev_priv); + (*intel_output->i2c_drv->vid_rec->restore)(dev_priv); } static int i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { I830OutputPrivatePtr intel_output = output->driver_private; - + void *dev_priv = intel_output->i2c_drv->dev_priv; + if (pMode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; /* XXX: Validate clock range */ - if ((*intel_output->i2c_drv->vid_rec->ModeValid)(intel_output->i2c_drv->dev_priv, pMode)) - return MODE_OK; - else - return MODE_BAD; + return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode); } static Bool @@ -141,8 +142,8 @@ i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, CARD32 dvo; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - intel_output->i2c_drv->vid_rec->Mode(intel_output->i2c_drv->dev_priv, - mode); + intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv, + mode); /* Save the data order, since I don't know what it should be set to. */ dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); @@ -176,7 +177,10 @@ i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, static xf86OutputStatus i830_dvo_detect(xf86OutputPtr output) { - return XF86OutputStatusUnknown; + I830OutputPrivatePtr intel_output = output->driver_private; + void *dev_priv = intel_output->i2c_drv->dev_priv; + + return intel_output->i2c_drv->vid_rec->detect(dev_priv); } static Bool @@ -198,7 +202,7 @@ I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus, ret_ptr = NULL; drv->vid_rec = LoaderSymbol(drv->fntablename); if (drv->vid_rec != NULL) - ret_ptr = drv->vid_rec->Detect(pI2CBus, drv->address); + ret_ptr = drv->vid_rec->init(pI2CBus, drv->address); if (ret_ptr != NULL) { drv->dev_priv = ret_ptr; diff --git a/src/i830_i2c.c b/src/i830_i2c.c index d246c167..8fd12ea9 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -272,31 +272,21 @@ i830I2CGetBits(I2CBusPtr b, int *clock, int *data) { ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - CARD32 val, tristate = 0; + CARD32 val; val = INREG(b->DriverPrivate.uval); - /* If we've released either of the lines from holding low, tristate them - * so that we can successfully read. Some hardware fails to read low - * values driven by slaves when our master is not tri-stated, while other - * chips succeed. + /* + * to read valid data, we must have written a 1 to + * the associated bit. Writing a 1 is done by + * tri-stating the bus in PutBits, so we needn't make + * sure that is true here */ - if ((val & GPIO_DATA_DIR_OUT) && (val & GPIO_DATA_VAL_OUT)) - tristate |= GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - if ((val & GPIO_CLOCK_DIR_OUT) && (val & GPIO_CLOCK_VAL_OUT)) - tristate |= GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - - if (tristate) { - OUTREG(b->DriverPrivate.uval, tristate); - - val = INREG(b->DriverPrivate.uval); - } - *data = (val & GPIO_DATA_VAL_IN) != 0; *clock = (val & GPIO_CLOCK_VAL_IN) != 0; #if I2C_DEBUG - ErrorF("Getting I2C: %c %c\n", + ErrorF("Getting %s: %c %c\n", b->BusName, *clock ? '^' : 'v', *data ? '^' : 'v'); #endif @@ -306,6 +296,7 @@ static void i830I2CPutBits(I2CBusPtr b, int clock, int data) { CARD32 reserved = 0; + CARD32 data_bits, clock_bits; #if I2C_DEBUG int cur_clock, cur_data; @@ -318,11 +309,11 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data) i830I2CGetBits(b, &cur_clock, &cur_data); if (first) { - ErrorF("I2C Debug: C D C D\n"); + ErrorF("%s Debug: C D C D\n", b->BusName); first = FALSE; } - ErrorF("Setting I2C 0x%08x to: %c %c\n", + ErrorF("Setting %s 0x%08x to: %c %c\n", b->BusName, (int)b->DriverPrivate.uval, clock ? '^' : 'v', data ? '^' : 'v'); @@ -334,17 +325,19 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data) (GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE); } - OUTREG(b->DriverPrivate.uval, - reserved | - (data ? GPIO_DATA_VAL_OUT : 0) | - (clock ? GPIO_CLOCK_VAL_OUT : 0) | - GPIO_CLOCK_DIR_OUT | - GPIO_DATA_DIR_OUT | - GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK | - GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK); + /* data or clock == 1 means to tristate the bus. otherwise, drive it low */ + if (data) + data_bits = GPIO_DATA_DIR_IN|GPIO_DATA_DIR_MASK; + else + data_bits = GPIO_DATA_DIR_OUT|GPIO_DATA_DIR_MASK|GPIO_DATA_VAL_MASK; + if (clock) + clock_bits = GPIO_CLOCK_DIR_IN|GPIO_CLOCK_DIR_MASK; + else + clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK; + + OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits); } + #endif /* the i830 has a number of I2C Buses */ diff --git a/src/i830_randr.c b/src/i830_randr.c index 290cb10d..0a103846 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -835,9 +835,10 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); int c; int width, height; + int mmWidth, mmHeight; /* - * Compute width of screen + * Compute size of screen */ width = 0; height = 0; for (c = 0; c < config->num_crtc; c++) @@ -854,14 +855,19 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) if (width && height) { - int mmWidth, mmHeight; - - mmWidth = pScreen->mmWidth; - mmHeight = pScreen->mmHeight; - if (width != pScreen->width) - mmWidth = mmWidth * width / pScreen->width; - if (height != pScreen->height) - mmHeight = mmHeight * height / pScreen->height; + /* + * Compute physical size of screen + */ + if (monitorResolution) + { + mmWidth = width * 25.4 / monitorResolution; + mmHeight = height * 25.4 / monitorResolution; + } + else + { + mmWidth = pScreen->mmWidth; + mmHeight = pScreen->mmHeight; + } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting screen physical size to %d x %d\n", mmWidth, mmHeight); diff --git a/src/i830_tv.c b/src/i830_tv.c index 46ce046e..05b68259 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -777,7 +777,7 @@ i830_tv_init(ScrnInfoPtr pScrn) return; } dev_priv = (struct i830_tv_priv *) (intel_output + 1); - intel_output->type = I830_OUTPUT_SDVO; + intel_output->type = I830_OUTPUT_TVOUT; intel_output->dev_priv = dev_priv; dev_priv->type = TV_TYPE_UNKNOWN; diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c index 51e6f1c7..bb6c8691 100644 --- a/src/i830_xf86Crtc.c +++ b/src/i830_xf86Crtc.c @@ -555,16 +555,20 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) for (mode = pScrn->modes; mode; mode = mode->next) if (xf86ModesEqual (mode, &crtc->desiredMode)) break; - - /* For some reason, pScrn->modes is circular, unlike the other mode lists. - * How great is that? - */ - for (last = pScrn->modes; last && last->next; last = last->next); - last->next = pScrn->modes; - pScrn->modes->prev = last; - if (mode) - while (pScrn->modes != mode) - pScrn->modes = pScrn->modes->next; + + if (pScrn->modes != NULL) { + /* For some reason, pScrn->modes is circular, unlike the other mode + * lists. How great is that? + */ + for (last = pScrn->modes; last && last->next; last = last->next) + ; + last->next = pScrn->modes; + pScrn->modes->prev = last; + if (mode) { + while (pScrn->modes != mode) + pScrn->modes = pScrn->modes->next; + } + } pScrn->currentMode = pScrn->modes; } diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c index daffa0c6..cefa15cd 100644 --- a/src/i915_exa_render.c +++ b/src/i915_exa_render.c @@ -142,7 +142,9 @@ static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format) * the source blend factor is 0, and the source blend value is the mask * channels multiplied by the source picture's alpha. */ - if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) { + if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format) && + I915BlendOp[op].src_alpha) + { if (dblend == BLENDFACT_SRC_ALPHA) { dblend = BLENDFACT_SRC_COLR; } else if (dblend == BLENDFACT_INV_SRC_ALPHA) { @@ -228,7 +230,9 @@ I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, /* Check for unsupported compositing operations. */ if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0])) I830FALLBACK("Unsupported Composite op 0x%x\n", op); - if (pMaskPicture != NULL && pMaskPicture->componentAlpha) { + if (pMaskPicture != NULL && pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) + { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. @@ -463,7 +467,7 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture, if (PICT_FORMAT_A(pMaskPicture->format) == 0) i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one()); - /* If component alpha is set in the mask and the blend operation + /* If component alpha is active in the mask and the blend operation * uses the source alpha, then we know we don't need the source * value (otherwise we would have hit a fallback earlier), so we * provide the source alpha (src.A * mask.X) as output color. @@ -472,7 +476,9 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture, * is unused.. Otherwise, we provide the non-CA source value * (src.X * mask.A). */ - if (pMaskPicture->componentAlpha) { + if (pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) + { if (I915BlendOp[op].src_alpha) { i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W), i915_fs_operand_reg(FS_R1)); diff --git a/src/i915_video.c b/src/i915_video.c index fb3f4fcc..636b2cbd 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -60,7 +60,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, DrawablePtr pDraw) { I830Ptr pI830 = I830PTR(pScrn); - CARD32 format, ms3, s2; + CARD32 format, ms3, s2, s5; BoxPtr pbox; int nbox, dxo, dyo; Bool planar; @@ -103,7 +103,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, /* draw rect -- just clipping */ OUT_RING(_3DSTATE_DRAW_RECT_CMD); - OUT_RING(0x00000000); /* flags */ + OUT_RING(DRAW_DITHER_OFS_X(pDraw->x & 3)| DRAW_DITHER_OFS_Y(pDraw->y & 3)); /* flags */ OUT_RING(0x00000000); /* ymin, xmin */ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */ @@ -131,7 +131,10 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_RING(s2); OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE | S4_CULLMODE_NONE | S4_VFMT_XY); - OUT_RING(0x00000000); /* S5 - enable bits */ + s5 = 0x0; + if (pI830->cpp == 2) + s5 |= S5_COLOR_DITHER_ENABLE; + OUT_RING(s5); /* S5 - enable bits */ OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) | (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) | (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE | diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index bb84d036..927f5a77 100644 --- a/src/sil164/Makefile.am +++ b/src/sil164/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 0a68d691..453ed044 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -26,22 +26,25 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" +#include "i830_xf86Crtc.h" +#define DPMS_SERVER +#include #include "../i2c_vid.h" #include "sil164.h" #include "sil164_reg.h" -static void -sil164PrintRegs(I2CDevPtr d); -static void -sil164Power(I2CDevPtr d, Bool On); - static Bool sil164ReadByte(SIL164Ptr sil, int addr, CARD8 *ch) { @@ -68,7 +71,7 @@ sil164WriteByte(SIL164Ptr sil, int addr, CARD8 ch) /* Silicon Image 164 driver for chip on i2c bus */ static void * -sil164Detect(I2CBusPtr b, I2CSlaveAddr addr) +sil164_init(I2CBusPtr b, I2CSlaveAddr addr) { /* this will detect the SIL164 chip on the specified i2c bus */ SIL164Ptr sil; @@ -120,26 +123,33 @@ out: return NULL; } - -static Bool -sil164Init(I2CDevPtr d) +static xf86OutputStatus +sil164_detect(I2CDevPtr d) { - /* not much to do */ - return TRUE; + SIL164Ptr sil = SILPTR(d); + CARD8 reg9; + + sil164ReadByte(sil, SIL164_REG9, ®9); + + if (reg9 & SIL164_9_HTPLG) + return XF86OutputStatusConnected; + else + return XF86OutputStatusDisconnected; } static ModeStatus -sil164ModeValid(I2CDevPtr d, DisplayModePtr mode) +sil164_mode_valid(I2CDevPtr d, DisplayModePtr mode) { return MODE_OK; } static void -sil164Mode(I2CDevPtr d, DisplayModePtr mode) +sil164_mode_set(I2CDevPtr d, DisplayModePtr mode) { - sil164Power(d, TRUE); - sil164PrintRegs(d); - + /* As long as the basics are set up, since we don't have clock dependencies + * in the mode setup, we can just leave the registers alone and everything + * will work fine. + */ /* recommended programming sequence from doc */ /*sil164WriteByte(sil, 0x08, 0x30); sil164WriteByte(sil, 0x09, 0x00); @@ -152,7 +162,7 @@ sil164Mode(I2CDevPtr d, DisplayModePtr mode) /* set the SIL164 power state */ static void -sil164Power(I2CDevPtr d, Bool On) +sil164_dpms(I2CDevPtr d, int mode) { SIL164Ptr sil = SILPTR(d); int ret; @@ -162,7 +172,7 @@ sil164Power(I2CDevPtr d, Bool On) if (ret == FALSE) return; - if (On) + if (mode == DPMSModeOn) ch |= SIL164_8_PD; else ch &= ~SIL164_8_PD; @@ -173,7 +183,7 @@ sil164Power(I2CDevPtr d, Bool On) } static void -sil164PrintRegs(I2CDevPtr d) +sil164_dump_regs(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); CARD8 val; @@ -193,7 +203,7 @@ sil164PrintRegs(I2CDevPtr d) } static void -sil164SaveRegs(I2CDevPtr d) +sil164_save(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); @@ -210,7 +220,7 @@ sil164SaveRegs(I2CDevPtr d) } static void -sil164RestoreRegs(I2CDevPtr d) +sil164_restore(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); @@ -224,12 +234,12 @@ sil164RestoreRegs(I2CDevPtr d) I830I2CVidOutputRec SIL164VidOutput = { - sil164Detect, - sil164Init, - sil164ModeValid, - sil164Mode, - sil164Power, - sil164PrintRegs, - sil164SaveRegs, - sil164RestoreRegs, + .init = sil164_init, + .detect = sil164_detect, + .mode_valid = sil164_mode_valid, + .mode_set = sil164_mode_set, + .dpms = sil164_dpms, + .dump_regs = sil164_dump_regs, + .save = sil164_save, + .restore = sil164_restore, };