Skip to content

Commit 9830605

Browse files
committed
drm/mgag200: fix G200ER pll picking algorithm
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. Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
1 parent f7b83b9 commit 9830605

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

drivers/gpu/drm/mgag200/mgag200_mode.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
468468
{
469469
unsigned int vcomax, vcomin, pllreffreq;
470470
unsigned int delta, tmpdelta;
471-
unsigned int testr, testn, testm, testo;
471+
int testr, testn, testm, testo;
472472
unsigned int p, m, n;
473-
unsigned int computed;
473+
unsigned int computed, vco;
474474
int tmp;
475+
const unsigned int m_div_val[] = { 1, 2, 4, 8 };
475476

476477
m = n = p = 0;
477478
vcomax = 1488000;
@@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
490491
if (delta == 0)
491492
break;
492493
for (testo = 5; testo < 33; testo++) {
493-
computed = pllreffreq * (testn + 1) /
494+
vco = pllreffreq * (testn + 1) /
494495
(testr + 1);
495-
if (computed < vcomin)
496+
if (vco < vcomin)
496497
continue;
497-
if (computed > vcomax)
498+
if (vco > vcomax)
498499
continue;
500+
computed = vco / (m_div_val[testm] * (testo + 1));
499501
if (computed > clock)
500502
tmpdelta = computed - clock;
501503
else

0 commit comments

Comments
 (0)