diff options
-rw-r--r-- | src/atombios_crtc.c | 4 | ||||
-rw-r--r-- | src/radeon.h | 12 | ||||
-rw-r--r-- | src/radeon_bios.c | 2 | ||||
-rw-r--r-- | src/radeon_crtc.c | 73 | ||||
-rw-r--r-- | src/radeon_display.c | 285 | ||||
-rw-r--r-- | src/radeon_dri.c | 15 | ||||
-rw-r--r-- | src/radeon_driver.c | 6 | ||||
-rw-r--r-- | src/radeon_exa_render.c | 93 | ||||
-rw-r--r-- | src/radeon_output.c | 17 | ||||
-rw-r--r-- | src/radeon_reg.h | 1 |
10 files changed, 298 insertions, 210 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 6c7828b9..e7ad4a97 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -166,8 +166,8 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) if (IS_AVIVO_VARIANT) { CARD32 temp; - RADEONComputePLL(&info->pll, mode->Clock * 1000, &temp, &fb_div, &ref_div, &post_div); - sclock = temp / 10000; + RADEONComputePLL(&info->pll, mode->Clock, &temp, &fb_div, &ref_div, &post_div, 0); + sclock = temp; /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ if (radeon_crtc->crtc_id == 0) { diff --git a/src/radeon.h b/src/radeon.h index 6cc2b6f9..a5717a06 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -200,6 +200,10 @@ typedef struct { CARD16 rr4_offset; } RADEONBIOSInitTable; +#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) +#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) +#define RADEON_PLL_USE_REF_DIV (1 << 2) + typedef struct { CARD16 reference_freq; CARD16 reference_div; @@ -703,6 +707,14 @@ typedef struct { unsigned long FbFreeStart, FbFreeSize; unsigned char* BIOSCopy; + /* 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_bios.c b/src/radeon_bios.c index 97301194..46a58ca2 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -638,7 +638,7 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn) /* not available in the bios */ pll->pll_in_min = 40; - pll->pll_in_max = 100; + pll->pll_in_max = 500; pll->xclk = RADEON_BIOS16 (pll_info_block + 0x08); diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c index 611c9abe..d2271b05 100644 --- a/src/radeon_crtc.c +++ b/src/radeon_crtc.c @@ -620,25 +620,22 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, } -/* Compute n/d with rounding */ static int RADEONDiv(int n, int d) { return (n + (d / 2)) / d; } -static CARD32 RADEONDiv64(CARD64 n, CARD32 d) -{ - return (n + (d / 2)) / d; -} - -void +static void RADEONComputePLL(RADEONPLLPtr pll, unsigned long freq, CARD32 *chosen_dot_clock_freq, CARD32 *chosen_feedback_div, CARD32 *chosen_reference_div, - CARD32 *chosen_post_div) + CARD32 *chosen_post_div, + int flags) { + CARD32 min_ref_div = pll->min_ref_div; + CARD32 max_ref_div = pll->max_ref_div; CARD32 best_vco = pll->best_vco; CARD32 best_post_div = 1; CARD32 best_ref_div = 1; @@ -648,37 +645,45 @@ RADEONComputePLL(RADEONPLLPtr pll, CARD32 best_vco_diff = 1; CARD32 post_div; + freq = freq / 10; + ErrorF("freq: %lu\n", freq); + if (flags & RADEON_PLL_USE_REF_DIV) + min_ref_div = max_ref_div = pll->reference_div; + for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) { CARD32 ref_div; - CARD32 vco = (freq / 10000) * post_div; + CARD32 vco = freq * post_div; + + if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) + continue; if (vco < pll->pll_out_min || vco > pll->pll_out_max) continue; - for (ref_div = pll->min_ref_div; ref_div <= pll->max_ref_div; ++ref_div) { + for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) { CARD32 feedback_div, current_freq, error, vco_diff; CARD32 pll_in = pll->reference_freq / ref_div; if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max) continue; - feedback_div = RADEONDiv64((CARD64)freq * ref_div * post_div, - pll->reference_freq * 10000); + feedback_div = RADEONDiv(freq * ref_div * post_div, + pll->reference_freq); if (feedback_div < pll->min_feedback_div || feedback_div > pll->max_feedback_div) continue; - current_freq = RADEONDiv64((CARD64)pll->reference_freq * 10000 * feedback_div, - ref_div * post_div); + current_freq = RADEONDiv(pll->reference_freq * feedback_div, + ref_div * post_div); error = abs(current_freq - freq); vco_diff = abs(vco - best_vco); if ((best_vco == 0 && error < best_error) || (best_vco != 0 && - (error < best_error - 100 || + (error < best_error - 1000 || (abs(error - best_error) < 100 && vco_diff < best_vco_diff )))) { best_post_div = post_div; best_ref_div = ref_div; @@ -705,7 +710,8 @@ RADEONComputePLL(RADEONPLLPtr pll, /* Define PLL registers for requested video mode */ static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, - RADEONPLLPtr pll, DisplayModePtr mode) + RADEONPLLPtr pll, DisplayModePtr mode, + int flags) { RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 feedback_div = 0; @@ -733,16 +739,15 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, { 0, 0 } }; - RADEONComputePLL(pll, mode->Clock * 1000, &freq, &feedback_div, &reference_div, &post_divider); -#if 0 - if (info->UseBiosDividers) { + if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) { save->ppll_ref_div = info->RefDivider; save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16); save->htotal_cntl = 0; return; } -#endif + + RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags); for (post_div = &post_divs[0]; post_div->divider; ++post_div) { if (post_div->divider == post_divider) @@ -754,7 +759,7 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, post_div = &post_divs[0]; } - save->dot_clock_freq = freq / 10000; + save->dot_clock_freq = freq; save->feedback_div = feedback_div; save->reference_div = reference_div; save->post_div = post_divider; @@ -786,7 +791,8 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, /* Define PLL2 registers for requested video mode */ static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, - RADEONPLLPtr pll, DisplayModePtr mode) + RADEONPLLPtr pll, DisplayModePtr mode, + int flags) { RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 feedback_div = 0; @@ -813,7 +819,14 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, { 0, 0 } }; - RADEONComputePLL(pll, mode->Clock * 1000, &freq, &feedback_div, &reference_div, &post_divider); + if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) { + save->p2pll_ref_div = info->RefDivider; + save->p2pll_div_0 = info->FeedbackDivider | (info->PostDivider << 16); + save->htotal_cntl2 = 0; + return; + } + + RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags); for (post_div = &post_divs[0]; post_div->divider; ++post_div) { if (post_div->divider == post_divider) @@ -825,7 +838,7 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, post_div = &post_divs[0]; } - save->dot_clock_freq_2 = freq / 10000; + save->dot_clock_freq_2 = freq; save->feedback_div_2 = feedback_div; save->reference_div_2 = reference_div; save->post_div_2 = post_divider; @@ -879,8 +892,8 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, RADEONInfoPtr info = RADEONPTR(pScrn); Bool tilingOld = info->tilingEnabled; int i = 0; - double dot_clock = 0; - Bool no_odd_post_div = FALSE; + double dot_clock = 0; + int pll_flags = 0; Bool update_tv_routing = FALSE; @@ -905,7 +918,9 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (output->crtc == crtc) { if (radeon_output->MonType != MT_CRT) - no_odd_post_div = TRUE; + pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; + if (radeon_output->MonType == MT_LCD) + pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV); } } @@ -927,7 +942,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dot_clock = adjusted_mode->Clock / 1000.0; if (dot_clock) { ErrorF("init pll1\n"); - RADEONInitPLLRegisters(pScrn, info->ModeReg, &info->pll, adjusted_mode); + RADEONInitPLLRegisters(pScrn, &info->ModeReg, &info->pll, adjusted_mode, pll_flags); } else { info->ModeReg->ppll_ref_div = info->SavedReg->ppll_ref_div; info->ModeReg->ppll_div_3 = info->SavedReg->ppll_div_3; @@ -941,7 +956,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dot_clock = adjusted_mode->Clock / 1000.0; if (dot_clock) { ErrorF("init pll2\n"); - RADEONInitPLL2Registers(pScrn, info->ModeReg, &info->pll, adjusted_mode); + RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, adjusted_mode, pll_flags); } break; } diff --git a/src/radeon_display.c b/src/radeon_display.c index 07d633fe..1cd8b052 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; diff --git a/src/radeon_dri.c b/src/radeon_dri.c index ac8d03c9..f1003d72 100644 --- a/src/radeon_dri.c +++ b/src/radeon_dri.c @@ -726,18 +726,9 @@ static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen) pcie-agp rialto bridge chip - use the one from bridge which must match */ CARD32 agp_status = (INREG(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode; Bool is_v3 = (agp_status & RADEON_AGPv3_MODE); - unsigned int defaultMode; - MessageType from; - - if (is_v3) { - defaultMode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; - } else { - if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4; - else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2; - else defaultMode = 1; - } - - from = X_DEFAULT; + unsigned int defaultMode = is_v3 ? + ((agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4) : 1; + MessageType from = X_DEFAULT; if (xf86GetOptValInteger(info->Options, OPTION_AGP_MODE, &info->agpMode)) { if ((info->agpMode < (is_v3 ? 4 : 1)) || diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 62e7cd0b..a9756faf 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -1202,7 +1202,7 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn) pll->pll_out_max = 50000; } else { pll->pll_in_min = 40; - pll->pll_in_max = 100; + pll->pll_in_max = 500; pll->pll_out_min = 12500; pll->pll_out_max = 35000; } @@ -4485,6 +4485,10 @@ void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) if (info->IsMobility) { OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl); + + if (info->ChipFamily == CHIP_FAMILY_RV410) { + OUTREG(RADEON_CLOCK_CNTL_INDEX, 0); + } } } diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 92515695..eae69c49 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -736,6 +736,21 @@ do { \ #endif /* !ACCEL_CP */ +#ifdef ONLY_ONCE +static inline void transformPoint(PictTransform *transform, xPointFixed *point) +{ + PictVector v; + v.vector[0] = point->x; + v.vector[1] = point->y; + v.vector[2] = xFixed1; + PictureTransformPoint(transform, &v); + point->x = v.vector[0]; + point->y = v.vector[1]; +} +#endif + +#define xFixedToFloat(f) (((float) (f)) / 65536) + static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, @@ -744,7 +759,8 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, { RINFO_FROM_SCREEN(pDst->drawable.pScreen); int srcXend, srcYend, maskXend, maskYend; - PictVector v; + xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight; + xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight; ACCEL_PREAMBLE(); ENTER_DRAW(0); @@ -756,33 +772,36 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, srcYend = srcY + h; maskXend = maskX + w; maskYend = maskY + h; + + srcTopLeft.x = IntToxFixed(srcX); + srcTopLeft.y = IntToxFixed(srcY); + srcTopRight.x = IntToxFixed(srcX + w); + srcTopRight.y = IntToxFixed(srcY); + srcBottomLeft.x = IntToxFixed(srcX); + srcBottomLeft.y = IntToxFixed(srcY + h); + srcBottomRight.x = IntToxFixed(srcX + w); + srcBottomRight.y = IntToxFixed(srcY + h); + + maskTopLeft.x = IntToxFixed(maskX); + maskTopLeft.y = IntToxFixed(maskY); + maskTopRight.x = IntToxFixed(maskX + w); + maskTopRight.y = IntToxFixed(maskY); + maskBottomLeft.x = IntToxFixed(maskX); + maskBottomLeft.y = IntToxFixed(maskY + h); + maskBottomRight.x = IntToxFixed(maskX + w); + maskBottomRight.y = IntToxFixed(maskY + h); + if (is_transform[0]) { - v.vector[0] = IntToxFixed(srcX); - v.vector[1] = IntToxFixed(srcY); - v.vector[2] = xFixed1; - PictureTransformPoint(transform[0], &v); - srcX = xFixedToInt(v.vector[0]); - srcY = xFixedToInt(v.vector[1]); - v.vector[0] = IntToxFixed(srcXend); - v.vector[1] = IntToxFixed(srcYend); - v.vector[2] = xFixed1; - PictureTransformPoint(transform[0], &v); - srcXend = xFixedToInt(v.vector[0]); - srcYend = xFixedToInt(v.vector[1]); + transformPoint(transform[0], &srcTopLeft); + transformPoint(transform[0], &srcTopRight); + transformPoint(transform[0], &srcBottomLeft); + transformPoint(transform[0], &srcBottomRight); } if (is_transform[1]) { - v.vector[0] = IntToxFixed(maskX); - v.vector[1] = IntToxFixed(maskY); - v.vector[2] = xFixed1; - PictureTransformPoint(transform[1], &v); - maskX = xFixedToInt(v.vector[0]); - maskY = xFixedToInt(v.vector[1]); - v.vector[0] = IntToxFixed(maskXend); - v.vector[1] = IntToxFixed(maskYend); - v.vector[2] = xFixed1; - PictureTransformPoint(transform[1], &v); - maskXend = xFixedToInt(v.vector[0]); - maskYend = xFixedToInt(v.vector[1]); + transformPoint(transform[1], &maskTopLeft); + transformPoint(transform[1], &maskTopRight); + transformPoint(transform[1], &maskBottomLeft); + transformPoint(transform[1], &maskBottomRight); } #ifdef ACCEL_CP @@ -828,18 +847,18 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend); VTX_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY); } else { - VTX_OUT((float)dstX, (float)dstY, - (float)srcX / info->texW[0], (float)srcY / info->texH[0], - (float)maskX / info->texW[1], (float)maskY / info->texH[1]); - VTX_OUT((float)dstX, (float)(dstY + h), - (float)srcX / info->texW[0], (float)srcYend / info->texH[0], - (float)maskX / info->texW[1], (float)maskYend / info->texH[1]); - VTX_OUT((float)(dstX + w), (float)(dstY + h), - (float)srcXend / info->texW[0], (float)srcYend / info->texH[0], - (float)maskXend / info->texW[1], (float)maskYend / info->texH[1]); - VTX_OUT((float)(dstX + w), (float)dstY, - (float)srcXend / info->texW[0], (float)srcY / info->texH[0], - (float)maskXend / info->texW[1], (float)maskY / info->texH[1]); + VTX_OUT((float)dstX, (float)dstY, + xFixedToFloat(srcTopLeft.x) / info->texW[0], xFixedToFloat(srcTopLeft.y) / info->texH[0], + xFixedToFloat(maskTopLeft.x) / info->texW[1], xFixedToFloat(maskTopLeft.y) / info->texH[1]); + VTX_OUT((float)dstX, (float)(dstY + h), + xFixedToFloat(srcBottomLeft.x) / info->texW[0], xFixedToFloat(srcBottomLeft.y) / info->texH[0], + xFixedToFloat(maskBottomLeft.x) / info->texW[1], xFixedToFloat(maskBottomLeft.y) / info->texH[1]); + VTX_OUT((float)(dstX + w), (float)(dstY + h), + xFixedToFloat(srcBottomRight.x) / info->texW[0], xFixedToFloat(srcBottomRight.y) / info->texH[0], + xFixedToFloat(maskBottomRight.x) / info->texW[1], xFixedToFloat(maskBottomRight.y) / info->texH[1]); + VTX_OUT((float)(dstX + w), (float)dstY, + xFixedToFloat(srcTopRight.x) / info->texW[0], xFixedToFloat(srcTopRight.y) / info->texH[0], + xFixedToFloat(maskTopRight.x) / info->texW[1], xFixedToFloat(maskTopRight.y) / info->texH[1]); } #ifdef ACCEL_CP diff --git a/src/radeon_output.c b/src/radeon_output.c index 02c96aef..519626fb 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -741,6 +741,8 @@ void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output) } } +#ifndef __powerpc__ + static RADEONMonitorType RADEONDetectLidStatus(ScrnInfoPtr pScrn) { @@ -780,6 +782,8 @@ RADEONDetectLidStatus(ScrnInfoPtr pScrn) return MonType; } +#endif /* __powerpc__ */ + static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output) { RADEONOutputPrivatePtr radeon_output = output->driver_private; @@ -1047,7 +1051,10 @@ static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save, save->lvds_gen_cntl = info->SavedReg->lvds_gen_cntl; save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); + save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | + RADEON_LVDS_BLON | + RADEON_LVDS_EN | + RADEON_LVDS_RST_FM); if (IS_R300_VARIANT) save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK); @@ -3384,6 +3391,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); diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 56eb7e91..dce29e29 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -916,6 +916,7 @@ # define RADEON_LVDS_DISPLAY_DIS (1 << 1) # define RADEON_LVDS_PANEL_TYPE (1 << 2) # define RADEON_LVDS_PANEL_FORMAT (1 << 3) +# define RADEON_LVDS_RST_FM (1 << 6) # define RADEON_LVDS_EN (1 << 7) # define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8 # define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8) |