aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-01 00:39:37 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-11-17 23:38:34 -0500
commit2a56a0b913a8d7314c2c10fdd57d667b599232b4 (patch)
treecbbb46a87d07059aaf730d1b7d30f3f335901c04 /drivers/gpu
parent699ddfd98061b725c52fd34ff1c4346e5b4824d4 (diff)
drm/nva3: fix overflow in fixed point math used for pll calculation
And a slight tweak which gets us closer to VBIOS-calculated numbers. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_calc.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c
index 2cdc2bfe7179..de81151648f8 100644
--- a/drivers/gpu/drm/nouveau/nv50_calc.c
+++ b/drivers/gpu/drm/nouveau/nv50_calc.c
@@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
51 int *N, int *fN, int *M, int *P) 51 int *N, int *fN, int *M, int *P)
52{ 52{
53 fixed20_12 fb_div, a, b; 53 fixed20_12 fb_div, a, b;
54 u32 refclk = pll->refclk / 10;
55 u32 max_vco_freq = pll->vco1.maxfreq / 10;
56 u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
57 clk /= 10;
54 58
55 *P = pll->vco1.maxfreq / clk; 59 *P = max_vco_freq / clk;
56 if (*P > pll->max_p) 60 if (*P > pll->max_p)
57 *P = pll->max_p; 61 *P = pll->max_p;
58 if (*P < pll->min_p) 62 if (*P < pll->min_p)
59 *P = pll->min_p; 63 *P = pll->min_p;
60 64
61 /* *M = ceil(refclk / pll->vco.max_inputfreq); */ 65 /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
62 a.full = dfixed_const(pll->refclk); 66 a.full = dfixed_const(refclk + max_vco_inputfreq);
63 b.full = dfixed_const(pll->vco1.max_inputfreq); 67 b.full = dfixed_const(max_vco_inputfreq);
64 a.full = dfixed_div(a, b); 68 a.full = dfixed_div(a, b);
65 a.full = dfixed_ceil(a); 69 a.full = dfixed_floor(a);
66 *M = dfixed_trunc(a); 70 *M = dfixed_trunc(a);
67 71
68 /* fb_div = (vco * *M) / refclk; */ 72 /* fb_div = (vco * *M) / refclk; */
69 fb_div.full = dfixed_const(clk * *P); 73 fb_div.full = dfixed_const(clk * *P);
70 fb_div.full = dfixed_mul(fb_div, a); 74 fb_div.full = dfixed_mul(fb_div, a);
71 a.full = dfixed_const(pll->refclk); 75 a.full = dfixed_const(refclk);
72 fb_div.full = dfixed_div(fb_div, a); 76 fb_div.full = dfixed_div(fb_div, a);
73 77
74 /* *N = floor(fb_div); */ 78 /* *N = floor(fb_div); */