From 9a08f099ae01de8e6e6511dbda556b1584d0fd0e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 2 Dec 2009 19:03:52 -0500 Subject: [PATCH] drm/radeon/kms: tighten the pll range when selecting dividers We use the pll in/out min/max values in the bios to limit our pll divider selection. In most cases the values in the bios for pll_out_min are higher than the default value we were using (64800) which gives us a more limited range of dividers. However, using the bios pll_out_min limit caused a problem on at least one 2560x1600 monitor. So, use the bios pll_out_min for everything except modes with clocks over 200 Mhz. This should provide the best of both worlds. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 6 ++++++ drivers/gpu/drm/radeon/radeon_atombios.c | 10 ---------- drivers/gpu/drm/radeon/radeon_display.c | 13 +++++++++++-- drivers/gpu/drm/radeon/radeon_mode.h | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 7a8cd93..c128e13 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -441,6 +441,12 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; else pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; + + /* some duallink monitors seem to prefer dividers calculated with a wider + * pll range + */ + if (mode->clock > 200000) + pll_flags |= RADEON_PLL_USE_DEFAULT_OUT_MIN; } else { pll_flags |= RADEON_PLL_LEGACY; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 76825ad..a45b251 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -851,16 +851,6 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) p1pll->pll_out_min = 64800; else p1pll->pll_out_min = 20000; - } else if (p1pll->pll_out_min > 64800) { - /* Limiting the pll output range is a good thing generally as - * it limits the number of possible pll combinations for a given - * frequency presumably to the ones that work best on each card. - * However, certain duallink DVI monitors seem to like - * pll combinations that would be limited by this at least on - * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per - * family. - */ - p1pll->pll_out_min = 64800; } p1pll->pll_in_min = diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d4f4fb1..89f99c9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -409,6 +409,8 @@ void radeon_compute_pll(struct radeon_pll *pll, { uint32_t min_ref_div = pll->min_ref_div; uint32_t max_ref_div = pll->max_ref_div; + uint32_t pll_out_min = pll->pll_out_min; + uint32_t pll_out_max = pll->pll_out_max; uint32_t min_fractional_feed_div = 0; uint32_t max_fractional_feed_div = 0; uint32_t best_vco = pll->best_vco; @@ -444,6 +446,13 @@ void radeon_compute_pll(struct radeon_pll *pll, max_fractional_feed_div = pll->max_frac_feedback_div; } + if (flags & RADEON_PLL_USE_DEFAULT_OUT_MIN) { + if (flags & RADEON_PLL_LEGACY) + pll_out_min = 20000; + else + pll_out_min = 64800; + } + for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) { uint32_t ref_div; @@ -484,10 +493,10 @@ void radeon_compute_pll(struct radeon_pll *pll, tmp = (uint64_t)pll->reference_freq * feedback_div; vco = radeon_div(tmp, ref_div); - if (vco < pll->pll_out_min) { + if (vco < pll_out_min) { min_feed_div = feedback_div + 1; continue; - } else if (vco > pll->pll_out_max) { + } else if (vco > pll_out_max) { max_feed_div = feedback_div; continue; } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 174e4a4..24c2016 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -150,6 +150,7 @@ struct radeon_tmds_pll { #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) +#define RADEON_PLL_USE_DEFAULT_OUT_MIN (1 << 12) struct radeon_pll { uint16_t reference_freq; -- 1.5.6.3