Commit 2dd04094 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/mgag200: Store values (not bits) in struct mgag200_pll_values



The fields in struct mgag200_pll_values currently hold the bits of
each register. Store the PLL values instead and let the PLL-update
code figure out the bits for each register.

Until now, the compute function either stored plain values or register
bits in struct mgag200_pll_values. The rsp update function used the
values as-is. This made it very hard to correctly interpret the stored
values (e.g., for logging or debugging). With the cleanup, the stored
values now have a clear meaning.

v2:
	* add a bit more context in the commit message (Sam)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210714142240.21979-7-tzimmermann@suse.de
parent d9d99223
Loading
Loading
Loading
Loading
+91 −62
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
	const int in_div_max = 6;
	const int feed_div_min = 7;
	const int feed_div_max = 127;
	u8 testm, testn;
	u8 testp, testm, testn;
	u8 n = 0, m = 0, p, s;
	long f_vco;
	long computed;
@@ -141,10 +141,11 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
		clock = p_clk_min >> 3;

	f_vco = clock;
	for (p = 0;
	     p <= post_div_max && f_vco < p_clk_min;
	     p = (p << 1) + 1, f_vco <<= 1)
	for (testp = 0;
	     testp <= post_div_max && f_vco < p_clk_min;
	     testp = (testp << 1) + 1, f_vco <<= 1)
		;
	p = testp + 1;

	delta = clock;

@@ -157,12 +158,12 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
				tmp_delta = computed - f_vco;
			if (tmp_delta < delta) {
				delta = tmp_delta;
				m = testm;
				n = testn;
				m = testm + 1;
				n = testn + 1;
			}
		}
	}
	f_vco = ref_clk * (n + 1) / (m + 1);
	f_vco = ref_clk * n / m;
	if (f_vco < 100000)
		s = 0;
	else if (f_vco < 140000)
@@ -186,11 +187,17 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
static void mgag200_set_pixpll_g200(struct mga_device *mdev,
				    const struct mgag200_pll_values *pixpllc)
{
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = pixpllcm;
	xpixpllcn = pixpllcn;
	xpixpllcp = (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);

@@ -238,9 +245,9 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
						tmpdelta = clock - computed;
					if (tmpdelta < delta) {
						delta = tmpdelta;
						m = testm - 1;
						n = testn - 1;
						p = testp - 1;
						m = testm;
						n = testn;
						p = testp;
					}
				}
			}
@@ -278,22 +285,19 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl

					if (tmpdelta < delta) {
						delta = tmpdelta;
						m = testm - 1;
						n = testn - 1;
						p = testp - 1;
						m = testm;
						n = testn;
						p = testp;
					}
				}
			}
		}

		fvv = pllreffreq * (n + 1) / (m + 1);
		fvv = pllreffreq * n / m;
		fvv = (fvv - 800000) / 50000;

		if (fvv > 15)
			fvv = 15;

		p |= (fvv << 4);
		m |= 0x80;
		s = fvv << 1;

		clock = clock / 2;
	}
@@ -315,11 +319,17 @@ static void mgag200_set_pixpll_g200se(struct mga_device *mdev,
				      const struct mgag200_pll_values *pixpllc)
{
	u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
	xpixpllcn = pixpllcn;
	xpixpllcp = (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);

@@ -348,7 +358,6 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
	delta = 0xffffffff;

	if (mdev->type == G200_EW3) {

		vcomax = 800000;
		vcomin = 400000;
		pllreffreq = 25000;
@@ -371,19 +380,16 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
							tmpdelta = clock - computed;
						if (tmpdelta < delta) {
							delta = tmpdelta;
							m = ((testn & 0x100) >> 1) |
								(testm);
							n = (testn & 0xFF);
							p = ((testn & 0x600) >> 3) |
								(testp2 << 3) |
								(testp);
							m = testm + 1;
							n = testn + 1;
							p = testp + 1;
							s = testp2;
						}
					}
				}
			}
		}
	} else {

		vcomax = 550000;
		vcomin = 150000;
		pllreffreq = 48000;
@@ -404,10 +410,10 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
						tmpdelta = clock - computed;
					if (tmpdelta < delta) {
						delta = tmpdelta;
						n = testn - 1;
						m = (testm - 1) |
							((n >> 1) & 0x80);
						p = testp - 1;
						n = testn;
						m = testm;
						p = testp;
						s = 0;
					}
				}
			}
