Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9830605d authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@redhat.com>
parent f7b83b90
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
{
	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 mga_device *mdev, long clock)
				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