From 2d0ca2202cb0d780bb4387bbe04e5caa6512e3b1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 10:37:33 -0800 Subject: [PATCH 01/22] Bug #8786: Treat pictures with no color data as non-component alpha. This is an un(der?)-documented part of the render protocol: If the mask is alpha only, then the component alpha flag is ignored on it. --- src/i915_exa_render.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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)); From 31849edb3b503ade659981dfa36babf5ad8757c5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 13:32:21 -0800 Subject: [PATCH 02/22] Move the ch7xxx code to the style I've been settling on for output code. --- src/ch7xxx/ch7xxx.c | 158 ++++++++++++++++++++++------------------ src/ch7xxx/ch7xxx_reg.h | 12 --- 2 files changed, 86 insertions(+), 84 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index df66d03d..bf70d8e3 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -41,113 +41,126 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * driver for the Chrontel 7xxx DVI chip over DVO. */ -static void ch7xxxSaveRegs(I2CDevPtr d); +struct ch7xxx_reg_state { + CARD8 regs[CH7xxx_NUM_REGS]; +}; + +struct ch7xxx_priv { + I2CDevRec d; + struct ch7xxx_reg_state SavedReg; + struct ch7xxx_reg_state ModeReg; +}; + +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) +/** Reads an 8 bit register */ +static Bool +ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch) { - if (!xf86I2CReadByte(&(ch7xxx->d), addr, ch)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, + if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n", - ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); return FALSE; } return TRUE; } -static Bool ch7xxxWriteByte(CH7xxxPtr ch7xxx, int addr, unsigned char ch) +/** Writes an 8 bit register */ +static Bool +ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch) { - if (!xf86I2CWriteByte(&(ch7xxx->d), addr, ch)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, + if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "Unable to write to %s Slave %d.\n", - ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); return FALSE; } return TRUE; } -static void *ch7xxxDetect(I2CBusPtr b, I2CSlaveAddr addr) +static void * +ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) { /* this will detect the CH7xxx chip on the specified i2c bus */ - CH7xxxPtr ch7xxx; + struct ch7xxx_priv *dev_priv; unsigned char ch; - xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting ch7xxx\n"); + xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ch7xxx\n"); - ch7xxx = xcalloc(1, sizeof(CH7xxxRec)); - if (ch7xxx == NULL) + dev_priv = xcalloc(1, sizeof(struct ch7xxx_priv)); + if (dev_priv == 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; + 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 (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_VID, &ch)) + if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &ch)) goto out; ErrorF("VID is %02X", ch); if (ch!=(CH7xxx_VID & 0xFF)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); + ch, dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); goto out; } - if (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_DID, &ch)) + if (!ch7xxx_read(dev_priv, CH7xxx_REG_DID, &ch)) goto out; ErrorF("DID is %02X", ch); if (ch!=(CH7xxx_DID & 0xFF)) { - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr); + ch, dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); goto out; } - if (!xf86I2CDevInit(&(ch7xxx->d))) { + if (!xf86I2CDevInit(&dev_priv->d)) { goto out; } - return ch7xxx; + return dev_priv; out: - xfree(ch7xxx); + xfree(dev_priv); return NULL; } -static Bool ch7xxxInit(I2CDevPtr d) +static Bool +ch7xxx_init(I2CDevPtr d) { - CH7xxxPtr ch7xxx = CH7PTR(d); - /* not much to do */ return TRUE; } -static ModeStatus ch7xxxModeValid(I2CDevPtr d, DisplayModePtr mode) +static ModeStatus +ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) { - CH7xxxPtr ch7xxx = CH7PTR(d); - return MODE_OK; } -static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode) +static void +ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode) { - CH7xxxPtr ch7xxx = CH7PTR(d); + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; int ret; unsigned char pm, idf; unsigned char tpcp, tpd, tpf, cm; @@ -164,16 +177,16 @@ static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode) 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]); + dev_priv->ModeReg.regs[i] = freq_regs[i - 0x31]; + ch7xxx_write(dev_priv, i, dev_priv->ModeReg.regs[i]); } #if 0 - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, + xf86DrvMsg(dev_priv->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, + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "ch7xxx pm is %02X\n", pm); if (mode->Clock < 65000) { @@ -199,31 +212,32 @@ static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode) /* 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); + ch7xxx_write(dev_priv, CH7xxx_CM, cm); + ch7xxx_write(dev_priv, CH7xxx_TPCP, tpcp); + ch7xxx_write(dev_priv, CH7xxx_TPD, tpd); + ch7xxx_write(dev_priv, CH7xxx_TPF, tpf); + ch7xxx_write(dev_priv, CH7xxx_TPF, idf); + ch7xxx_write(dev_priv, CH7xxx_PM, pm); #endif } /* set the CH7xxx power state */ -static void ch7xxxPower(I2CDevPtr d, Bool On) +static void +ch7xxx_power(I2CDevPtr d, Bool On) { - CH7xxxPtr ch7xxx = CH7PTR(d); + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; int ret; unsigned char ch; - ret = ch7xxxReadByte(ch7xxx, CH7xxx_PM, &ch); + ret = ch7xxx_read(dev_priv, CH7xxx_PM, &ch); if (ret == FALSE) return; - xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR, + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, "ch7xxx pm is %02X\n", ch); #if 0 - ret = ch7xxxReadByte(ch7xxx, CH7xxx_REG8, &ch); + ret = ch7xxx_read(dev_priv, CH7xxx_REG8, &ch); if (ret) return; @@ -232,48 +246,48 @@ static void ch7xxxPower(I2CDevPtr d, Bool On) else ch &= ~CH7xxx_8_PD; - ch7xxxWriteByte(ch7xxx, CH7xxx_REG8, ch); + ch7xxx_write(dev_priv, CH7xxx_REG8, ch); #endif } -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); + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; int ret; int i; for (i = 0; i < CH7xxx_NUM_REGS; i++) { - ret = ch7xxxReadByte(ch7xxx, i, &ch7xxx->SavedReg.regs[i]); + ret = ch7xxx_read(dev_priv, i, &dev_priv->SavedReg.regs[i]); if (ret == FALSE) break; } - memcpy(ch7xxx->ModeReg.regs, ch7xxx->SavedReg.regs, CH7xxx_NUM_REGS); + memcpy(dev_priv->ModeReg.regs, dev_priv->SavedReg.regs, CH7xxx_NUM_REGS); return; } I830I2CVidOutputRec CH7xxxVidOutput = { - ch7xxxDetect, - ch7xxxInit, - ch7xxxModeValid, - ch7xxxMode, - ch7xxxPower, - ch7xxxPrintRegs, - ch7xxxSaveRegs, + ch7xxx_probe, + ch7xxx_init, + ch7xxx_mode_valid, + ch7xxx_mode_set, + ch7xxx_power, + ch7xxx_dump_regs, + ch7xxx_save, NULL, }; diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h index e24e9a6b..891fde8b 100644 --- a/src/ch7xxx/ch7xxx_reg.h +++ b/src/ch7xxx/ch7xxx_reg.h @@ -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) From 4ca92da5b93b07f0bff51843f8fb5d04a2a29443 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 13:45:34 -0800 Subject: [PATCH 03/22] Add save/restore to ch7xxx to avoid segfaults on server start. --- src/ch7xxx/ch7xxx.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index bf70d8e3..5213646b 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -49,6 +49,8 @@ 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_TPF, save_TCT, save_PM; }; static void ch7xxx_save(I2CDevPtr d); @@ -270,13 +272,29 @@ ch7xxx_save(I2CDevPtr d) int ret; int i; - for (i = 0; i < CH7xxx_NUM_REGS; i++) { - ret = ch7xxx_read(dev_priv, i, &dev_priv->SavedReg.regs[i]); - if (ret == FALSE) - break; - } + ch7xxx_read(dev_priv, CH7xxx_PM, &dev_priv->save_PM); + 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_TPF, &dev_priv->save_TPF); - memcpy(dev_priv->ModeReg.regs, dev_priv->SavedReg.regs, CH7xxx_NUM_REGS); + return; +} + +static void +ch7xxx_restore(I2CDevPtr d) +{ + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; + int ret; + int i; + + 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_TPF, dev_priv->save_TPF); + ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM); return; } @@ -289,5 +307,5 @@ I830I2CVidOutputRec CH7xxxVidOutput = { ch7xxx_power, ch7xxx_dump_regs, ch7xxx_save, - NULL, + ch7xxx_restore, }; From 3167bc6b24bd74c50ca4c4d361b14aa24d77cfa3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 13:45:55 -0800 Subject: [PATCH 04/22] Fix DVO mode valid function to not throw out all modes. --- src/i830_dvo.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/i830_dvo.c b/src/i830_dvo.c index ed8d1c74..804f0fc1 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -107,16 +107,14 @@ 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->ModeValid(dev_priv, pMode); } static Bool From 633d718f6fb019844304228a81c84a8605da004f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 13:59:17 -0800 Subject: [PATCH 05/22] Clean up a bunch of log noise from ch7xxx startup. --- src/ch7xxx/ch7xxx.c | 34 ++++++++++++++++------------------ src/ch7xxx/ch7xxx_reg.h | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 5213646b..59722b8f 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -93,10 +93,9 @@ ch7xxx_probe(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; - xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ch7xxx\n"); - dev_priv = xcalloc(1, sizeof(struct ch7xxx_priv)); if (dev_priv == NULL) return NULL; @@ -110,29 +109,31 @@ ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) dev_priv->d.ByteTimeout = b->ByteTimeout; dev_priv->d.DriverPrivate.ptr = dev_priv; - if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &ch)) + if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor)) goto out; - ErrorF("VID is %02X", ch); - if (ch!=(CH7xxx_VID & 0xFF)) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + if (vendor != CH7xxx_VID) { + 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, &ch)) + if (!ch7xxx_read(dev_priv, CH7xxx_REG_DID, &device)) goto out; - ErrorF("DID is %02X", ch); - if (ch!=(CH7xxx_DID & 0xFF)) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx not detected got %d: from %s Slave %d.\n", - ch, dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + 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 CH7xxx chipset, vendor/device ID 0x%02x/0x%02x\n", + vendor, device); if (!xf86I2CDevInit(&dev_priv->d)) { goto out; @@ -235,9 +236,6 @@ ch7xxx_power(I2CDevPtr d, Bool On) if (ret == FALSE) return; - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx pm is %02X\n", ch); - #if 0 ret = ch7xxx_read(dev_priv, CH7xxx_REG8, &ch); if (ret) diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h index 891fde8b..0a5f1885 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 From 23114fbccad849249b4b7200e3d085a9ac0e2e99 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 14:47:44 -0800 Subject: [PATCH 06/22] Align the driver to the CH7009[AB] spec. With this, the driver works at 640x480 and 1280x1024 on my panel. --- src/ch7xxx/ch7xxx.c | 100 +++++++++++----------------------------- src/ch7xxx/ch7xxx_reg.h | 5 +- 2 files changed, 30 insertions(+), 75 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 59722b8f..e4b21f28 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -50,7 +50,7 @@ struct ch7xxx_priv { struct ch7xxx_reg_state SavedReg; struct ch7xxx_reg_state ModeReg; CARD8 save_TCTL, save_TPCP, save_TPD, save_TPVT; - CARD8 save_TPF, save_TCT, save_PM; + CARD8 save_TLPF, save_TCT, save_PM, save_IDF; }; static void ch7xxx_save(I2CDevPtr d); @@ -164,44 +164,30 @@ static void ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode) { struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - int ret; - unsigned char pm, idf; - unsigned char tpcp, tpd, tpf, cm; - CARD8 *freq_regs; - int i; + 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++) { - dev_priv->ModeReg.regs[i] = freq_regs[i - 0x31]; - ch7xxx_write(dev_priv, i, dev_priv->ModeReg.regs[i]); - } - -#if 0 - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "ch7xxx idf is 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - idf, tpcp, tpd, tpf); - - xf86DrvMsg(dev_priv->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; @@ -209,45 +195,19 @@ ch7xxx_mode_set(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; */ - - ch7xxx_write(dev_priv, CH7xxx_CM, cm); - ch7xxx_write(dev_priv, CH7xxx_TPCP, tpcp); - ch7xxx_write(dev_priv, CH7xxx_TPD, tpd); - ch7xxx_write(dev_priv, CH7xxx_TPF, tpf); - ch7xxx_write(dev_priv, CH7xxx_TPF, idf); - ch7xxx_write(dev_priv, CH7xxx_PM, pm); -#endif + ch7xxx_write(dev_priv, CH7xxx_IDF, idf); } /* set the CH7xxx power state */ static void -ch7xxx_power(I2CDevPtr d, Bool On) +ch7xxx_power(I2CDevPtr d, Bool on) { struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - int ret; - unsigned char ch; - ret = ch7xxx_read(dev_priv, CH7xxx_PM, &ch); - if (ret == FALSE) - return; - -#if 0 - ret = ch7xxx_read(dev_priv, CH7xxx_REG8, &ch); - if (ret) - return; - - if (On) - ch |= CH7xxx_8_PD; + if (on) + ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); else - ch &= ~CH7xxx_8_PD; - - ch7xxx_write(dev_priv, CH7xxx_REG8, ch); -#endif + ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_FPD); } static void @@ -267,34 +227,28 @@ static void ch7xxx_save(I2CDevPtr d) { struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - int ret; - int i; - ch7xxx_read(dev_priv, CH7xxx_PM, &dev_priv->save_PM); 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_TPF, &dev_priv->save_TPF); - - return; + 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); } static void ch7xxx_restore(I2CDevPtr d) { struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - int ret; - int i; 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_TPF, dev_priv->save_TPF); + 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); - - return; } I830I2CVidOutputRec CH7xxxVidOutput = { diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h index 0a5f1885..c626e1fc 100644 --- a/src/ch7xxx/ch7xxx_reg.h +++ b/src/ch7xxx/ch7xxx_reg.h @@ -53,11 +53,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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 From 0305298405bd7018e5c520bdd5ea46a75be09f37 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 14:49:01 -0800 Subject: [PATCH 07/22] Limit modes to 165Mhz on CH7009, according to spec. --- src/ch7xxx/ch7xxx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index e4b21f28..d31a38c6 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -157,6 +157,9 @@ ch7xxx_init(I2CDevPtr d) static ModeStatus ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) { + if (mode->Clock > 165000) + return MODE_CLOCK_HIGH; + return MODE_OK; } From dcb069a1da6b3300b0772843dd9b67efdf319637 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 10:29:56 +1100 Subject: [PATCH 08/22] ch7xxx: add lookup table for name Don't load if we don't match name --- src/ch7xxx/ch7xxx.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index d31a38c6..61ab20d1 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -41,6 +41,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * driver for the Chrontel 7xxx DVI chip over DVO. */ +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]; }; @@ -60,6 +71,18 @@ static CARD8 ch7xxxFreqRegs[][7] = { 0, 0x23, 0x04, 0x26, 0x30, 0x60, 0x00 }, { 0, 0x2D, 0x07, 0x26, 0x30, 0xE0, 0x00 } }; +static char *ch7xxx_get_id(int vid) +{ + int i; + + for (i = 0; i < ID_ARRAY_SIZE; i++) { + if (ch7xxx_ids[i].vid == vid) + return ch7xxx_ids[i].name; + } + + return NULL; +} + /** Reads an 8 bit register */ static Bool ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch) @@ -95,6 +118,7 @@ ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) 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) @@ -112,7 +136,8 @@ ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor)) goto out; - if (vendor != CH7xxx_VID) { + 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, @@ -132,8 +157,8 @@ ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) goto out; } xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "Detected CH7xxx chipset, vendor/device ID 0x%02x/0x%02x\n", - vendor, device); + "Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", + name, vendor, device); if (!xf86I2CDevInit(&dev_priv->d)) { goto out; From fa4642048b183134544fc5ee47558446d27f6194 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 15:32:35 -0800 Subject: [PATCH 09/22] Clean up i2c_vid interface, including de-StudlyCapsing and removing dead code. The old Init() function is removed and the previous Detect() function is now init(). This leaves us room in the namespace for a detect() like other outputs have ("is the monitor connected?"). Also, Power() became dpms(), taking a DPMSMode*. In general, the mode setting path now matches the intel internal path, except for the lack of mode_fixup(). --- src/ch7xxx/ch7xxx.c | 31 ++++++++++---------------- src/i2c_vid.h | 15 ++++++------- src/i830_dvo.c | 19 +++++++++------- src/sil164/sil164.c | 53 ++++++++++++++++++--------------------------- 4 files changed, 51 insertions(+), 67 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 61ab20d1..b1e8cbd7 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -32,6 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" +#define DPMS_SERVER +#include #include "../i2c_vid.h" #include "ch7xxx.h" @@ -112,7 +114,7 @@ ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch) } static void * -ch7xxx_probe(I2CBusPtr b, I2CSlaveAddr addr) +ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr) { /* this will detect the CH7xxx chip on the specified i2c bus */ struct ch7xxx_priv *dev_priv; @@ -171,14 +173,6 @@ out: return NULL; } - -static Bool -ch7xxx_init(I2CDevPtr d) -{ - /* not much to do */ - return TRUE; -} - static ModeStatus ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) { @@ -228,11 +222,11 @@ ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode) /* set the CH7xxx power state */ static void -ch7xxx_power(I2CDevPtr d, Bool on) +ch7xxx_dpms(I2CDevPtr d, int mode) { struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - if (on) + if (mode == DPMSModeOn) ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); else ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_FPD); @@ -280,12 +274,11 @@ ch7xxx_restore(I2CDevPtr d) } I830I2CVidOutputRec CH7xxxVidOutput = { - ch7xxx_probe, - ch7xxx_init, - ch7xxx_mode_valid, - ch7xxx_mode_set, - ch7xxx_power, - ch7xxx_dump_regs, - ch7xxx_save, - ch7xxx_restore, + .init = ch7xxx_init, + .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/i2c_vid.h b/src/i2c_vid.h index 5a743d29..877122fd 100644 --- a/src/i2c_vid.h +++ b/src/i2c_vid.h @@ -3,14 +3,13 @@ #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); + 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_dvo.c b/src/i830_dvo.c index 804f0fc1..c3ad4c08 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,12 +97,13 @@ 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 @@ -114,7 +117,7 @@ i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) /* XXX: Validate clock range */ - return intel_output->i2c_drv->vid_rec->ModeValid(dev_priv, pMode); + return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode); } static Bool @@ -139,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); @@ -196,7 +199,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/sil164/sil164.c b/src/sil164/sil164.c index 0a68d691..497336cc 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -32,16 +32,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.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 +65,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 +117,19 @@ out: return NULL; } - -static Bool -sil164Init(I2CDevPtr d) -{ - /* not much to do */ - return TRUE; -} - 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 +142,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 +152,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 +163,7 @@ sil164Power(I2CDevPtr d, Bool On) } static void -sil164PrintRegs(I2CDevPtr d) +sil164_dump_regs(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); CARD8 val; @@ -193,7 +183,7 @@ sil164PrintRegs(I2CDevPtr d) } static void -sil164SaveRegs(I2CDevPtr d) +sil164_save(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); @@ -210,7 +200,7 @@ sil164SaveRegs(I2CDevPtr d) } static void -sil164RestoreRegs(I2CDevPtr d) +sil164_restore(I2CDevPtr d) { SIL164Ptr sil = SILPTR(d); @@ -224,12 +214,11 @@ sil164RestoreRegs(I2CDevPtr d) I830I2CVidOutputRec SIL164VidOutput = { - sil164Detect, - sil164Init, - sil164ModeValid, - sil164Mode, - sil164Power, - sil164PrintRegs, - sil164SaveRegs, - sil164RestoreRegs, + .init = sil164_init, + .mode_valid = sil164_mode_valid, + .mode_set = sil164_mode_set, + .dpms = sil164_dpms, + .dump_regs = sil164_dump_regs, + .save = sil164_save, + .restore = sil164_restore, }; From 8983845f91cacf8110c70121e0f5f293fe443e6d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 15:57:08 -0800 Subject: [PATCH 10/22] Fix crash in xf86SetScrnInfoModes when pScrn->modes ends up empty. --- src/i830_xf86Crtc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) 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; } From eedef7adc53dd8337d27c02551c5778fb43bae05 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Dec 2006 15:57:44 -0800 Subject: [PATCH 11/22] Add a detect() function for DVO chips, and implement it on sil164. --- src/ch7xxx/Makefile.am | 2 +- src/ch7xxx/ch7xxx.c | 13 +++++++++++++ src/i2c_vid.h | 1 + src/i830_dvo.c | 5 ++++- src/sil164/Makefile.am | 2 +- src/sil164/sil164.c | 21 +++++++++++++++++++++ 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index 645ac692..d63c7fc9 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../ ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index b1e8cbd7..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,7 @@ 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 @@ -173,6 +179,12 @@ out: return NULL; } +static xf86OutputStatus +ch7xxx_detect(I2CDevPtr d) +{ + return XF86OutputStatusUnknown; +} + static ModeStatus ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) { @@ -275,6 +287,7 @@ ch7xxx_restore(I2CDevPtr d) I830I2CVidOutputRec CH7xxxVidOutput = { .init = ch7xxx_init, + .detect = ch7xxx_detect, .mode_valid = ch7xxx_mode_valid, .mode_set = ch7xxx_mode_set, .dpms = ch7xxx_dpms, diff --git a/src/i2c_vid.h b/src/i2c_vid.h index 877122fd..3be394d7 100644 --- a/src/i2c_vid.h +++ b/src/i2c_vid.h @@ -4,6 +4,7 @@ typedef struct _I830I2CVidOutputRec { 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); diff --git a/src/i830_dvo.c b/src/i830_dvo.c index c3ad4c08..97453ded 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -177,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 diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index bb84d036..d4c0cbd2 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../ sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 497336cc..453ed044 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -26,12 +26,18 @@ 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 @@ -117,6 +123,20 @@ out: return NULL; } +static xf86OutputStatus +sil164_detect(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + CARD8 reg9; + + sil164ReadByte(sil, SIL164_REG9, ®9); + + if (reg9 & SIL164_9_HTPLG) + return XF86OutputStatusConnected; + else + return XF86OutputStatusDisconnected; +} + static ModeStatus sil164_mode_valid(I2CDevPtr d, DisplayModePtr mode) { @@ -215,6 +235,7 @@ sil164_restore(I2CDevPtr d) I830I2CVidOutputRec SIL164VidOutput = { .init = sil164_init, + .detect = sil164_detect, .mode_valid = sil164_mode_valid, .mode_set = sil164_mode_set, .dpms = sil164_dpms, From 7b8056e3e347b15b37be0116315d7d3a23aef99f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Dec 2006 01:32:54 -0800 Subject: [PATCH 12/22] Writing 1 to I2C line means to tristate the bus so others can manipulate it. We were forcing bus lines to 1 which was breaking DDC for some monitors. Instead, make the PutBits function just tristate when writing 1 bits. --- src/i830_i2c.c | 51 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) 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 */ From 3fc9feec7b29e0b908e3b90e0f6634117d66ba6d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Dec 2006 14:38:23 -0800 Subject: [PATCH 13/22] Simplify i830DisableUnusedFunctions() by using the CRTC dpms routines. --- src/i830_display.c | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index f87aadca..4899763b 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,51 +969,24 @@ 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); - - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } - - 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); + crtc->funcs->dpms(crtc, DPMSModeOff); } memset(&crtc->curMode, 0, sizeof(crtc->curMode)); From d89e211b12ff715d7475421af69157b102accaca Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Dec 2006 14:39:14 -0800 Subject: [PATCH 14/22] Disable configure-disabled outputs before mode setting. We're not supposed to turn off pipes/planes/dplls with outputs attached, which we could have done before this. --- src/i830_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 7da4bf55..09488ab6 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3173,6 +3173,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]; @@ -3188,8 +3190,6 @@ I830EnterVT(int scrnIndex, int flags) i830PipeSetBase(crtc, crtc->x, crtc->y); } - i830DisableUnusedFunctions(pScrn); - i830DumpRegs (pScrn); i830DescribeOutputConfiguration(pScrn); From 3b5703c7fa08e63f2a31be7496ded9c70015946d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 19 Dec 2006 09:49:49 -0800 Subject: [PATCH 15/22] Respect the srcdir. --- src/ch7xxx/Makefile.am | 2 +- src/sil164/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index d63c7fc9..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@ -I../ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index d4c0cbd2..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@ -I../ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version From ff1223142aedcf888665de6e4d7d5d03a55b2688 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 19 Dec 2006 12:49:55 -0800 Subject: [PATCH 16/22] Only erase curMode in i830DisableUnusedFunctions when the CRTC is disabled. This bug resulted in broken xinerama, among other issues. --- src/i830_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index 4899763b..88f6f163 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -987,9 +987,9 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling CRTC %s\n", pipe_name); crtc->funcs->dpms(crtc, DPMSModeOff); - } - memset(&crtc->curMode, 0, sizeof(crtc->curMode)); + memset(&crtc->curMode, 0, sizeof(crtc->curMode)); + } } } From 293ad158ece941eeb9894f5af4d663464b9954e5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 19 Dec 2006 14:35:51 -0800 Subject: [PATCH 17/22] Remove 8k framebuffer stride restriction on 965. Also, clean up the message if the limitation is hit. --- src/i830_driver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 09488ab6..7309675b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1840,8 +1840,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; } From 3c86fdda1d09fd22d4c15a8e412611db4cea7dcf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Dec 2006 15:53:07 -0800 Subject: [PATCH 18/22] Turn on dithering for 915 textured video --- src/i915_video.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/i915_video.c b/src/i915_video.c index fb3f4fcc..c2f01848 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(x1 & 3)| DRAW_DITHER_OFS_Y(y1 & 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 | From c0a0ddc0ce69b60ac3a58d45cb32ccd0e0bfb0c9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 19 Dec 2006 16:06:13 -0800 Subject: [PATCH 19/22] Bug #9382: Save the CRTC's desired mode in the old RandR 1.0 mode set path. --- src/i830_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i830_display.c b/src/i830_display.c index 88f6f163..e3fdf6d2 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1013,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", From 05cd921140fae2746c3421715d7f18248a66735a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Dec 2006 16:21:46 -0800 Subject: [PATCH 20/22] Align textured video dither matrix to window --- src/i915_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i915_video.c b/src/i915_video.c index c2f01848..636b2cbd 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -103,7 +103,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, /* draw rect -- just clipping */ OUT_RING(_3DSTATE_DRAW_RECT_CMD); - OUT_RING(DRAW_DITHER_OFS_X(x1 & 3)| DRAW_DITHER_OFS_Y(y1 & 3)); /* 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 */ From 2ef4c5e8f6444aad192304e5a2f7a0c77bfb917d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Dec 2006 16:45:39 -0800 Subject: [PATCH 21/22] Re-initialize physical screen size only if -dpi was passed. Physical screen size from the config file or DDC will already be set correctly in the screen structure, unless it was computed from the virtual size using the -dpi command line option. Recompute physical size as we reset the screen size if the -dpi option was used. --- src/i830_randr.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) 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); From c28075e1d70c98b39fc9829a6a01da171a9b9426 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Dec 2006 21:53:10 -0800 Subject: [PATCH 22/22] TV output I830OutputPrivate had wrong type (crashed in SetMode). TV output private type field was set to I830_OUTPUT_SDVO instead of I830_OUTPUT_TVOUT. When DGA mode setting occurred, the sdvo output debug code would be invoked and attempt to dereference sdvo-specific bits of the private structure leading to a segfault. --- src/i830_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_tv.c b/src/i830_tv.c index af9826b0..68527934 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -774,7 +774,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;