@@ -425,13 +431,19 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
static void mgag200_set_pixpll_g200wb(struct mga_device *mdev,
				      const struct mgag200_pll_values *pixpllc)
{
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
	int i, j, tmpcount, vcount;
	bool pll_locked = false;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = ((pixpllcn & BIT(8)) >> 1) | pixpllcm;
	xpixpllcn = pixpllcn;
	xpixpllcp = ((pixpllcn & GENMASK(10, 9)) >> 3) | (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);

@@ -564,9 +576,9 @@ static int mgag200_compute_pixpll_values_g200ev(struct mga_device *mdev, long cl
					tmpdelta = clock - computed;
				if (tmpdelta < delta) {
					delta = tmpdelta;
					n = testn - 1;
					m = testm - 1;
					p = testp - 1;
					n = testn;
					m = testm;
					p = testp;
				}
			}
		}
@@ -583,11 +595,17 @@ static int mgag200_compute_pixpll_values_g200ev(struct mga_device *mdev, long cl
static void mgag200_set_pixpll_g200ev(struct mga_device *mdev,
				      const struct mgag200_pll_values *pixpllc)
{
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = pixpllcm;
	xpixpllcn = pixpllcn;
	xpixpllcp = (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);

@@ -675,9 +693,9 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl
					tmpdelta = clock - computed;
				if (tmpdelta < delta) {
					delta = tmpdelta;
					n = testn;
					m = testm;
					p = testp;
					n = testn + 1;
					m = testm + 1;
					p = testp + 1;
				}
				if (delta == 0)
					break;
@@ -709,12 +727,10 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl
						tmpdelta = clock - computed;
					if (tmpdelta < delta) {
						delta = tmpdelta;
						n = testn - 1;
						m = (testm - 1);
						p = testp - 1;
						n = testn;
						m = testm;
						p = testp;
					}
					if ((clock * testp) >= 600000)
						p |= 0x80;
				}
			}
		}
@@ -731,13 +747,19 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl
static void mgag200_set_pixpll_g200eh(struct mga_device *mdev,
				      const struct mgag200_pll_values *pixpllc)
{
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
	int i, j, tmpcount, vcount;
	bool pll_locked = false;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = ((pixpllcn & BIT(8)) >> 1) | pixpllcm;
	xpixpllcn = pixpllcn;
	xpixpllcp = (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);

@@ -830,9 +852,10 @@ static int mgag200_compute_pixpll_values_g200er(struct mga_device *mdev, long cl
						tmpdelta = clock - computed;
					if (tmpdelta < delta) {
						delta = tmpdelta;
						m = testm | (testo << 3);
						n = testn;
						p = testr | (testr << 3);
						m = (testm | (testo << 3)) + 1;
						n = testn + 1;
						p = testr + 1;
						s = testr;
					}
				}
			}
@@ -850,11 +873,17 @@ static int mgag200_compute_pixpll_values_g200er(struct mga_device *mdev, long cl
static void mgag200_set_pixpll_g200er(struct mga_device *mdev,
				      const struct mgag200_pll_values *pixpllc)
{
	unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
	u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;

	xpixpllcm = pixpllc->m;
	xpixpllcn = pixpllc->n;
	xpixpllcp = pixpllc->p | (pixpllc->s << 3);
	pixpllcm = pixpllc->m - 1;
	pixpllcn = pixpllc->n - 1;
	pixpllcp = pixpllc->p - 1;
	pixpllcs = pixpllc->s;

	xpixpllcm = pixpllcm;
	xpixpllcn = pixpllcn;
	xpixpllcp = (pixpllcs << 3) | pixpllcp;

	WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);