diff --git a/src/radeon_display.c b/src/radeon_display.c index d661c17..7479803 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -48,6 +48,7 @@ #include "radeon_version.h" #include "radeon_mergedfb.h" extern int getRADEONEntityIndex(void); +extern xf86MonPtr RADEONProbeDDC(ScrnInfoPtr pScrn, int indx); const char *MonTypeName[7] = { "AUTO", @@ -546,6 +547,8 @@ static RADEONMonitorType RADEONDisplayDD RADEONMonitorType MonType = MT_NONE; xf86MonPtr* MonInfo = &port->MonInfo; int i, j; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + int vbeProbe = FALSE;; DDCReg = info->DDCReg; switch(DDCType) @@ -564,7 +567,7 @@ static RADEONMonitorType RADEONDisplayDD break; default: info->DDCReg = DDCReg; - return MT_NONE; + /* Fall through, can still try vbe probing */ } /* Read and output monitor info using DDC2 over I2C bus */ @@ -630,6 +633,15 @@ static RADEONMonitorType RADEONDisplayDD OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1)); + if ((!*MonInfo) && ((port == pRADEONEnt->PortInfo[0]) || + (RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[1]->DACType)) + == MT_CRT))) { + vbeProbe = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC probing on port %d ::: \n", + (port == pRADEONEnt->PortInfo[0])? 1:2); + *MonInfo = RADEONProbeDDC(pScrn, info->pEnt->index); + } + if (*MonInfo) { if ((*MonInfo)->rawData[0x14] & 0x80) { /* Note some laptops have a DVI output that uses internal TMDS, @@ -639,14 +651,32 @@ static RADEONMonitorType RADEONDisplayDD * Also for laptop, when X starts with lid closed (no DVI connection) * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel. */ - if (port->TMDSType == TMDS_EXT) MonType = MT_DFP; - else { - if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility) - MonType = MT_DFP; - else - MonType = MT_LCD; + if (vbeProbe && + (RADEONCrtIsPhysicallyConnected(pScrn, !(port->DACType)) == MT_CRT)) { + MonType = MT_NONE; + *MonInfo = NULL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE probed DDC info nullified on port %d :::\n", (port == pRADEONEnt->PortInfo[0])? 1:2); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT physically connected but digital device indicated in DDC\n"); + } else { + if (port->TMDSType == TMDS_EXT) MonType = MT_DFP; + else { + if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility) + MonType = MT_DFP; + else + MonType = MT_LCD; + } } - } else MonType = MT_CRT; + } else { + if ((RADEONCrtIsPhysicallyConnected(pScrn, + !(pRADEONEnt->PortInfo[1]->DACType)) == MT_CRT) && vbeProbe && + (pRADEONEnt->HasCRTC2) && (port == pRADEONEnt->PortInfo[0])) { + MonType = MT_NONE; + *MonInfo = NULL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC info nullified on port 1 :::\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Analog device indicated in DDC but port 2 CRT physically connected\n"); + } else + MonType = MT_CRT; + } } else MonType = MT_NONE; info->DDCReg = DDCReg; @@ -947,9 +977,11 @@ void RADEONSetupConnectors(ScrnInfoPtr p pRADEONEnt->Controller[0]->IsActive = FALSE; pRADEONEnt->Controller[1]->IsActive = FALSE; + /* On a lot of laptops, DDCType is deteced 0 on port 0, and DDCType for + port 1 may be wrong too. Use default common setting + */ if (!RADEONGetConnectorInfoFromBIOS(pScrn) || - ((pRADEONEnt->PortInfo[0]->DDCType == 0) && - (pRADEONEnt->PortInfo[1]->DDCType == 0))) { + (pRADEONEnt->PortInfo[0]->DDCType == 0)) { /* Below is the most common setting, but may not be true */ pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN; pRADEONEnt->PortInfo[0]->MonInfo = NULL; @@ -1117,9 +1149,14 @@ #if 0 pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN; pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA; pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT; + /* Don't know why need to set port 1, but at least DDCType can't be + set to DDC_NONE_DETECTED, since this will prevent probing + */ pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC; pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN; + /* pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED; + */ pRADEONEnt->PortInfo[0]->ConnectorType = pRADEONEnt->PortInfo[0]->MonType+1; pRADEONEnt->PortInfo[0]->MonInfo = NULL; } @@ -1222,7 +1259,6 @@ static void RADEONQueryConnectedDisplays if (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN || pRADEONEnt->PortInfo[1]->MonType == MT_UNKNOWN) { - if ((!pRADEONEnt->HasCRTC2) && (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN)) { if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI, pRADEONEnt->PortInfo[0]))); diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 1d217ae..191a787 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -2935,15 +2935,18 @@ static Bool RADEONPreInitControllers(Scr return TRUE; } -static void +xf86MonPtr RADEONProbeDDC(ScrnInfoPtr pScrn, int indx) { vbeInfoPtr pVbe; - - if (xf86LoadSubModule(pScrn, "vbe")) { - pVbe = VBEInit(NULL,indx); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - } + xf86MonPtr monitor; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,indx); + monitor = vbeDoEDID(pVbe, NULL); + return (monitor); + } else + return (NULL); } _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) @@ -3032,7 +3035,7 @@ #endif } if (flags & PROBE_DETECT) { - RADEONProbeDDC(pScrn, info->pEnt->index); + ConfiguredMonitor = RADEONProbeDDC(pScrn, info->pEnt->index); RADEONPostInt10Check(pScrn, int10_save); if(info->MMIO) RADEONUnmapMMIO(pScrn); return TRUE;