diff options
author | Alex Deucher <alex@t41p.hsd1.va.comcast.net> | 2007-12-17 18:51:31 -0500 |
---|---|---|
committer | Alex Deucher <alex@t41p.hsd1.va.comcast.net> | 2007-12-17 18:51:31 -0500 |
commit | 4da3782239921eb377216d4de4a9cc5bb55e0e8a (patch) | |
tree | 0116590e446475884493681d42a84f99fd636487 | |
parent | 5c5d2d19b2b032a06dd333b4ecc029aac342fb93 (diff) |
RADEON: add output enable masks
add output enable masks for outputs that drive
more than one connector. Make sure we don't turn off
an output that's driving another connector.
-rw-r--r-- | src/radeon.h | 8 | ||||
-rw-r--r-- | src/radeon_display.c | 129 | ||||
-rw-r--r-- | src/radeon_output.c | 8 |
3 files changed, 96 insertions, 49 deletions
diff --git a/src/radeon.h b/src/radeon.h index 67315a2d..03db3604 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -850,6 +850,14 @@ typedef struct { #endif RADEONExtTMDSChip ext_tmds_chip; + /* output enable masks for outputs shared across connectors */ + int output_crt1; + int output_crt2; + int output_dfp1; + int output_dfp2; + int output_lcd1; + int output_tv1; + Rotation rotation; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; diff --git a/src/radeon_display.c b/src/radeon_display.c index 9437ef48..95f6b096 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -322,19 +322,28 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) unsigned char * RADEONMMIO = info->MMIO; unsigned long tmp; RADEONOutputPrivatePtr radeon_output; - int tv_dac_change = 0; + int tv_dac_change = 0, o; radeon_output = output->driver_private; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + for (o = 0; o < xf86_config->num_output; o++) { + if (output == xf86_config->output[o]) { + break; + } + } if (bEnable) { ErrorF("enable montype: %d\n", radeon_output->MonType); if (radeon_output->MonType == MT_CRT) { if (radeon_output->DACType == DAC_PRIMARY) { + info->output_crt1 |= (1 << o); tmp = INREG(RADEON_CRTC_EXT_CNTL); tmp |= RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); } else if (radeon_output->DACType == DAC_TVDAC) { + info->output_crt2 |= (1 << o); if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -350,11 +359,13 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) } } else if (radeon_output->MonType == MT_DFP) { if (radeon_output->TMDSType == TMDS_INT) { + info->output_dfp1 |= (1 << o); tmp = INREG(RADEON_FP_GEN_CNTL); tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else if (radeon_output->TMDSType == TMDS_EXT) { + info->output_dfp2 |= (1 << o); tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~RADEON_FP2_BLANK_EN; tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -363,6 +374,7 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; } } else if (radeon_output->MonType == MT_LCD) { + info->output_lcd1 |= (1 << o); tmp = INREG(RADEON_LVDS_GEN_CNTL); tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); tmp &= ~(RADEON_LVDS_DISPLAY_DIS); @@ -372,6 +384,7 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { + info->output_tv1 |= (1 << o); tmp = INREG(RADEON_TV_MASTER_CNTL); tmp |= RADEON_TV_ON; OUTREG(RADEON_TV_MASTER_CNTL, tmp); @@ -382,70 +395,88 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) ErrorF("disable montype: %d\n", radeon_output->MonType); if (radeon_output->MonType == MT_CRT) { if (radeon_output->DACType == DAC_PRIMARY) { - tmp = INREG(RADEON_CRTC_EXT_CNTL); - tmp &= ~RADEON_CRTC_CRT_ON; - OUTREG(RADEON_CRTC_EXT_CNTL, tmp); - save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; - RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); + info->output_crt1 &= ~(1 << o); + if (!info->output_crt1) { + tmp = INREG(RADEON_CRTC_EXT_CNTL); + tmp &= ~RADEON_CRTC_CRT_ON; + OUTREG(RADEON_CRTC_EXT_CNTL, tmp); + save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; + RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); + } } else if (radeon_output->DACType == DAC_TVDAC) { - if (info->ChipFamily == CHIP_FAMILY_R200) { - tmp = INREG(RADEON_FP2_GEN_CNTL); - tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - OUTREG(RADEON_FP2_GEN_CNTL, tmp); - save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - } else { - tmp = INREG(RADEON_CRTC2_GEN_CNTL); - tmp &= ~RADEON_CRTC2_CRT2_ON; - OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); - save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; + info->output_crt2 &= ~(1 << o); + if (!info->output_crt2) { + if (info->ChipFamily == CHIP_FAMILY_R200) { + tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + OUTREG(RADEON_FP2_GEN_CNTL, tmp); + save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + } else { + tmp = INREG(RADEON_CRTC2_GEN_CNTL); + tmp &= ~RADEON_CRTC2_CRT2_ON; + OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); + save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; + tv_dac_change = 1; + } } - tv_dac_change = 1; } } else if (radeon_output->MonType == MT_DFP) { if (radeon_output->TMDSType == TMDS_INT) { - tmp = INREG(RADEON_FP_GEN_CNTL); - tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - OUTREG(RADEON_FP_GEN_CNTL, tmp); - save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + info->output_dfp1 &= ~(1 << o); + if (!info->output_dfp1) { + tmp = INREG(RADEON_FP_GEN_CNTL); + tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + OUTREG(RADEON_FP_GEN_CNTL, tmp); + save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + } } else if (radeon_output->TMDSType == TMDS_EXT) { - tmp = INREG(RADEON_FP2_GEN_CNTL); - tmp |= RADEON_FP2_BLANK_EN; - tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - OUTREG(RADEON_FP2_GEN_CNTL, tmp); - save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; + info->output_dfp2 &= ~(1 << o); + if (!info->output_dfp2) { + tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp |= RADEON_FP2_BLANK_EN; + tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + OUTREG(RADEON_FP2_GEN_CNTL, tmp); + save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; + } } } else if (radeon_output->MonType == MT_LCD) { - unsigned long 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); - } - tmp = INREG(RADEON_LVDS_GEN_CNTL); - tmp |= RADEON_LVDS_DISPLAY_DIS; - tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - OUTREG(RADEON_LVDS_GEN_CNTL, tmp); - save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); - if (info->IsMobility || info->IsIGP) { - OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + info->output_lcd1 &= ~(1 << o); + if (!info->output_lcd1) { + unsigned long 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); + } + tmp = INREG(RADEON_LVDS_GEN_CNTL); + tmp |= RADEON_LVDS_DISPLAY_DIS; + tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + OUTREG(RADEON_LVDS_GEN_CNTL, tmp); + save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; + save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + if (info->IsMobility || info->IsIGP) { + OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + } } } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { - tmp = INREG(RADEON_TV_MASTER_CNTL); - tmp &= ~RADEON_TV_ON; - OUTREG(RADEON_TV_MASTER_CNTL, tmp); - tv_dac_change = 2; - radeon_output->tv_on = FALSE; + info->output_tv1 &= ~(1 << o); + if (!info->output_tv1) { + tmp = INREG(RADEON_TV_MASTER_CNTL); + tmp &= ~RADEON_TV_ON; + OUTREG(RADEON_TV_MASTER_CNTL, tmp); + tv_dac_change = 2; + radeon_output->tv_on = FALSE; + } } } if (tv_dac_change) { if (bEnable) - info->tv_dac_enable_mask |= tv_dac_change; + info->tv_dac_enable_mask |= tv_dac_change; else - info->tv_dac_enable_mask &= ~tv_dac_change; + info->tv_dac_enable_mask &= ~tv_dac_change; if (bEnable && info->tv_dac_enable_mask) RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); diff --git a/src/radeon_output.c b/src/radeon_output.c index 9e73c08c..c60ece81 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -3207,6 +3207,14 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } } + /* clear the enable masks */ + info->output_crt1 = 0; + info->output_crt2 = 0; + info->output_dfp1 = 0; + info->output_dfp2 = 0; + info->output_lcd1 = 0; + info->output_tv1 = 0; + for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) { if (info->BiosConnector[i].valid) { RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1); |