diff options
author | David Airlie <airlied@linux.ie> | 2007-02-02 14:15:03 +1100 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-02-02 15:34:22 +1100 |
commit | 76bc53f9b153880730ab61dcd2b6e4e7717e4058 (patch) | |
tree | b38a594a2117effcc584636bd7abbfe9089c923f | |
parent | 47fb9ce657f018177a35b449a4d716dc03be9327 (diff) |
move i2c buses into outputs
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_display.c | 123 | ||||
-rw-r--r-- | src/radeon_driver.c | 2 | ||||
-rw-r--r-- | src/radeon_modes.c | 112 | ||||
-rw-r--r-- | src/radeon_probe.h | 2 |
5 files changed, 93 insertions, 148 deletions
diff --git a/src/radeon.h b/src/radeon.h index 211385d..204c1f2 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -476,8 +476,6 @@ typedef struct { Bool ddc_bios; Bool ddc1; Bool ddc2; - I2CBusPtr pI2CBus; - CARD32 DDCReg; RADEONPLLRec pll; RADEONTMDSPll tmds_pll[4]; diff --git a/src/radeon_display.c b/src/radeon_display.c index 07df70d..813f277 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -177,7 +177,7 @@ static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data) unsigned char *RADEONMMIO = info->MMIO; /* Get the result */ - val = INREG(info->DDCReg); + val = INREG(b->DriverPrivate.uval); *Clock = (val & RADEON_GPIO_Y_1) != 0; *data = (val & RADEON_GPIO_Y_0) != 0; @@ -190,29 +190,32 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) unsigned long val; unsigned char *RADEONMMIO = info->MMIO; - val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1); + val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1); val |= (Clock ? 0:RADEON_GPIO_EN_1); val |= (data ? 0:RADEON_GPIO_EN_0); - OUTREG(info->DDCReg, val); + OUTREG(b->DriverPrivate.uval, val); /* read back to improve reliability on some cards. */ - val = INREG(info->DDCReg); + val = INREG(b->DriverPrivate.uval); } -Bool RADEONI2cInit(ScrnInfoPtr pScrn) +Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) { - RADEONInfoPtr info = RADEONPTR(pScrn); + I2CBusPtr pI2CBus; + + pI2CBus = xf86CreateI2CBusRec(); + if (!pI2CBus) return FALSE; - info->pI2CBus = xf86CreateI2CBusRec(); - if (!info->pI2CBus) return FALSE; + pI2CBus->BusName = name; + pI2CBus->scrnIndex = pScrn->scrnIndex; + pI2CBus->I2CPutBits = RADEONI2CPutBits; + pI2CBus->I2CGetBits = RADEONI2CGetBits; + pI2CBus->AcknTimeout = 5; + pI2CBus->DriverPrivate.uval = i2c_reg; - info->pI2CBus->BusName = "DDC"; - info->pI2CBus->scrnIndex = pScrn->scrnIndex; - info->pI2CBus->I2CPutBits = RADEONI2CPutBits; - info->pI2CBus->I2CGetBits = RADEONI2CGetBits; - info->pI2CBus->AcknTimeout = 5; + if (!xf86I2CBusInit(pI2CBus)) return FALSE; - if (!xf86I2CBusInit(info->pI2CBus)) return FALSE; + *bus_ptr = pI2CBus; return TRUE; } @@ -550,88 +553,71 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) } -static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr port) +static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr output) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; unsigned long DDCReg; RADEONMonitorType MonType = MT_NONE; - xf86MonPtr* MonInfo = &port->MonInfo; - RADEONOutputPrivatePtr radeon_output = port->driver_private; + xf86MonPtr* MonInfo = &output->MonInfo; + RADEONOutputPrivatePtr radeon_output = output->driver_private; int i, j; - DDCReg = info->DDCReg; - switch(DDCType) - { - case DDC_MONID: - info->DDCReg = RADEON_GPIO_MONID; - break; - case DDC_DVI: - info->DDCReg = RADEON_GPIO_DVI_DDC; - break; - case DDC_VGA: - info->DDCReg = RADEON_GPIO_VGA_DDC; - break; - case DDC_CRT2: - info->DDCReg = RADEON_GPIO_CRT2_DDC; - break; - default: - info->DDCReg = DDCReg; - return MT_NONE; - } + DDCReg = radeon_output->DDCReg; /* Read and output monitor info using DDC2 over I2C bus */ - if (info->pI2CBus && info->ddc2) { - OUTREG(info->DDCReg, INREG(info->DDCReg) & + if (radeon_output->pI2CBus && info->ddc2) { + + OUTREG(DDCReg, INREG(DDCReg) & (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1)); /* For some old monitors (like Compaq Presario FP500), we need * following process to initialize/stop DDC */ - OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (j = 0; j < 3; j++) { - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(13000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (i = 0; i < 10; i++) { usleep(15000); - if (INREG(info->DDCReg) & RADEON_GPIO_Y_1) + if (INREG(DDCReg) & RADEON_GPIO_Y_1) break; } if (i == 10) continue; usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(15000); - *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus); + *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (i = 0; i < 5; i++) { usleep(15000); - if (INREG(info->DDCReg) & RADEON_GPIO_Y_1) + if (INREG(DDCReg) & RADEON_GPIO_Y_1) break; } usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); if(*MonInfo) break; } @@ -640,7 +626,7 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT MonType = MT_NONE; } - OUTREG(info->DDCReg, INREG(info->DDCReg) & + OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1)); if (*MonInfo) { @@ -662,8 +648,6 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT } else MonType = MT_CRT; } else MonType = MT_NONE; - info->DDCReg = DDCReg; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Type: %d, Detected Type: %d\n", DDCType, MonType); @@ -1140,7 +1124,24 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I; pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN; } + } + for (i = 0; i < 2; i++) { + int DDCReg = 0; + char *names[] = { "DDC1", "DDC2" }; + + switch(pRADEONEnt->PortInfo[i]->DDCType) { + case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break; + case DDC_DVI : DDCReg = RADEON_GPIO_DVI_DDC; break; + case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break; + case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break; + default: break; + } + + if (DDCReg) { + pRADEONEnt->PortInfo[i]->DDCReg = DDCReg; + RADEONI2CInit(pScrn, &pRADEONEnt->PortInfo[i]->pI2CBus, DDCReg, names[i]); + } } } diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 2706a0d..5371c4c 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -1922,9 +1922,7 @@ static void RADEONPreInitDDC(ScrnInfoPtr pScrn) if (info->ddc2) { if (xf86LoadSubModule(pScrn, "i2c")) { xf86LoaderReqSymLists(i2cSymbols,NULL); - info->ddc2 = RADEONI2cInit(pScrn); } - else info->ddc2 = FALSE; } } diff --git a/src/radeon_modes.c b/src/radeon_modes.c index 16c2c30..fb7727e 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -269,65 +269,49 @@ RADEONProbeOutputModes(xf86OutputPtr output) RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; - DisplayModePtr ddc_modes, mode; + DisplayModePtr mode; DisplayModePtr test; + xf86MonPtr edid_mon; + DisplayModePtr modes; /* force reprobe */ radeon_output->MonType = MT_UNKNOWN; RADEONConnectorFindMonitor(pScrn, output); - - /* okay we got DDC info */ - if (output->MonInfo) { - /* Debug info for now, at least */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num); - xf86PrintEDID(output->MonInfo); - - ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo); + + if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) { + edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); + xf86OutputSetEDID (output, edid_mon); - for (mode = ddc_modes; mode != NULL; mode = mode->next) { - if (mode->Flags & V_DBLSCAN) { - if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768)) + output->probed_modes = xf86OutputGetEDIDModes (output); + return; + } + if (radeon_output->type == OUTPUT_LVDS) { + /* okay we got DDC info */ + if (output->MonInfo) { + /* Debug info for now, at least */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num); + xf86PrintEDID(output->MonInfo); + + modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo); + + for (mode = modes; mode != NULL; mode = mode->next) { + if (mode->Flags & V_DBLSCAN) { + if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768)) mode->status = MODE_CLOCK_RANGE; + } } + xf86PruneInvalidModes(pScrn, &modes, TRUE); + + /* do some physcial size stuff */ } - xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE); - /* do some physcial size stuff */ - } - - - if (output->probed_modes == NULL) { - MonRec fixed_mon; - DisplayModePtr modes; - switch(radeon_output->MonType) { - case MT_CRT: - case MT_DFP: - - /* We've got a potentially-connected monitor that we can't DDC. Return a - * fixed set of VESA plus user modes for a presumed multisync monitor with - * some reasonable limits. - */ - fixed_mon.nHsync = 1; - fixed_mon.hsync[0].lo = 31.0; - fixed_mon.hsync[0].hi = 100.0; - fixed_mon.nVrefresh = 1; - fixed_mon.vrefresh[0].lo = 50.0; - fixed_mon.vrefresh[0].hi = 70.0; - - modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes); - xf86ValidateModesSync(pScrn, modes, &fixed_mon); - xf86PruneInvalidModes(pScrn, &modes, TRUE); - /* fill out CRT of FP mode table */ - output->probed_modes = modes; - break; + if (output->probed_modes == NULL) { + MonRec fixed_mon; + DisplayModePtr modes; - case MT_LCD: RADEONValidateFPModes(pScrn, pScrn->display->modes, &output->probed_modes); - break; - default: - break; } } @@ -339,42 +323,4 @@ RADEONProbeOutputModes(xf86OutputPtr output) } } -/** - * Takes the output mode lists and decides the default root window size - * and framebuffer pitch. - */ -void -RADEON_set_default_screen_size(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - int maxX = -1, maxY = -1; - int i; - - /* Set up a virtual size that will cover any clone mode we'd want to - * set for the currently-connected outputs. - */ - for (i = 0; i < RADEON_MAX_CONNECTOR; i++) { - DisplayModePtr mode; - - for (mode = pRADEONEnt->pOutput[i]->probed_modes; mode != NULL; - mode = mode->next) - { - if (mode->HDisplay > maxX) - maxX = mode->HDisplay; - if (mode->VDisplay > maxY) - maxY = mode->VDisplay; - } - } - /* let the user specify a bigger virtual size if they like */ - if (pScrn->display->virtualX > maxX) - maxX = pScrn->display->virtualX; - if (pScrn->display->virtualY > maxY) - maxY = pScrn->display->virtualY; - pScrn->virtualX = maxX; - pScrn->virtualY = maxY; - pScrn->displayWidth = (maxX + 63) & ~63; -} - - diff --git a/src/radeon_probe.h b/src/radeon_probe.h index b62bcf6..66210a4 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -132,6 +132,8 @@ typedef struct _RADEONOutputPrivateRec { RADEONConnectorType ConnectorType; RADEONMonitorType MonType; int crtc_num; + int DDCReg; + I2CBusPtr pI2CBus; } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr; #define RADEON_MAX_CONNECTOR 2 |