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

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
...@@ -123,7 +123,7 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc ...@@ -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 in_div_max = 6;
const int feed_div_min = 7; const int feed_div_min = 7;
const int feed_div_max = 127; const int feed_div_max = 127;
u8 testm, testn; u8 testp, testm, testn;
u8 n = 0, m = 0, p, s; u8 n = 0, m = 0, p, s;
long f_vco; long f_vco;
long computed; long computed;
...@@ -141,10 +141,11 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc ...@@ -141,10 +141,11 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
clock = p_clk_min >> 3; clock = p_clk_min >> 3;
f_vco = clock; f_vco = clock;
for (p = 0; for (testp = 0;
p <= post_div_max && f_vco < p_clk_min; testp <= post_div_max && f_vco < p_clk_min;
p = (p << 1) + 1, f_vco <<= 1) testp = (testp << 1) + 1, f_vco <<= 1)
; ;
p = testp + 1;
delta = clock; delta = clock;
...@@ -157,12 +158,12 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc ...@@ -157,12 +158,12 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
tmp_delta = computed - f_vco; tmp_delta = computed - f_vco;
if (tmp_delta < delta) { if (tmp_delta < delta) {
delta = tmp_delta; delta = tmp_delta;
m = testm; m = testm + 1;
n = testn; n = testn + 1;
} }
} }
} }
f_vco = ref_clk * (n + 1) / (m + 1); f_vco = ref_clk * n / m;
if (f_vco < 100000) if (f_vco < 100000)
s = 0; s = 0;
else if (f_vco < 140000) else if (f_vco < 140000)
...@@ -186,11 +187,17 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc ...@@ -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, static void mgag200_set_pixpll_g200(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp; u8 xpixpllcm, xpixpllcn, xpixpllcp;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); 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 ...@@ -238,9 +245,9 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
m = testm - 1; m = testm;
n = testn - 1; n = testn;
p = testp - 1; p = testp;
} }
} }
} }
...@@ -278,22 +285,19 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -278,22 +285,19 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
m = testm - 1; m = testm;
n = testn - 1; n = testn;
p = testp - 1; p = testp;
} }
} }
} }
} }
fvv = pllreffreq * (n + 1) / (m + 1); fvv = pllreffreq * n / m;
fvv = (fvv - 800000) / 50000; fvv = (fvv - 800000) / 50000;
if (fvv > 15) if (fvv > 15)
fvv = 15; fvv = 15;
s = fvv << 1;
p |= (fvv << 4);
m |= 0x80;
clock = clock / 2; clock = clock / 2;
} }
...@@ -315,11 +319,17 @@ static void mgag200_set_pixpll_g200se(struct mga_device *mdev, ...@@ -315,11 +319,17 @@ static void mgag200_set_pixpll_g200se(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
u32 unique_rev_id = mdev->model.g200se.unique_rev_id; u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp; u8 xpixpllcm, xpixpllcn, xpixpllcp;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); 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 ...@@ -348,7 +358,6 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
delta = 0xffffffff; delta = 0xffffffff;
if (mdev->type == G200_EW3) { if (mdev->type == G200_EW3) {
vcomax = 800000; vcomax = 800000;
vcomin = 400000; vcomin = 400000;
pllreffreq = 25000; pllreffreq = 25000;
...@@ -371,19 +380,16 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl ...@@ -371,19 +380,16 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
m = ((testn & 0x100) >> 1) | m = testm + 1;
(testm); n = testn + 1;
n = (testn & 0xFF); p = testp + 1;
p = ((testn & 0x600) >> 3) | s = testp2;
(testp2 << 3) |
(testp);
} }
} }
} }
} }
} }
} else { } else {
vcomax = 550000; vcomax = 550000;
vcomin = 150000; vcomin = 150000;
pllreffreq = 48000; pllreffreq = 48000;
...@@ -404,10 +410,10 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl ...@@ -404,10 +410,10 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
n = testn - 1; n = testn;
m = (testm - 1) | m = testm;
((n >> 1) & 0x80); p = testp;
p = testp - 1; s = 0;
} }
} }
} }
...@@ -425,13 +431,19 @@ static int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long cl ...@@ -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, static void mgag200_set_pixpll_g200wb(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp; u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
int i, j, tmpcount, vcount; int i, j, tmpcount, vcount;
bool pll_locked = false; bool pll_locked = false;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); 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 ...@@ -564,9 +576,9 @@ static int mgag200_compute_pixpll_values_g200ev(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
n = testn - 1; n = testn;
m = testm - 1; m = testm;
p = testp - 1; p = testp;
} }
} }
} }
...@@ -583,11 +595,17 @@ static int mgag200_compute_pixpll_values_g200ev(struct mga_device *mdev, long cl ...@@ -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, static void mgag200_set_pixpll_g200ev(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp; u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); 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 ...@@ -675,9 +693,9 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
n = testn; n = testn + 1;
m = testm; m = testm + 1;
p = testp; p = testp + 1;
} }
if (delta == 0) if (delta == 0)
break; break;
...@@ -709,12 +727,10 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl ...@@ -709,12 +727,10 @@ static int mgag200_compute_pixpll_values_g200eh(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
n = testn - 1; n = testn;
m = (testm - 1); m = testm;
p = testp - 1; 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 ...@@ -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, static void mgag200_set_pixpll_g200eh(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp; u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
int i, j, tmpcount, vcount; int i, j, tmpcount, vcount;
bool pll_locked = false; bool pll_locked = false;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); 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 ...@@ -830,9 +852,10 @@ static int mgag200_compute_pixpll_values_g200er(struct mga_device *mdev, long cl
tmpdelta = clock - computed; tmpdelta = clock - computed;
if (tmpdelta < delta) { if (tmpdelta < delta) {
delta = tmpdelta; delta = tmpdelta;
m = testm | (testo << 3); m = (testm | (testo << 3)) + 1;
n = testn; n = testn + 1;
p = testr | (testr << 3); p = testr + 1;
s = testr;
} }
} }
} }
...@@ -850,11 +873,17 @@ static int mgag200_compute_pixpll_values_g200er(struct mga_device *mdev, long cl ...@@ -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, static void mgag200_set_pixpll_g200er(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs;
u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp; u8 xpixpllcm, xpixpllcn, xpixpllcp, tmp;
xpixpllcm = pixpllc->m; pixpllcm = pixpllc->m - 1;
xpixpllcn = pixpllc->n; pixpllcn = pixpllc->n - 1;
xpixpllcp = pixpllc->p | (pixpllc->s << 3); 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); WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment