From 24406877fb30ad5ef53df02f63bad10b34e05552 Mon Sep 17 00:00:00 2001 From: Connor Behan Date: Tue, 13 May 2014 21:07:49 -0700 Subject: [PATCH] Failed attempt at DDC Content-Type: text/plain; charset="utf-8" This modifies the DDCReg code to make it as similar as possible to the code in r128-support branch of radeon. --- src/r128_output.c | 128 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/src/r128_output.c b/src/r128_output.c index 41c26cc..e99e620 100644 --- a/src/r128_output.c +++ b/src/r128_output.c @@ -192,47 +192,77 @@ static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output) R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; R128OutputPrivatePtr r128_output = output->driver_private; - - R128MonitorType MonType = MT_NONE; xf86MonPtr *MonInfo = &output->MonInfo; - if (r128_output->pI2CBus && info->isDFP) { - /* XXX: Radeon does something more complicated to appease old monitors - * but it might be dangerous to put that here because r128 and radeon - * DDC registers are slightly different. */ - - OUTREG(info->DDCReg, (INREG(info->DDCReg) - | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3)); - - OUTREG(info->DDCReg, INREG(info->DDCReg) - & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3)); - - *MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), r128_output->pI2CBus); - } else if (info->isDFP) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n"); - MonType = MT_NONE; + if (r128_output->num == 0) { + return MT_LCD; } else { - /* XXX: For non-DFP cards we just have to assume? */ - if (r128_output->num == 0) - return MT_LCD; - else - return MT_CRT; + /* For output 1 (VGA), radeon_bios.c uses RADEON_GPIO_VGA_DDC at offset 0x0060. */ + CARD32 DDCReg = 0x0060; + info->DDCReg = DDCReg; + int i, j; + + R128TRACE(("Code gets to here.\n")); + + OUTREG(DDCReg, INREG(DDCReg) & + (CARD32)~(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_1)); + + R128TRACE(("Code does not get to here.\n")); + + /* For some old monitors (like Compaq Presario FP500), we need + * following process to initialize/stop DDC + */ + OUTREG(DDCReg, INREG(DDCReg) & ~(R128_GPIO_MONID_EN_1)); + for (j = 0; j < 3; j++) { + OUTREG(DDCReg, + INREG(DDCReg) & ~(R128_GPIO_MONID_EN_0)); + usleep(13000); + + OUTREG(DDCReg, + INREG(DDCReg) & ~(R128_GPIO_MONID_EN_1)); + for (i = 0; i < 10; i++) { + usleep(15000); + if (INREG(DDCReg) & R128_GPIO_MONID_Y_1) + break; + } + if (i == 10) continue; + + usleep(15000); + + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_0); + usleep(15000); + + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_1); + usleep(15000); + OUTREG(DDCReg, + INREG(DDCReg) & ~(R128_GPIO_MONID_EN_0)); + usleep(15000); + + *MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), r128_output->pI2CBus); + + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_0); + usleep(15000); + OUTREG(DDCReg, + INREG(DDCReg) & ~(R128_GPIO_MONID_EN_1)); + for (i = 0; i < 5; i++) { + usleep(15000); + if (INREG(DDCReg) & R128_GPIO_MONID_Y_1) + break; + } + usleep(15000); + OUTREG(DDCReg, + INREG(DDCReg) & ~(R128_GPIO_MONID_EN_0)); + usleep(15000); + + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | R128_GPIO_MONID_EN_0); + usleep(15000); + if (*MonInfo) return MT_CRT; + } } - if (*MonInfo) { - if ((*MonInfo)->rawData[0x14] & 0x80) { - if (INREG(R128_FP_GEN_CNTL) & R128_FP_TDMS_EN) - MonType = MT_DFP; - else - MonType = MT_LCD; - } else { - MonType = MT_CRT; - } - } else { - MonType = MT_NONE; - } - - return MonType; + return MT_NONE; } static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output) @@ -307,9 +337,15 @@ static void R128I2CGetBits(I2CBusPtr b, int *Clock, int *data) unsigned long val; unsigned char *R128MMIO = info->MMIO; + /* Execution never gets here, but just in case, we make it the same as + * radeon. The clock and data regs are both 0x0060. The masks are Y_1 + * and Y_0 respectively. + */ + /* Get the result. */ val = INREG(info->DDCReg); - *Clock = (val & R128_GPIO_MONID_Y_3) != 0; + *Clock = (val & R128_GPIO_MONID_Y_1) != 0; + val = INREG(info->DDCReg); *data = (val & R128_GPIO_MONID_Y_0) != 0; } @@ -321,11 +357,22 @@ static void R128I2CPutBits(I2CBusPtr b, int Clock, int data) unsigned long val; unsigned char *R128MMIO = info->MMIO; - val = INREG(info->DDCReg) - & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3); - val |= (Clock ? 0:R128_GPIO_MONID_EN_3); + /* Execution never gets here, but just in case, we make it the same as + * radeon. The clock and data regs are both 0x0060. The masks are EN_1 + * and EN_0 respectively. + */ + + val = INREG(info->DDCReg) & (CARD32)~(R128_GPIO_MONID_EN_1); + val |= (Clock ? 0:R128_GPIO_MONID_EN_1); + OUTREG(info->DDCReg, val); + /* read back to improve reliability on some cards. */ + val = INREG(info->DDCReg); + + val = INREG(info->DDCReg) & (CARD32)~(R128_GPIO_MONID_EN_0); val |= (data ? 0:R128_GPIO_MONID_EN_0); OUTREG(info->DDCReg, val); + /* read back to improve reliability on some cards. */ + val = INREG(info->DDCReg); } static Bool R128I2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name) @@ -334,7 +381,6 @@ static Bool R128I2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name) R128InfoPtr info = R128PTR(pScrn); I2CBusPtr pI2CBus; - info->DDCReg = R128_GPIO_MONID; if ( !xf86LoadSubModule(pScrn, "i2c") ) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to load i2c module\n"); -- 1.9.2