diff options
author | Christian König <christian.koenig@amd.com> | 2014-04-16 11:54:21 +0200 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-04-17 14:14:18 +0200 |
commit | f8a2645ecede4eaf90b3d785f2805c8ecb76d43e (patch) | |
tree | 7268ea388aa053239e8876e9ae08c71871faf432 /drivers | |
parent | 74073c9dd29905645feb6dee03c144657a9844cd (diff) | |
download | linux-f8a2645ecede4eaf90b3d785f2805c8ecb76d43e.tar.bz2 |
drm/radeon: improve PLL params if we don't match exactly v2
Otherwise we might be quite off on older chipsets.
v2: keep ref_div minimum
Signed-off-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 2f42912031ac..063d4255137f 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -865,7 +865,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, unsigned post_div_min, post_div_max, post_div; unsigned ref_div_min, ref_div_max, ref_div; unsigned post_div_best, diff_best; - unsigned nom, den, tmp; + unsigned nom, den; /* determine allowed feedback divider range */ fb_div_min = pll->min_feedback_div; @@ -941,22 +941,23 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ref_div_max = min(210 / post_div, ref_div_max); /* get matching reference and feedback divider */ - ref_div = max(den / post_div, 1u); - fb_div = nom; + ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u); + fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den); /* we're almost done, but reference and feedback divider might be to large now */ - tmp = ref_div; + nom = fb_div; + den = ref_div; if (fb_div > fb_div_max) { - ref_div = ref_div * fb_div_max / fb_div; + ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom); fb_div = fb_div_max; } if (ref_div > ref_div_max) { ref_div = ref_div_max; - fb_div = nom * ref_div_max / tmp; + fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den); } /* reduce the numbers to a simpler ratio once more */ |