aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2021-07-14 16:22:35 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2021-08-08 20:13:58 +0200
commitac643ccd3023e967cad895f7eb7ff4a02135020a (patch)
tree5c1e13d99b1c81cab5e25bb741939408db11d365
parentdrm/mgag200: Split PLL compute functions by device type (diff)
downloadlinux-dev-ac643ccd3023e967cad895f7eb7ff4a02135020a.tar.xz
linux-dev-ac643ccd3023e967cad895f7eb7ff4a02135020a.zip
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: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210714142240.21979-9-tzimmermann@suse.de
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c166
1 files changed, 96 insertions, 70 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 45ba4fb83601..3ef8b9f7e455 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -206,102 +206,117 @@ static void mgag200_set_pixpll_g200(struct mga_device *mdev,
WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp);
}
-static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long clock,
- struct mgag200_pll_values *pixpllc)
+static int mgag200_compute_pixpll_values_g200se_00(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};
-
- u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
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;
- if (unique_rev_id <= 0x03) {
- vcomax = 320000;
- vcomin = 160000;
- pllreffreq = 25000;
- delta = 0xffffffff;
- permitteddelta = clock * 5 / 1000;
+ vcomax = 320000;
+ vcomin = 160000;
+ pllreffreq = 25000;
+ permitteddelta = clock * 5 / 1000;
- for (testp = 8; testp > 0; testp /= 2) {
- if (clock * testp > vcomax)
- continue;
- if (clock * testp < vcomin)
- continue;
+ for (testp = 8; testp > 0; testp /= 2) {
+ if (clock * testp > vcomax)
+ continue;
+ if (clock * testp < vcomin)
+ continue;
- for (testn = 17; testn < 256; testn++) {
- for (testm = 1; testm < 32; testm++) {
- computed = (pllreffreq * testn) /
- (testm * testp);
- if (computed > clock)
- tmpdelta = computed - clock;
- else
- tmpdelta = clock - computed;
- if (tmpdelta < delta) {
- delta = tmpdelta;
- m = testm;
- n = testn;
- p = testp;
- }
+ for (testn = 17; testn < 256; testn++) {
+ for (testm = 1; testm < 32; testm++) {
+ computed = (pllreffreq * testn) / (testm * testp);
+ if (computed > clock)
+ tmpdelta = computed - clock;
+ else
+ tmpdelta = clock - computed;
+ if (tmpdelta < delta) {
+ delta = tmpdelta;
+ m = testm;
+ n = testn;
+ p = testp;
}
}
}
- } else {
- vcomax = 1600000;
- vcomin = 800000;
- pllreffreq = 25000;
+ }
- if (clock < 25000)
- clock = 25000;
+ if (delta > permitteddelta) {
+ pr_warn("PLL delta too large\n");
+ return -EINVAL;
+ }
- clock = clock * 2;
+ pixpllc->m = m;
+ pixpllc->n = n;
+ pixpllc->p = p;
+ pixpllc->s = s;
- delta = 0xFFFFFFFF;
- /* Permited delta is 0.5% as VESA Specification */
- permitteddelta = clock * 5 / 1000;
+ return 0;
+}
- for (i = 0 ; i < ARRAY_SIZE(pvalues_e4); i++) {
- testp = pvalues_e4[i];
+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};
- if ((clock * testp) > vcomax)
- continue;
- if ((clock * testp) < vcomin)
- continue;
+ 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;
- for (testn = 50; testn <= 256; testn++) {
- for (testm = 1; testm <= 32; testm++) {
- computed = (pllreffreq * testn) /
- (testm * testp);
- if (computed > clock)
- tmpdelta = computed - clock;
- else
- tmpdelta = clock - computed;
+ m = n = p = s = 0;
+ delta = 0xffffffff;
- if (tmpdelta < delta) {
- delta = tmpdelta;
- m = testm;
- n = testn;
- p = testp;
- }
+ vcomax = 1600000;
+ vcomin = 800000;
+ pllreffreq = 25000;
+
+ if (clock < 25000)
+ clock = 25000;
+ clock = clock * 2;
+
+ /* Permited delta is 0.5% as VESA Specification */
+ permitteddelta = clock * 5 / 1000;
+
+ for (i = 0 ; i < ARRAY_SIZE(pvalues_e4); i++) {
+ testp = pvalues_e4[i];
+
+ if ((clock * testp) > vcomax)
+ continue;
+ if ((clock * testp) < vcomin)
+ continue;
+
+ for (testn = 50; testn <= 256; testn++) {
+ for (testm = 1; testm <= 32; testm++) {
+ computed = (pllreffreq * testn) / (testm * testp);
+ if (computed > clock)
+ tmpdelta = computed - clock;
+ else
+ tmpdelta = clock - computed;
+
+ if (tmpdelta < delta) {
+ delta = tmpdelta;
+ m = testm;
+ n = testn;
+ p = testp;
}
}
}
-
- fvv = pllreffreq * n / m;
- fvv = (fvv - 800000) / 50000;
- if (fvv > 15)
- fvv = 15;
- s = fvv << 1;
-
- clock = clock / 2;
}
+ fvv = pllreffreq * n / m;
+ fvv = (fvv - 800000) / 50000;
+ if (fvv > 15)
+ fvv = 15;
+ s = fvv << 1;
+
if (delta > permitteddelta) {
pr_warn("PLL delta too large\n");
return -EINVAL;
@@ -315,6 +330,17 @@ static int mgag200_compute_pixpll_values_g200se(struct mga_device *mdev, long cl
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,
const struct mgag200_pll_values *pixpllc)
{