| From | Greg Kroah-Hartman <> | Subject | [ 04/46] drm/mgag200: fix G200ER pll picking algorithm | Date | Sun, 19 Aug 2012 20:58:40 -0700 |
| |
From: Greg KH <gregkh@linuxfoundation.org>
3.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <airlied@gmail.com>
commit 9830605d4c070b16ec5c24a75503877cc7698409 upstream.
The original code was misported from the X driver,
a) an int went to unsigned int, breaking the downward counting testm code b) the port did the vco/computed clock bits completely wrong.
This fixes an infinite loop on modprobe on some Dell servers with the G200ER chipset variant.
Found in internal testing.
Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- drivers/gpu/drm/mgag200/mgag200_mode.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mg { unsigned int vcomax, vcomin, pllreffreq; unsigned int delta, tmpdelta; - unsigned int testr, testn, testm, testo; + int testr, testn, testm, testo; unsigned int p, m, n; - unsigned int computed; + unsigned int computed, vco; int tmp; + const unsigned int m_div_val[] = { 1, 2, 4, 8 }; m = n = p = 0; vcomax = 1488000; @@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mg if (delta == 0) break; for (testo = 5; testo < 33; testo++) { - computed = pllreffreq * (testn + 1) / + vco = pllreffreq * (testn + 1) / (testr + 1); - if (computed < vcomin) + if (vco < vcomin) continue; - if (computed > vcomax) + if (vco > vcomax) continue; + computed = vco / (m_div_val[testm] * (testo + 1)); if (computed > clock) tmpdelta = computed - clock; else
|