diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-04-13 11:08:59 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2010-04-13 11:08:59 -0400 |
commit | 22a46dddd375b2b9399e12fdf168fa5292ff17a4 (patch) | |
tree | 8227b869aad03913f3add76fde3d8ad69c64174b /src | |
parent | c1b817c45477c21234abaaebe78feb7ea4fd92b1 (diff) |
radeon: add support for pll algo selection
tv-out on atom systems is very particular about it's
dividers. force it to use the old algo.
Should fix fdo bug 27593.
Diffstat (limited to 'src')
-rw-r--r-- | src/atombios_crtc.c | 22 | ||||
-rw-r--r-- | src/legacy_crtc.c | 28 | ||||
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_crtc.c | 37 | ||||
-rw-r--r-- | src/radeon_probe.h | 6 |
5 files changed, 65 insertions, 30 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 1d86643b..6f083b48 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -458,6 +458,19 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) unsigned char *space; memset(&spc_param, 0, sizeof(spc_param)); + + if (IS_AVIVO_VARIANT) { + if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE)) + radeon_crtc->pll_algo = RADEON_PLL_NEW; + else + radeon_crtc->pll_algo = RADEON_PLL_OLD; + } else { + if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE)) + radeon_crtc->pll_algo = RADEON_PLL_NEW; + else + radeon_crtc->pll_algo = RADEON_PLL_OLD; + } + if (IS_AVIVO_VARIANT) { if ((info->ChipFamily == CHIP_FAMILY_RS600) || (info->ChipFamily == CHIP_FAMILY_RS690) || @@ -471,6 +484,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc == crtc) { + radeon_output = output->driver_private; radeon_encoder = radeon_get_encoder(output); /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ /* AdjustDisplayPll handles this on DCE3.x */ @@ -478,6 +492,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) && !IS_DCE3_VARIANT) sclock *= 2; + if (radeon_output->active_device & + (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) { + pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; + radeon_crtc->pll_algo = RADEON_PLL_OLD; + } } } @@ -614,7 +633,8 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) } } - RADEONComputePLL(pScrn, &info->pll, sclock, &temp, &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags); + RADEONComputePLL(crtc, &info->pll, sclock, &temp, + &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags); sclock = temp; /* 10 khz */ xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c index e4c1f043..0beb54d4 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -1184,10 +1184,12 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, /* Define PLL registers for requested video mode */ static void -RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, +RADEONInitPLLRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, RADEONPLLPtr pll, DisplayModePtr mode, int flags) { + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t feedback_div = 0; uint32_t frac_fb_div = 0; @@ -1223,7 +1225,13 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, return; } - RADEONComputePLL(pScrn, pll, mode->Clock, &freq, &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags); + if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE)) + radeon_crtc->pll_algo = RADEON_PLL_NEW; + else + radeon_crtc->pll_algo = RADEON_PLL_OLD; + + RADEONComputePLL(crtc, pll, mode->Clock, &freq, + &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags); for (post_div = &post_divs[0]; post_div->divider; ++post_div) { if (post_div->divider == post_divider) @@ -1266,10 +1274,12 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, /* Define PLL2 registers for requested video mode */ static void -RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, +RADEONInitPLL2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, RADEONPLLPtr pll, DisplayModePtr mode, int flags) { + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t feedback_div = 0; uint32_t frac_fb_div = 0; @@ -1303,7 +1313,13 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, return; } - RADEONComputePLL(pScrn, pll, mode->Clock, &freq, &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags); + if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE)) + radeon_crtc->pll_algo = RADEON_PLL_NEW; + else + radeon_crtc->pll_algo = RADEON_PLL_OLD; + + RADEONComputePLL(crtc, pll, mode->Clock, &freq, + &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags); for (post_div = &post_divs[0]; post_div->divider; ++post_div) { if (post_div->divider == post_divider) @@ -1795,7 +1811,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, pll_flags); + RADEONInitPLLRegisters(crtc, 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; @@ -1809,7 +1825,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, pll_flags); + RADEONInitPLL2Registers(crtc, info->ModeReg, &info->pll, adjusted_mode, pll_flags); } break; } diff --git a/src/radeon.h b/src/radeon.h index 88f1516b..388422a6 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -1176,7 +1176,7 @@ extern void radeon_crtc_load_lut(xf86CrtcPtr crtc); extern void radeon_crtc_modeset_ioctl(xf86CrtcPtr crtc, Bool post); extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask); extern void RADEONBlank(ScrnInfoPtr pScrn); -extern void RADEONComputePLL(ScrnInfoPtr pScrn, +extern void RADEONComputePLL(xf86CrtcPtr crtc, RADEONPLLPtr pll, unsigned long freq, uint32_t *chosen_dot_clock_freq, uint32_t *chosen_feedback_div, diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c index 0b071b8b..a4a3302b 100644 --- a/src/radeon_crtc.c +++ b/src/radeon_crtc.c @@ -447,7 +447,7 @@ done: } void -RADEONComputePLL(ScrnInfoPtr pScrn, +RADEONComputePLL(xf86CrtcPtr crtc, RADEONPLLPtr pll, unsigned long freq, uint32_t *chosen_dot_clock_freq, @@ -457,28 +457,21 @@ RADEONComputePLL(ScrnInfoPtr pScrn, uint32_t *chosen_post_div, int flags) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; - if (IS_AVIVO_VARIANT) { - if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE)) { - /* disable frac fb dividers */ - flags &= ~RADEON_PLL_USE_FRAC_FB_DIV; - RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq, - chosen_feedback_div, chosen_frac_feedback_div, - chosen_reference_div, chosen_post_div, flags); - } else - RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq, - chosen_feedback_div, chosen_frac_feedback_div, - chosen_reference_div, chosen_post_div, flags); - } else { - if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE)) - RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq, - chosen_feedback_div, chosen_frac_feedback_div, - chosen_reference_div, chosen_post_div, flags); - else - RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq, - chosen_feedback_div, chosen_frac_feedback_div, - chosen_reference_div, chosen_post_div, flags); + switch (radeon_crtc->pll_algo) { + case RADEON_PLL_OLD: + RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq, + chosen_feedback_div, chosen_frac_feedback_div, + chosen_reference_div, chosen_post_div, flags); + break; + case RADEON_PLL_NEW: + /* disable frac fb dividers */ + flags &= ~RADEON_PLL_USE_FRAC_FB_DIV; + RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq, + chosen_feedback_div, chosen_frac_feedback_div, + chosen_reference_div, chosen_post_div, flags); + break; } } diff --git a/src/radeon_probe.h b/src/radeon_probe.h index dc02bdff..cab077fe 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -147,6 +147,11 @@ typedef struct Bool hw_capable; } RADEONI2CBusRec, *RADEONI2CBusPtr; +enum radeon_pll_algo { + RADEON_PLL_OLD, + RADEON_PLL_NEW +}; + typedef struct _RADEONCrtcPrivateRec { void *crtc_rotate_mem; void *cursor_mem; @@ -164,6 +169,7 @@ typedef struct _RADEONCrtcPrivateRec { float vsc; float hsc; int pll_id; + enum radeon_pll_algo pll_algo; } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr; typedef struct _radeon_encoder { |