Commit ac643ccd authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/mgag200: Split PLL compute function for G200SE by rev

The compute function for G200SE pixel PLLs handles two revisions with
different algorithms. Split it accordingly to make it readable. No
functional changes.
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-9-tzimmermann@suse.de
parent 35b36ff4
...@@ -206,27 +206,20 @@ static void mgag200_set_pixpll_g200(struct mga_device *mdev, ...@@ -206,27 +206,20 @@ static void mgag200_set_pixpll_g200(struct mga_device *mdev,
WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp); WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp);
} }
static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long clock, static int mgag200_compute_pixpll_values_g200se_00(struct mga_device *mdev, long clock,
struct mgag200_pll_values *pixpllc) struct mgag200_pll_values *pixpllc)
{ {
static const unsigned int pvalues_e4[] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
unsigned int vcomax, vcomin, pllreffreq; unsigned int vcomax, vcomin, pllreffreq;
unsigned int delta, tmpdelta, permitteddelta; unsigned int delta, tmpdelta, permitteddelta;
unsigned int testp, testm, testn; unsigned int testp, testm, testn;
unsigned int p, m, n, s; unsigned int p, m, n, s;
unsigned int computed; unsigned int computed;
unsigned int fvv;
unsigned int i;
m = n = p = s = 0; m = n = p = s = 0;
if (unique_rev_id <= 0x03) {
vcomax = 320000; vcomax = 320000;
vcomin = 160000; vcomin = 160000;
pllreffreq = 25000; pllreffreq = 25000;
delta = 0xffffffff;
permitteddelta = clock * 5 / 1000; permitteddelta = clock * 5 / 1000;
for (testp = 8; testp > 0; testp /= 2) { for (testp = 8; testp > 0; testp /= 2) {
...@@ -237,8 +230,7 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -237,8 +230,7 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
for (testn = 17; testn < 256; testn++) { for (testn = 17; testn < 256; testn++) {
for (testm = 1; testm < 32; testm++) { for (testm = 1; testm < 32; testm++) {
computed = (pllreffreq * testn) / computed = (pllreffreq * testn) / (testm * testp);
(testm * testp);
if (computed > clock) if (computed > clock)
tmpdelta = computed - clock; tmpdelta = computed - clock;
else else
...@@ -252,17 +244,44 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -252,17 +244,44 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
} }
} }
} }
} else {
if (delta > permitteddelta) {
pr_warn("PLL delta too large\n");
return -EINVAL;
}
pixpllc->m = m;
pixpllc->n = n;
pixpllc->p = p;
pixpllc->s = s;
return 0;
}
static int mgag200_compute_pixpll_values_g200se_04(struct mga_device *mdev, long clock,
struct mgag200_pll_values *pixpllc)
{
static const unsigned int pvalues_e4[] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
unsigned int vcomax, vcomin, pllreffreq;
unsigned int delta, tmpdelta, permitteddelta;
unsigned int testp, testm, testn;
unsigned int p, m, n, s;
unsigned int computed;
unsigned int fvv;
unsigned int i;
m = n = p = s = 0;
delta = 0xffffffff;
vcomax = 1600000; vcomax = 1600000;
vcomin = 800000; vcomin = 800000;
pllreffreq = 25000; pllreffreq = 25000;
if (clock < 25000) if (clock < 25000)
clock = 25000; clock = 25000;
clock = clock * 2; clock = clock * 2;
delta = 0xFFFFFFFF;
/* Permited delta is 0.5% as VESA Specification */ /* Permited delta is 0.5% as VESA Specification */
permitteddelta = clock * 5 / 1000; permitteddelta = clock * 5 / 1000;
...@@ -276,8 +295,7 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -276,8 +295,7 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
for (testn = 50; testn <= 256; testn++) { for (testn = 50; testn <= 256; testn++) {
for (testm = 1; testm <= 32; testm++) { for (testm = 1; testm <= 32; testm++) {
computed = (pllreffreq * testn) / computed = (pllreffreq * testn) / (testm * testp);
(testm * testp);
if (computed > clock) if (computed > clock)
tmpdelta = computed - clock; tmpdelta = computed - clock;
else else
...@@ -299,9 +317,6 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -299,9 +317,6 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
fvv = 15; fvv = 15;
s = fvv << 1; s = fvv << 1;
clock = clock / 2;
}
if (delta > permitteddelta) { if (delta > permitteddelta) {
pr_warn("PLL delta too large\n"); pr_warn("PLL delta too large\n");
return -EINVAL; return -EINVAL;
...@@ -315,6 +330,17 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl ...@@ -315,6 +330,17 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
return 0; return 0;
} }
static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long clock,
struct mgag200_pll_values *pixpllc)
{
u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
if (unique_rev_id >= 0x04)
return mgag200_compute_pixpll_values_g200se_04(mdev, clock, pixpllc);
else
return mgag200_compute_pixpll_values_g200se_00(mdev, clock, pixpllc);
}
static void mgag200_set_pixpll_g200se(struct mga_device *mdev, static void mgag200_set_pixpll_g200se(struct mga_device *mdev,
const struct mgag200_pll_values *pixpllc) const struct mgag200_pll_values *pixpllc)
{ {
......
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