From a156db5e8b037ed12a448f70045453baf9d0c504 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Sat, 4 Aug 2007 17:37:18 +1000 Subject: Clean up PortInfo to CRTC mapping Also sanitise blanking and DPMS functions Fixes from Novell Bug 264720, and fd.o 10772 --- src/radeon.h | 4 +- src/radeon_display.c | 566 +++++++++++++++++++++------------------------------ src/radeon_driver.c | 93 +++------ src/radeon_probe.h | 3 - 4 files changed, 265 insertions(+), 401 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index a22e481..5f3f4ab 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -904,14 +904,12 @@ extern void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort extern void RADEONDisableDisplays(ScrnInfoPtr pScrn); extern void RADEONGetPanelInfo(ScrnInfoPtr pScrn); extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn); -extern void RADEONUnblank(ScrnInfoPtr pScrn); -extern void RADEONBlank(ScrnInfoPtr pScrn); +extern void RADEONBlank(ScrnInfoPtr pScrn, Bool Blank); extern void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn); extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn); -extern RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num); extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn); extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName, RADEONMonitorType DisplayType, int crtc2); diff --git a/src/radeon_display.c b/src/radeon_display.c index 6ae8862..0bf7271 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -941,6 +941,16 @@ void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn) } } +static void +RADEONConnectorReverse(RADEONEntPtr pRADEONEnt) +{ + RADEONConnector *connector; + + connector = pRADEONEnt->PortInfo[0]; + pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; + pRADEONEnt->PortInfo[1] = connector; +} + /* * initialise the static data sos we don't have to re-do at randr change */ void RADEONSetupConnectors(ScrnInfoPtr pScrn) @@ -998,12 +1008,9 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) } /* always make TMDS_INT port first*/ - if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) { - RADEONConnector *connector; - connector = pRADEONEnt->PortInfo[0]; - pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; - pRADEONEnt->PortInfo[1] = connector; - } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT && + if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) + RADEONConnectorReverse(pRADEONEnt); + else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT && pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) { /* no TMDS_INT port, make primary DAC port first */ /* On my Inspiron 8600 both internal and external ports are @@ -1011,10 +1018,7 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) swap when the first port is not DAC_PRIMARY */ if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) && (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) && (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) { - RADEONConnector *connector; - connector = pRADEONEnt->PortInfo[0]; - pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; - pRADEONEnt->PortInfo[1] = connector; + RADEONConnectorReverse(pRADEONEnt); } } @@ -1269,10 +1273,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN; pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN; pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE; - - pRADEONEnt->PortInfo[0]->crtc_num = 1; - pRADEONEnt->PortInfo[1]->crtc_num = 2; - + return; } @@ -1307,16 +1308,12 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; Bool head_reversed = FALSE; - RADEONConnector *connector; info->MergeType = MT_NONE; if (!info->IsSecondary) { RADEONQueryConnectedDisplays(pScrn); - pRADEONEnt->PortInfo[0]->crtc_num = 1; - pRADEONEnt->PortInfo[1]->crtc_num = 2; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port1:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n", MonTypeName[pRADEONEnt->PortInfo[0]->MonType+1], @@ -1341,8 +1338,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE) { if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE) { /* Only one detected on secondary, let it to be primary */ - pRADEONEnt->PortInfo[0]->crtc_num = 2; - pRADEONEnt->PortInfo[1]->crtc_num = 1; + if (!head_reversed) + RADEONConnectorReverse(pRADEONEnt); head_reversed = TRUE; } else { /* None detected, Default to a CRT connected */ @@ -1354,10 +1351,10 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) (pRADEONEnt->PortInfo[1]->MonType == MT_CRT)) { if (!(INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON)) { /* LCD is switched off, don't turn it on, otherwise it may casue lockup due to SS issue. */ - pRADEONEnt->PortInfo[0]->crtc_num = 2; - pRADEONEnt->PortInfo[1]->crtc_num = 1; - pRADEONEnt->PortInfo[0]->MonType = MT_NONE; + if (!head_reversed) + RADEONConnectorReverse(pRADEONEnt); head_reversed = TRUE; + pRADEONEnt->PortInfo[0]->MonType = MT_NONE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD is switched off, only CRT will be used\n"); } } @@ -1371,8 +1368,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) */ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Reverse Display cannot be used for mobility chip\n"); } else { - pRADEONEnt->PortInfo[0]->crtc_num = 2; - pRADEONEnt->PortInfo[1]->crtc_num = 1; + if (!head_reversed) + RADEONConnectorReverse(pRADEONEnt); head_reversed = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Primary and Secondary mapping is reversed\n"); } @@ -1386,46 +1383,33 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) if(pRADEONEnt->HasCRTC2) { if(info->IsSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); pRADEONEnt->Controller[1]->binding = 2; - if (connector) { - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; - } + info->DisplayType = pRADEONEnt->PortInfo[1]->MonType; + pScrn->monitor->DDC = pRADEONEnt->PortInfo[1]->MonInfo; } else { - connector = RADEONGetCrtcConnector(pScrn, 1); pRADEONEnt->Controller[0]->binding = 1; - if (connector) { - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; - } + info->DisplayType = pRADEONEnt->PortInfo[0]->MonType; + pScrn->monitor->DDC = pRADEONEnt->PortInfo[0]->MonInfo; } - + if(!pRADEONEnt->HasSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); - if (connector) - info->MergeType = connector->MonType; + info->MergeType = pRADEONEnt->PortInfo[1]->MonType; if (info->MergeType) pRADEONEnt->Controller[1]->binding = 1; - } - } else { - connector = RADEONGetCrtcConnector(pScrn, 1); - if (connector) { - if (connector->MonType == MT_NONE) - connector->MonType = MT_CRT; - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; } - connector = RADEONGetCrtcConnector(pScrn, 2); - if (connector) - connector->MonType = MT_NONE; + } else { + if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE) + pRADEONEnt->PortInfo[0]->MonType = MT_CRT; + info->DisplayType = pRADEONEnt->PortInfo[0]->MonType; + pScrn->monitor->DDC = pRADEONEnt->PortInfo[0]->MonInfo; + + pRADEONEnt->PortInfo[1]->MonType = MT_NONE; pRADEONEnt->Controller[1]->binding = 1; } if (!info->IsSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head: Port%d ---- \n", head_reversed?2:1); - if (connector->MonType != MT_NONE) + if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2); else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n"); @@ -2031,259 +2015,247 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2); } -static void RADEONBlankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort) +static void +RADEONOutputsBlank(ScrnInfoPtr pScrn, RADEONConnector *pPort, Bool Blank) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; switch(pPort->MonType) { case MT_LCD: - OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS); + if (Blank) + OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS); + else + OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS); break; - case MT_CRT: - if ((info->ChipFamily == CHIP_FAMILY_R200) && - (pPort->DACType == DAC_TVDAC)) - OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - + if ((info->ChipFamily == CHIP_FAMILY_R200) && (pPort->DACType == DAC_TVDAC)) { + if (Blank) + OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + else + OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + } break; case MT_DFP: - if (pPort->TMDSType == TMDS_EXT) - OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - else - OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN); - + if (pPort->TMDSType == TMDS_EXT) { + if (Blank) + OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + else + OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + } else { + if (Blank) + OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN); + else + OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN); + } break; case MT_NONE: default: break; - } + } +} + +static void +RADEONCRTC1Blank(RADEONInfoPtr info, Bool Blank) +{ + unsigned char *RADEONMMIO = info->MMIO; + + if (Blank) + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS, + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS)); + else + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS)); +} + +static void +RADEONCRTC2Blank(RADEONInfoPtr info, Bool Blank) +{ + unsigned char *RADEONMMIO = info->MMIO; + + if (Blank) + OUTREGP(RADEON_CRTC2_GEN_CNTL, + RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS, + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); + else + OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); } /* Blank screen */ -void RADEONBlank(ScrnInfoPtr pScrn) +void RADEONBlank(ScrnInfoPtr pScrn, Bool Blank) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONConnector *pPort; if (!pRADEONEnt->HasSecondary || (pRADEONEnt->HasSecondary && !info->IsSwitching) || (info->IsSwitching && (!info->IsSecondary))) { - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC_EXT_CNTL, - RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS, - ~(RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS)); - - if (!pRADEONEnt->HasCRTC2) return; + + RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[0], Blank); + RADEONCRTC1Blank(info, Blank); + + if (!pRADEONEnt->HasCRTC2) + return; if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC2_GEN_CNTL, - RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[1], Blank); + RADEONCRTC2Blank(info, Blank); } } if ((pRADEONEnt->HasSecondary && !info->IsSwitching) || (info->IsSwitching && info->IsSecondary)) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC2_GEN_CNTL, - RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[1], Blank); + RADEONCRTC2Blank(info, Blank); } } -static void RADEONUnblankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort) + +static void +RADEONOutputsDPMS(ScrnInfoPtr pScrn, RADEONConnector *pPort, int Mode) { - RADEONInfoPtr info = RADEONPTR (pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - switch(pPort->MonType) { + RADEONMonitorType MonType; + RADEONTmdsType TmdsType; + RADEONDacType DacType; + + MonType = pPort->MonType; + TmdsType = pPort->TMDSType; + DacType = pPort->DACType; + + switch (MonType) { case MT_LCD: - OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS); - break; - case MT_CRT: - if ((info->ChipFamily == CHIP_FAMILY_R200) && - (pPort->DACType == DAC_TVDAC)) - OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - break; + if (Mode == DPMSModeOn) { + OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON); + usleep (info->PanelPwrDly * 1000); + OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON); + } else { + unsigned int tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + + /* Asic bug, when turning off LVDS_ON, we have to make sure + RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off */ + if (info->IsMobility || info->IsIGP) + OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); + OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~(RADEON_LVDS_BLON | RADEON_LVDS_ON)); + if (info->IsMobility || info->IsIGP) + OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + } + break; case MT_DFP: - if (pPort->TMDSType == TMDS_EXT) - OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - else - OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN); - break; - case MT_NONE: + if (Mode == DPMSModeOn) { + if (TmdsType == TMDS_EXT) { + OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) + OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + } else + OUTREGP(RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), + ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); + } else { + if (TmdsType == TMDS_EXT) { + OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + } + } else + OUTREGP(RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); + } + break; + case MT_CRT: default: - break; + RADEONDacPowerSet(pScrn, (Mode == DPMSModeOn), (DacType == DAC_PRIMARY)); + break; } } -/* Unblank screen */ -void RADEONUnblank(ScrnInfoPtr pScrn) +void +RADEONCRTC1DPMS(RADEONInfoPtr info, int Mode) { - RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONConnector *pPort; - - if (!pRADEONEnt->HasSecondary || - (pRADEONEnt->HasSecondary && !info->IsSwitching) || - (info->IsSwitching && (!info->IsSecondary))) { - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC_EXT_CNTL, - 0, - ~(RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS)); - - if (!pRADEONEnt->HasCRTC2) return; - - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); - } - } - if ((pRADEONEnt->HasSecondary && !info->IsSwitching) || - (info->IsSwitching && info->IsSecondary)) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + switch (Mode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS)); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS)); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS)); + break; + case DPMSModeOff: + default: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, + (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS), + ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS)); + break; } } -static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - RADEONMonitorType MonType; - RADEONTmdsType TmdsType; - RADEONDacType DacType; - - MonType = pPort->MonType; - TmdsType = pPort->TMDSType; - DacType = pPort->DACType; - - switch(MonType) { - case MT_LCD: - OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON); - usleep (info->PanelPwrDly * 1000); - OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON); - break; - case MT_DFP: - if (TmdsType == TMDS_EXT) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, - ~RADEON_FP2_DVO_EN); - } - } else - OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), - ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); - break; - case MT_CRT: - default: - RADEONDacPowerSet(pScrn, TRUE, (DacType == DAC_PRIMARY)); - break; - } -} - -static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort) +void +RADEONCRTC2DPMS(RADEONInfoPtr info, int Mode) { - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - RADEONMonitorType MonType; - RADEONTmdsType TmdsType; - RADEONDacType DacType; - unsigned long tmpPixclksCntl; - - MonType = pPort->MonType; - TmdsType = pPort->TMDSType; - DacType = pPort->DACType; - - switch(MonType) { - case MT_LCD: - tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); - if (info->IsMobility || info->IsIGP) { - /* Asic bug, when turning off LVDS_ON, we have to make sure - RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); - } - OUTREGP (RADEON_LVDS_GEN_CNTL, 0, - ~(RADEON_LVDS_BLON | RADEON_LVDS_ON)); - if (info->IsMobility || info->IsIGP) { - OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + unsigned char *RADEONMMIO = info->MMIO; + + switch (Mode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); + break; + case DPMSModeOff: + default: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(RADEON_CRTC2_GEN_CNTL, + (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS), + ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS)); + break; + } - break; - case MT_DFP: - if (TmdsType == TMDS_EXT) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); - } - } else - OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); - break; - case MT_CRT: - default: - RADEONDacPowerSet(pScrn, FALSE, (DacType == DAC_PRIMARY)); - break; - } } /* Sets VESA Display Power Management Signaling (DPMS) Mode */ -void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, - int flags) +void +RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - unsigned char *RADEONMMIO = info->MMIO; RADEONConnector *pPort; - if (!pScrn->vtSema) return; + + if (!pScrn->vtSema) + return; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags); #ifdef XF86DRI - if (info->CPStarted) DRILock(pScrn->pScreen, 0); + if (info->CPStarted) + DRILock(pScrn->pScreen, 0); #endif if (info->accelOn) @@ -2292,92 +2264,23 @@ void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, if (info->FBDev) { fbdevHWDPMSSet(pScrn, PowerManagementMode, flags); } else { - int mask1 = (RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_HSYNC_DIS | - RADEON_CRTC_VSYNC_DIS); - int mask2 = (RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS); - - switch (PowerManagementMode) { - case DPMSModeOn: - /* Screen: On; HSync: On, VSync: On */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask1); - } - break; - - case DPMSModeStandby: - /* Screen: Off; HSync: Off, VSync: On */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), - ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), - ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, - (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), - ~mask1); - } - break; - - case DPMSModeSuspend: - /* Screen: Off; HSync: On, VSync: Off */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), - ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), - ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, - (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), - ~mask1); - } - break; - - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, mask1, ~mask1); - } - break; - } + if (info->IsSecondary) { + RADEONCRTC2DPMS(info, PowerManagementMode); + RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[1], PowerManagementMode); + } else { + RADEONCRTC1DPMS(info, PowerManagementMode); + RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[0], PowerManagementMode); - if (PowerManagementMode == DPMSModeOn) { - pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1); - RADEONDPMSSetOn(pScrn, pPort); - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - RADEONDPMSSetOn(pScrn, pPort); - } - } else if ((PowerManagementMode == DPMSModeOff) || - (PowerManagementMode == DPMSModeSuspend) || - (PowerManagementMode == DPMSModeStandby)) { - pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1); - RADEONDPMSSetOff(pScrn, pPort); if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - RADEONDPMSSetOff(pScrn, pPort); + RADEONCRTC2DPMS(info, PowerManagementMode); + RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[1], PowerManagementMode); } - } + } } #ifdef XF86DRI - if (info->CPStarted) DRIUnlock(pScrn->pScreen); + if (info->CPStarted) + DRIUnlock(pScrn->pScreen); #endif } @@ -2405,28 +2308,21 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn) Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - int i; if (pRADEONEnt->PortInfo[0]) return TRUE; - - /* for now always allocate max connectors */ - for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) { - pRADEONEnt->PortInfo[i] = xcalloc(sizeof(RADEONConnector), 1); - if (!pRADEONEnt->PortInfo[i]) + + /* for now always allocate both connectors */ + pRADEONEnt->PortInfo[0] = xcalloc(sizeof(RADEONConnector), 1); + if (!pRADEONEnt->PortInfo[0]) + return FALSE; + + pRADEONEnt->PortInfo[1] = xcalloc(sizeof(RADEONConnector), 1); + if (!pRADEONEnt->PortInfo[1]) { + xfree(pRADEONEnt->PortInfo[0]); return FALSE; } return TRUE; } -RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num) -{ - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num) - return pRADEONEnt->PortInfo[0]; - else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num) - return pRADEONEnt->PortInfo[1]; - return NULL; -} diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 5c20b0e..74323c9 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -2034,9 +2034,8 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE); /* don't use RMX if we have a dual-tmds panels */ - if ((connector = RADEONGetCrtcConnector(pScrn, 2))) - if (connector->MonType == MT_DFP) - info->ddc_mode = TRUE; + if (pRADEONEnt->PortInfo[1]->MonType == MT_DFP) + info->ddc_mode = TRUE; /* don't use RMX if we are Dell Server */ if (info->IsDellServer) info->ddc_mode = TRUE; @@ -5176,11 +5175,8 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtc2Registers(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; - } + RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); + pCRTC2->IsActive = TRUE; } else { RADEONRestoreMemMapRegisters(pScrn, restore); RADEONRestoreCommonRegisters(pScrn, restore); @@ -5192,17 +5188,11 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC1->IsActive = TRUE; - } + RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE); + pCRTC1->IsActive = TRUE; if (pCRTC2->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; - } + RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); + pCRTC2->IsActive = TRUE; } } } else { @@ -5216,17 +5206,11 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC1->IsActive = TRUE; - } - if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; - } + RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE); + pCRTC1->IsActive = TRUE; + if (pCRTC2->binding == 1) { + RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE); + pCRTC2->IsActive = TRUE; } } @@ -5538,7 +5522,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn) fbdevHWRestore(pScrn); return; } - RADEONBlank(pScrn); + RADEONBlank(pScrn, TRUE); OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index); RADEONPllErrataAfterIndex(info); @@ -5602,7 +5586,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn) } } #endif - RADEONUnblank(pScrn); + RADEONBlank(pScrn, FALSE); #if 0 RADEONWaitForVerticalSync(pScrn); @@ -5910,10 +5894,8 @@ static void RADEONInitDAC2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, } } -static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, int crtc_num) +static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, Bool IsPrimary) { - Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE; - if (pPort->MonType == MT_CRT) { if (pPort->DACType == DAC_PRIMARY) { RADEONInitDACRegisters(pScrn, save, mode, IsPrimary); @@ -5921,11 +5903,11 @@ static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, Dis RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary); } } else if (pPort->MonType == MT_LCD) { - if (crtc_num == 1) + if (IsPrimary) RADEONInitRMXRegisters(pScrn, save, mode); RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary); } else if (pPort->MonType == MT_DFP) { - if (crtc_num == 1) + if (IsPrimary) RADEONInitRMXRegisters(pScrn, save, mode); if (pPort->TMDSType == TMDS_INT) { RADEONInitFPRegisters(pScrn, save, mode, IsPrimary); @@ -6095,11 +6077,7 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, } /* get the output connected to this CRTC */ - if (pRADEONEnt->PortInfo[0]->crtc_num == 1) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 1); - } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 1); - } + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], TRUE); if (info->IsDellServer) { save->dac2_cntl = info->SavedReg.dac2_cntl; @@ -6230,12 +6208,8 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid; /* get the output connected to this CRTC */ - if (pRADEONEnt->PortInfo[0]->crtc_num == 2) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 2); - } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 2); - } - + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], FALSE); + /* We must set SURFACE_CNTL properly on the second screen too */ save->surface_cntl = 0; #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -6568,9 +6542,9 @@ static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; pScrn->vtSema = TRUE; - RADEONBlank(pScrn); + RADEONBlank(pScrn, TRUE); RADEONRestoreMode(pScrn, &info->ModeReg); - RADEONUnblank(pScrn); + RADEONBlank(pScrn, FALSE); info->CurrentLayout.mode = mode; @@ -6592,8 +6566,10 @@ static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) if (unblank) SetTimeSinceLastInputEvent(); if ((pScrn != NULL) && pScrn->vtSema) { - if (unblank) RADEONUnblank(pScrn); - else RADEONBlank(pScrn); + if (unblank) + RADEONBlank(pScrn, FALSE); + else + RADEONBlank(pScrn, TRUE); } return TRUE; } @@ -7152,7 +7128,7 @@ static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONConnector *connector; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); char *strptr; char *default_hsync = "28-33"; char *default_vrefresh = "43-72"; @@ -7182,12 +7158,10 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) info->MergedFB = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n"); - } else if ((connector = RADEONGetCrtcConnector(pScrn, 2))) { - if (!connector->MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n"); - default_range = TRUE; - } + } else if (!pRADEONEnt->PortInfo[1]->MonInfo) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n"); + default_range = TRUE; } if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) { @@ -7352,8 +7326,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */ - connector = RADEONGetCrtcConnector(pScrn, 2); - info->CRT2pScrn->monitor->DDC = connector ? connector->MonInfo : NULL; + info->CRT2pScrn->monitor->DDC = pRADEONEnt->PortInfo[1]->MonInfo; if (default_range) { RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC); diff --git a/src/radeon_probe.h b/src/radeon_probe.h index dc30e2e..dfec12f 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -119,9 +119,6 @@ typedef struct RADEONConnectorType ConnectorType; RADEONMonitorType MonType; xf86MonPtr MonInfo; - - /* one connector can be bound to one CRTC */ - int crtc_num; } RADEONConnector; -- cgit v1.2.3