drivers/gpu/drm/via/via_clocks.c |  118 ++++++++++++++++++++++++---------------
 drivers/gpu/drm/via/via_drv.h    |    4 -
 2 files changed, 76 insertions(+), 46 deletions(-)

New commits:
commit affa9b9df2045dd1275705d4897fce1ce2dd2cc6
Author: Kevin Brace <kevinbr...@gmx.com>
Date:   Tue Sep 27 13:31:01 2016 -0700

    Version bumped to 3.0.1
    
    Signed-off-by: Kevin Brace <kevinbr...@gmx.com>

diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index a3497ca..49deb8c 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -27,11 +27,11 @@
 #define DRIVER_AUTHOR       "The OpenChrome Project"
 #define DRIVER_NAME         "via"
 #define DRIVER_DESC         "VIA Technologies UniChrome / Chrome9"
-#define DRIVER_DATE         "20160916"
+#define DRIVER_DATE         "20160927"
 
 #define DRIVER_MAJOR           3
 #define DRIVER_MINOR           0
-#define DRIVER_PATCHLEVEL      0
+#define DRIVER_PATCHLEVEL      1
 
 #include <linux/module.h>
 
commit 166edf8d0ace0681deddb5b95be05c00d718b835
Author: Kevin Brace <kevinbr...@gmx.com>
Date:   Tue Sep 27 13:27:06 2016 -0700

    Add code to properly support UniChrome IGP PLL
    
    Unfortunately, the code to properly support UniChrome IGP
    (i.e., CLE266, KM400(A), KN400, and P4M800 chipsets) PLL was
    missing, so nothing proper would have been displayed on the
    monitor. This commit will fix this major flaw. The code for
    this commit was borrowed from OpenChrome DDX device driver UMS
    (User Mode Setting) section, but with some modifications applied.
    
    Signed-off-by: Kevin Brace <kevinbr...@gmx.com>

diff --git a/drivers/gpu/drm/via/via_clocks.c b/drivers/gpu/drm/via/via_clocks.c
index ad61369..61cdb76 100644
--- a/drivers/gpu/drm/via/via_clocks.c
+++ b/drivers/gpu/drm/via/via_clocks.c
@@ -2,6 +2,8 @@
  * Copyright 2012 James Simmons <jsimm...@infradead.org>
  *
  * Based on code for the viafb driver.
+ * UniChrome PLL parameters calculation code borrowed from OpenChrome DDX
+ * device driver.
  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
  *
@@ -60,58 +62,86 @@ via_get_clk_value(struct drm_device *dev, u32 freq)
                { 0, 0, 0, 0, 0 } };
        int count;
 
