diff options
Diffstat (limited to 'src/radeon_display.c')
-rw-r--r-- | src/radeon_display.c | 285 |
1 files changed, 158 insertions, 127 deletions
diff --git a/src/radeon_display.c b/src/radeon_display.c index 07d633f..1cd8b05 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -163,7 +163,7 @@ void RADEONGetTVDacAdjInfo(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; - + /* Todo: get this setting from BIOS */ radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily]; if (info->IsMobility) { /* some mobility chips may different */ @@ -202,7 +202,7 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) } else { CARD32 tv_dac_cntl; CARD32 fp2_gen_cntl; - + switch(info->ChipFamily) { case CHIP_FAMILY_R420: @@ -259,19 +259,19 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) { /* primary DAC */ tmp = INREG(RADEON_CRTC_EXT_CNTL); - tmp &= ~RADEON_CRTC_CRT_ON; + tmp &= ~RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); RADEONDacPowerSet(pScrn, FALSE, TRUE); /* Secondary DAC */ 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); + tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + OUTREG(RADEON_FP2_GEN_CNTL, tmp); } else { - tmp = INREG(RADEON_CRTC2_GEN_CNTL); - tmp &= ~RADEON_CRTC2_CRT2_ON; - OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); + tmp = INREG(RADEON_CRTC2_GEN_CNTL); + tmp &= ~RADEON_CRTC2_CRT2_ON; + OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); } RADEONDacPowerSet(pScrn, FALSE, FALSE); @@ -304,7 +304,7 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) { } tmp = INREG(RADEON_LVDS_GEN_CNTL); tmp |= RADEON_LVDS_DISPLAY_DIS; - tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); + tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); OUTREG(RADEON_LVDS_GEN_CNTL, tmp); if (info->IsMobility || info->IsIGP) { OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); @@ -322,130 +322,161 @@ 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) { - 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; - } - 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); - } else if (radeon_output->TMDSType == TMDS_EXT) { - tmp = INREG(RADEON_FP2_GEN_CNTL); + 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); + 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; + } + } 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); - OUTREG(RADEON_FP2_GEN_CNTL, tmp); - save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_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) { - tmp = INREG(RADEON_LVDS_GEN_CNTL); - tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); - tmp &= ~(RADEON_LVDS_DISPLAY_DIS); + } + } 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); usleep (radeon_output->PanelPwrDly * 1000); - OUTREG(RADEON_LVDS_GEN_CNTL, tmp); - save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); - save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); - } else if (radeon_output->MonType == MT_STV || + OUTREG(RADEON_LVDS_GEN_CNTL, tmp); + save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN); + 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); - tv_dac_change = 2; + tv_dac_change = 2; radeon_output->tv_on = TRUE; } } else { 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)); - } 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; - } - 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); - } 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; - } - } 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); + if (radeon_output->MonType == MT_CRT) { + if (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) { + info->output_crt2 &= ~(1 << o); + tv_dac_change = 1; + 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; + } + } } - tmp = INREG(RADEON_LVDS_GEN_CNTL); - tmp |= RADEON_LVDS_DISPLAY_DIS; - tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); - OUTREG(RADEON_LVDS_GEN_CNTL, tmp); - save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); - if (info->IsMobility || info->IsIGP) { - OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl); + } else if (radeon_output->MonType == MT_DFP) { + if (radeon_output->TMDSType == TMDS_INT) { + 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) { + 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) { + 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) { + info->output_tv1 &= ~(1 << o); + tv_dac_change = 2; + if (!info->output_tv1) { + tmp = INREG(RADEON_TV_MASTER_CNTL); + tmp &= ~RADEON_TV_ON; + OUTREG(RADEON_TV_MASTER_CNTL, tmp); + radeon_output->tv_on = FALSE; } - } 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; } } 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)); @@ -487,13 +518,13 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b int stop_req, max_stop_req; float read_return_rate, time_disp1_drop_priority; - /* - * Set display0/1 priority up on r3/4xx in the memory controller for - * high res modes if the user specifies HIGH for displaypriority + /* + * Set display0/1 priority up on r3/4xx in the memory controller for + * high res modes if the user specifies HIGH for displaypriority * option. */ if ((info->DispPriority == 2) && IS_R300_VARIANT) { - CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER); + CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER); if (pRADEONEnt->pCrtc[1]->enabled) { mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */ } else { @@ -522,14 +553,14 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b peak_disp_bw += (pix_clk2 * pixel_bytes2); if (peak_disp_bw >= mem_bw * min_mem_eff) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You may not have enough display bandwidth for current mode\n" "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); - } + } /* CRTC1 Set GRPH_BUFFER_CNTL register using h/w defined optimal values. - GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] + GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] */ stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16; @@ -540,7 +571,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b max_stop_req = 0x7c; if (stop_req > max_stop_req) stop_req = max_stop_req; - + /* Get values from the EXT_MEM_CNTL register...converting its contents. */ temp = INREG(RADEON_MEM_TIMING_CNTL); if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */ @@ -552,8 +583,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b mem_trp = MemTrpMemTimingCntl[ (temp & 0x700) >> 8]; mem_tras = MemTrasMemTimingCntl[(temp & 0xf000) >> 12]; } - - /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ + + /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ temp = INREG(RADEON_MEM_SDRAM_MODE_REG); data = (temp & (7<<20)) >> 20; if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */ @@ -625,7 +656,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b } mc_latency_sclk = sclk_delay / sclk_eff; - + if (info->IsDDR) { if (info->RamWidth == 32) { k1 = 40; @@ -667,7 +698,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b /* Find the critical point of the display buffer. */ - critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5); + critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5); /* ???? */ /* @@ -682,7 +713,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b The critical point should never be above max_stop_req-4. Setting GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time. */ - if (max_stop_req - critical_point < 4) critical_point = 0; + if (max_stop_req - critical_point < 4) critical_point = 0; if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) { /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ @@ -733,7 +764,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b RADEON_GRPH_CRITICAL_AT_SOF | RADEON_GRPH_STOP_CNTL); - if ((info->ChipFamily == CHIP_FAMILY_RS100) || + if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200)) critical_point2 = 0; else { @@ -813,7 +844,7 @@ void RADEONBlank(ScrnInfoPtr pScrn) for (c = 0; c < xf86_config->num_crtc; c++) { crtc = xf86_config->crtc[c]; - for (o = 0; o < xf86_config->num_output; o++) { + for (o = 0; o < xf86_config->num_output; o++) { output = xf86_config->output[o]; if (output->crtc != crtc) continue; @@ -836,7 +867,7 @@ void RADEONUnblank(ScrnInfoPtr pScrn) if(!crtc->enabled) continue; crtc->funcs->dpms(crtc, DPMSModeOn); - for (o = 0; o < xf86_config->num_output; o++) { + for (o = 0; o < xf86_config->num_output; o++) { output = xf86_config->output[o]; if (output->crtc != crtc) continue; |