[PATCH 09/12] drm/mgag200: Split PLL computation for G200SE
Thomas Zimmermann
tzimmermann at suse.de
Mon Jul 5 12:45:12 UTC 2021
The compute function for G200SE pixle PLLs handles two revisions with
different algorithms. Split it accordingly to make it readable.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
drivers/gpu/drm/mgag200/mgag200_mode.c | 165 +++++++++++++++----------
1 file changed, 97 insertions(+), 68 deletions(-)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 72fdf242cac7..99b35e4f9353 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -184,100 +184,118 @@ static int mgag200_compute_pixpll_values_g200(struct mga_device *mdev, long cloc
return 0;
}
-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;
delta = 0xffffffff;
- if (unique_rev_id <= 0x03) {
- vcomax = 320000;
- vcomin = 160000;
- pllreffreq = 25000;
- 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;
- clock = clock * 2;
+ if (delta > permitteddelta) {
+ pr_warn("PLL delta too large\n");
+ return -EINVAL;
+ }
- /* Permited delta is 0.5% as VESA Specification */
- permitteddelta = clock * 5 / 1000;
+ pixpllc->m = m;
+ pixpllc->n = n;
+ pixpllc->p = p;
+ pixpllc->s = s;
- for (i = 0 ; i < ARRAY_SIZE(pvalues_e4); i++) {
- testp = pvalues_e4[i];
+ return 0;
+}
- if ((clock * testp) > vcomax)
- continue;
- if ((clock * testp) < vcomin)
- continue;
+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};
- 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;
+ 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;
- if (tmpdelta < delta) {
- delta = tmpdelta;
- m = testm;
- n = testn;
- p = testp;
- }
+ m = n = p = s = 0;
+ delta = 0xffffffff;
+
+ 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;
@@ -291,6 +309,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 int mgag200_compute_pixpll_values_g200wb(struct mga_device *mdev, long clock,
struct mgag200_pll_values *pixpllc)
{
--
2.32.0
More information about the dri-devel
mailing list