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@xxxxxxx> --- 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