diff options
Diffstat (limited to 'src/radeon_display.c')
-rw-r--r-- | src/radeon_display.c | 129 |
1 files changed, 80 insertions, 49 deletions
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)); |