-       /* DN[6:0] */
-       for (pll_n = 2; pll_n < 6; pll_n++) {
-               /* DR[2:0] */
-               for (pll_r = 0; pll_r < 6; pll_r++) {
-                       /* DM[9:0] */
-                       for (pll_m = 2; pll_m < 512; pll_m++) {
-                               /* first divide pll_n then multiply
-                                * pll_m. We have to reduce pll_m
-                                * to 512 to get rid of the overflow */
-                               pll_fvco = (VIA_CLK_REFERENCE / pll_n) * pll_m;
-                               if ((pll_fvco >= CSR_VCO_DOWN) && (pll_fvco <= 
CSR_VCO_UP)) {
-                                       pll_fout = pll_fvco >> pll_r;
+    if ((dev->pdev->device != PCI_DEVICE_ID_VIA_CLE266) 
+        && (dev->pdev->device != PCI_DEVICE_ID_VIA_KM400)) {
+               /* DN[6:0] */
+               for (pll_n = 2; pll_n < 6; pll_n++) {
+                       /* DR[2:0] */
+                       for (pll_r = 0; pll_r < 6; pll_r++) {
+                               /* DM[9:0] */
+                               for (pll_m = 2; pll_m < 512; pll_m++) {
+                                       /* first divide pll_n then multiply
+                                        * pll_m. We have to reduce pll_m
+                                        * to 512 to get rid of the overflow */
+                                       pll_fvco = (VIA_CLK_REFERENCE / pll_n) 
* pll_m;
+                                       if ((pll_fvco >= CSR_VCO_DOWN) && 
(pll_fvco <= CSR_VCO_UP)) {
+                                               pll_fout = pll_fvco >> pll_r;
+                                               if (pll_fout < freq)
+                                                       clk_diff = freq - 
pll_fout;
+                                               else
+                                                       clk_diff = pll_fout - 
freq;
+
+                                               /* if frequency (which is the 
PLL we want
+                                                * to set) > 150MHz, the MRN 
value we
+                                                * write in register must < 
frequency, and
+                                                * get MRN value whose M is the 
largeset */
+                                               if (freq >= 150000000) {
+                                                       if ((clk_diff <= 
pll_tmp[0].diff_clk) || pll_tmp[0].pll_fout == 0) {
+                                                               for (count = 
ARRAY_SIZE(pll_tmp) - 1; count >= 1; count--)
+                                                                       
pll_tmp[count] = pll_tmp[count - 1];
+
+                                                               
pll_tmp[0].pll_m = pll_m;
+                                                               
pll_tmp[0].pll_r = pll_r;
+                                                               
pll_tmp[0].pll_n = pll_n;
+                                                               
pll_tmp[0].diff_clk = clk_diff;
+                                                               
pll_tmp[0].pll_fout = pll_fout;
+                                                       }
+                                               }
+
+                                               if (clk_diff < best_clk_diff) {
+                                                       best_clk_diff = 
clk_diff;
+                                                       best_pll_m = pll_m;
+                                                       best_pll_n = pll_n;
+                                                       best_pll_r = pll_r;
+                                               }
+                                       } /* if pll_fvco in VCO range */
+                               } /* for PLL M */
+                       } /* for PLL R */
+               } /* for PLL N */
+
+               /* if frequency(which is the PLL we want to set) > 150MHz,
+                * the MRN value we write in register must < frequency,
+                * and get MRN value whose M is the largeset */
+               if (freq > 150000000) {
+                       best_pll_m = pll_tmp[0].pll_m;
+                       best_pll_r = pll_tmp[0].pll_r;
+                       best_pll_n = pll_tmp[0].pll_n;
+               }
+       /* UniChrome IGP (CLE266, KM400(A), KN400, and P4M800 chipsets)
+        * requires a different formula for calculating the PLL parameters.
+        * The code was borrowed from OpenChrome DDX device driver UMS
+        * (User Mode Setting) section, but was modified to not use float type
+        * variables. */
+    } else {
+               for (pll_r = 0; pll_r < 4; ++pll_r) {
+                       for (pll_n = (pll_r == 0) ? 2 : 1; pll_n <= 7; ++pll_n) 
{
+                               for (pll_m = 1; pll_m <= 127; ++pll_m) {
+                                       pll_fout = VIA_CLK_REFERENCE * pll_m;
+                                       pll_fout /= (pll_n << pll_r);
                                        if (pll_fout < freq)
                                                clk_diff = freq - pll_fout;
                                        else
                                                clk_diff = pll_fout - freq;
 
-                                       /* if frequency (which is the PLL we 
want
-                                        * to set) > 150MHz, the MRN value we
-                                        * write in register must < frequency, 
and
-                                        * get MRN value whose M is the 
largeset */
-                                       if (freq >= 150000000) {
-                                               if ((clk_diff <= 
pll_tmp[0].diff_clk) || pll_tmp[0].pll_fout == 0) {
-                                                       for (count = 
ARRAY_SIZE(pll_tmp) - 1; count >= 1; count--)
-                                                               pll_tmp[count] 
= pll_tmp[count - 1];
-
-                                                       pll_tmp[0].pll_m = 
pll_m;
-                                                       pll_tmp[0].pll_r = 
pll_r;
-                                                       pll_tmp[0].pll_n = 
pll_n;
-                                                       pll_tmp[0].diff_clk = 
clk_diff;
-                                                       pll_tmp[0].pll_fout = 
pll_fout;
-                                               }
-                                       }
-
                                        if (clk_diff < best_clk_diff) {
                                                best_clk_diff = clk_diff;
-                                               best_pll_m = pll_m;
-                                               best_pll_n = pll_n;
-                                               best_pll_r = pll_r;
+                                               best_pll_m = pll_m & 0x7F;
+                                               best_pll_n = pll_n & 0x1F;
+                                               best_pll_r = pll_r & 0x03;
                                        }
-                               } /* if pll_fvco in VCO range */
-                       } /* for PLL M */
-               } /* for PLL R */
-       } /* for PLL N */
-
-       /* if frequency(which is the PLL we want to set) > 150MHz,
-        * the MRN value we write in register must < frequency,
-        * and get MRN value whose M is the largeset */
-       if (freq > 150000000) {
-               best_pll_m = pll_tmp[0].pll_m;
-               best_pll_r = pll_tmp[0].pll_r;
-               best_pll_n = pll_tmp[0].pll_n;
+                               }
+                       }
+               }
        }
 
        switch (dev->pdev->device) {
_______________________________________________
Openchrome-devel mailing list
Openchrome-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/openchrome-devel

Reply via email to