From f8a2645ecede4eaf90b3d785f2805c8ecb76d43e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
Date: Wed, 16 Apr 2014 11:54:21 +0200
Subject: [PATCH] drm/radeon: improve PLL params if we don't match exactly v2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Otherwise we might be quite off on older chipsets.

v2: keep ref_div minimum

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/radeon_display.c | 13 +++++++------
 1 file 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 */
-- 
2.30.9