Blob Blame History Raw
--- src/via_mode.c	2009-06-16 23:17:42.000000000 +0200
+++ src/via_mode.c	2009-06-16 22:43:58.000000000 +0200
@@ -974,21 +974,35 @@
  *
  */
 static void
-ViaSetPrimaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+ViaSetDotclock(ScrnInfoPtr pScrn, CARD32 clock, int base, int probase)
 {
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
 
     DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO,
-                     "ViaSetPrimaryDotclock to 0x%06x\n", (unsigned)clock));
+                     "ViaSetDotclock to 0x%06x\n", (unsigned)clock));
 
     if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) {
-        hwp->writeSeq(hwp, 0x46, clock >> 8);
-        hwp->writeSeq(hwp, 0x47, clock & 0xFF);
+        hwp->writeSeq(hwp, base, clock >> 8);
+        hwp->writeSeq(hwp, base+1, clock & 0xFF);
     } else {  /* unichrome pro */
-        hwp->writeSeq(hwp, 0x44, clock >> 16);
-        hwp->writeSeq(hwp, 0x45, (clock >> 8) & 0xFF);
-        hwp->writeSeq(hwp, 0x46, clock & 0xFF);
+        union pllparams pll;
+        int dtz, dr, dn, dm;
+        pll.packed = clock;
+        dtz = pll.params.dtz;
+        dr  = pll.params.dr;
+        dn  = pll.params.dn;
+        dm  = pll.params.dm;
+
+        /* The VX855 does not modify dm/dn, but earlier chipsets do. */
+        if (pVia->Chipset != VIA_VX855) {
+            dm -= 2;
+            dn -= 2;
+        }
+
+        hwp->writeSeq(hwp, probase, dm & 0xff);
+        hwp->writeSeq(hwp, probase+1, ((dm >> 8) & 0x03) | (dr << 2) | ((dtz & 1) << 7));
+        hwp->writeSeq(hwp, probase+2, (dn & 0x7f) | ((dtz & 2) << 6));
     }
 
     ViaSeqMask(hwp, 0x40, 0x02, 0x02);
@@ -999,25 +1013,28 @@
  *
  */
 static void
-ViaSetSecondaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+ViaSetPrimaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
 {
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    VIAPtr pVia = VIAPTR(pScrn);
-
-    DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO,
-                     "ViaSetSecondaryDotclock to 0x%06x\n", (unsigned)clock));
+    ViaSetDotclock(pScrn, clock, 0x46, 0x44);
+}
 
-    if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) {
-        hwp->writeSeq(hwp, 0x44, clock >> 8);
-        hwp->writeSeq(hwp, 0x45, clock & 0xFF);
-    } else {  /* unichrome pro */
-        hwp->writeSeq(hwp, 0x4A, clock >> 16);
-        hwp->writeSeq(hwp, 0x4B, (clock >> 8) & 0xFF);
-        hwp->writeSeq(hwp, 0x4C, clock & 0xFF);
-    }
+/*
+ *
+ */
+static void
+ViaSetSecondaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+{
+    ViaSetDotclock(pScrn, clock, 0x44, 0x4A);
+}
 
-    ViaSeqMask(hwp, 0x40, 0x04, 0x04);
-    ViaSeqMask(hwp, 0x40, 0x00, 0x04);
+/*
+ *
+ */
+static void
+ViaSetECKDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+{
+    /* Does the non-pro chip have an ECK clock ? */  
+    ViaSetDotclock(pScrn, clock, 0, 0x47);
 }
 
 /*
@@ -1287,15 +1304,16 @@
 {
     double fvco, fout, fref, err, minErr;
     CARD32 dr = 0, dn, dm, maxdm, maxdn;
-    CARD32 factual, bestClock;
-
+    CARD32 factual;
+    union pllparams bestClock;
+    
     fref = 14.318e6;
     fout = (double)clock * 1.e3;
 
     factual = ~0;
-    maxdm = factual / 14318000U - 2;
+    maxdm = factual / 14318000U;
     minErr = 1.e10;
-    bestClock = 0U;
+    bestClock.packed = 0U;
 
     do {
         fvco = fout * (1 << dr);
@@ -1306,30 +1324,31 @@
     }
 
     if (clock < 30000)
-        maxdn = 6;
+        maxdn = 8;
     else if (clock < 45000)
-        maxdn = 5;
+        maxdn = 7;
     else if (clock < 170000)
-        maxdn = 4;
+        maxdn = 6;
     else
-        maxdn = 3;
+        maxdn = 5;
 
-    for (dn = 0; dn < maxdn; ++dn) {
-        for (dm = 0; dm < maxdm; ++dm) {
-            factual = 14318000U * (dm + 2);
-            factual /= (dn + 2) << dr;
+    for (dn = 2; dn < maxdn; ++dn) {
+        for (dm = 2; dm < maxdm; ++dm) {
+            factual = 14318000U * dm;
+            factual /= dn << dr;
             if ((err = fabs((double)factual / fout - 1.)) < 0.005) {
                 if (err < minErr) {
                     minErr = err;
-                    bestClock = ((dm & 0xff) << 16) |
-                            (((1 << 7) | (dr << 2) | ((dm & 0x300) >> 8)) << 8)
-                            | (dn & 0x7f);
+                    bestClock.params.dtz = 1;
+                    bestClock.params.dr = dr;
+                    bestClock.params.dn = dn;
+                    bestClock.params.dm = dm;
                 }
             }
         }
     }
 
-    return bestClock;
+    return bestClock.packed;
 }
 
 /*
@@ -1356,15 +1375,10 @@
                          "ViaComputeDotClock %d : %04x : %04x\n",
                          mode->Clock, best1, best2));
         return best2;
-    } else if (pVia->Chipset == VIA_VX855) {
-        for (i = 0; ViaDotClocks[i].DotClock; i++)
-            if (ViaDotClocks[i].DotClock == mode->Clock &&
-                ViaDotClocks[i].Chrome9HCM)
-                return ViaDotClocks[i].Chrome9HCM;
     } else {
         for (i = 0; ViaDotClocks[i].DotClock; i++)
             if (ViaDotClocks[i].DotClock == mode->Clock)
-                return ViaDotClocks[i].UniChromePro;
+                return ViaDotClocks[i].UniChromePro.packed;
         return ViaComputeProDotClock(mode->Clock);
     }
 
--- src/via_mode.h	2009-06-16 23:08:20.000000000 +0200
+++ src/via_mode.h	2009-06-16 22:43:58.000000000 +0200
@@ -35,7 +35,16 @@
 #define VIA_BW_DDR400   498000000 /* > 1920x1080@60Hz@32bpp */
 #define VIA_BW_DDR667   922000000
 
-    
+union pllparams {
+    struct {
+        CARD32 dtz : 2;
+        CARD32 dr  : 3;
+        CARD32 dn  : 7;
+        CARD32 dm  :10;
+    } params;
+    CARD32 packed;
+};
+
 /*
  * simple lookup table for dotclocks
  *
@@ -43,57 +52,51 @@
 static struct ViaDotClock {
     int DotClock;
     CARD16 UniChrome;
-    CARD32 UniChromePro;
-    CARD32 Chrome9HCM;
+    union pllparams UniChromePro;
 } ViaDotClocks[] = {
-    {  25200, 0x513C, 0xa79004 }, 
-    {  25312, 0xC763, 0xc49005 }, 
-    {  26591, 0x471A, 0xce9005 }, 
-    {  31500, 0xC558, 0xae9003, 0xb01005 }, 
-    {  31704, 0x471F, 0xaf9002 }, 
-    {  32663, 0xC449, 0x479000 }, 
-    {  33750, 0x4721, 0x959002, 0x921004 }, 
-    {  35500, 0x5877, 0x759001 }, 
-    {  36000, 0x5879, 0x9f9002, 0xa11004 }, 
-    {  39822, 0xC459, 0x578c02 }, 
-    {  40000, 0x515F, 0x848c04, 0x700c05 }, 
-    {  41164, 0x4417, 0x2c8c00 }, 
-    {  46981, 0x5069, 0x678c02, 0x690c04 }, 
-    {  49500, 0xC353, 0xa48c04, 0x530c03 }, 
-    {  50000, 0xC354, 0x368c00 }, 
-    {  56300, 0x4F76, 0x3d8c00, 0x9d0c05 }, 
-    {  57284, 0x4E70, 0x3e8c00 }, 
-    {  64995, 0x0D3B, 0x6b8c01, 0x6d0c03 }, 
-    {  65000, 0x0D3B, 0x6b8c01, 0x6d0c03 }, /* Slightly unstable on PM800 */ 
-    {  65028, 0x866D, 0x6b8c01 }, 
-    {  74480, 0x156E, 0x288800, 0xd10c05 }, 
-    {  75000, 0x156E, 0x288800 }, 
-    {  78800, 0x442C, 0x2a8800, 0x6e0805 }, 
-    {  81135, 0x0622, 0x428801 }, 
-    {  81613, 0x4539, 0x708803, 0x720805 }, 
-    {  94500, 0x4542, 0x4d8801, 0x840805 }, 
-    { 108000, 0x0B53, 0x778802, 0x970805 }, 
-    { 108280, 0x4879, 0x778802 }, 
-    { 122000, 0x0D6F, 0x428800 }, 
-    { 122726, 0x073C, 0x878802, 0xac0805 }, 
-    { 135000, 0x0742, 0x6f8801, 0xbd0805}, 
-    { 148500, 0x0853, 0x518800, 0xd00805}, 
-    { 155800, 0x0857, 0x558402 },  
-    { 157500, 0x422C, 0x2a8400, 0x6e0405 }, 
-    { 161793, 0x4571, 0x6f8403 },  
-    { 162000, 0x0A71, 0x6f8403, 0x710405 }, 
-    { 175500, 0x4231, 0x2f8400 }, 
-    { 189000, 0x0542, 0x4d8401 }, 
-    { 202500, 0x0763, 0x6F8402, 0x8e0405 }, 
-    { 204800, 0x0764, 0x548401 }, 
-    { 218300, 0x043D, 0x3b8400, 0x990405 }, 
-    { 229500, 0x0660, 0x3e8400, 0xa10405 }, /* Not tested on Pro */
-    { 234000, 0, 0xa20403, 0xa40405 },
-    { 267250, 0, 0xb90403, 0xbb0405 },
-    { 297500, 0, 0xce0403, 0xd00405 },
-    { 339500, 0, 0x5d0002, 0x770005 },
-    { 340772, 0, 0x750003, 0x770005 },
-    {      0,      0,        0 }
+    {  25200, 0x513C, /* 0xa79004 */ { 1, 4, 6, 169 } },
+    {  25312, 0xC763, /* 0xc49005 */ { 1, 4, 7, 198 } },
+    {  26591, 0x471A, /* 0xce9005 */ { 1, 4, 7, 208 } },
+    {  31500, 0xC558, /* 0xae9003 */ { 1, 4, 5, 176 } },
+    {  31704, 0x471F, /* 0xaf9002 */ { 1, 4, 4, 177 } },
+    {  32663, 0xC449, /* 0x479000 */ { 1, 4, 2,  73 } },
+    {  33750, 0x4721, /* 0x959002 */ { 1, 4, 4, 151 } },
+    {  35500, 0x5877, /* 0x759001 */ { 1, 4, 3, 119 } },
+    {  36000, 0x5879, /* 0x9f9002 */ { 1, 4, 4, 161 } },
+    {  39822, 0xC459, /* 0x578c02 */ { 1, 3, 4,  89 } },
+    {  40000, 0x515F, /* 0x848c04 */ { 1, 3, 6, 134 } },
+    {  41164, 0x4417, /* 0x2c8c00 */ { 1, 3, 2,  46 } },
+    {  46981, 0x5069, /* 0x678c02 */ { 1, 3, 4, 105 } },
+    {  49500, 0xC353, /* 0xa48c04 */ { 3, 3, 5, 138 } },
+    {  50000, 0xC354, /* 0x368c00 */ { 1, 3, 2,  56 } },
+    {  56300, 0x4F76, /* 0x3d8c00 */ { 1, 3, 2,  63 } },
+    {  57284, 0x4E70, /* 0x3e8c00 */ { 1, 3, 2,  64 } },
+    {  64995, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } },
+    {  65000, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } }, /* Slightly unstable on PM800 */
+    {  65028, 0x866D, /* 0x6b8c01 */ { 1, 3, 3, 109 } },
+    {  74480, 0x156E, /* 0x288800 */ { 1, 2, 2,  42 } },
+    {  75000, 0x156E, /* 0x288800 */ { 1, 2, 2,  42 } },
+    {  78800, 0x442C, /* 0x2a8800 */ { 1, 2, 2,  44 } },
+    {  81135, 0x0622, /* 0x428801 */ { 1, 2, 3,  68 } },
+    {  81613, 0x4539, /* 0x708803 */ { 1, 2, 5, 114 } },
+    {  94500, 0x4542, /* 0x4d8801 */ { 1, 2, 3,  79 } },
+    { 108000, 0x0B53, /* 0x778802 */ { 1, 2, 4, 121 } },
+    { 108280, 0x4879, /* 0x778802 */ { 1, 2, 4, 121 } },
+    { 122000, 0x0D6F, /* 0x428800 */ { 1, 2, 2,  68 } },
+    { 122726, 0x073C, /* 0x878802 */ { 1, 2, 4, 137 } },
+    { 135000, 0x0742, /* 0x6f8801 */ { 1, 2, 3, 113 } },
+    { 148500, 0x0853, /* 0x518800 */ { 1, 2, 2,  83 } },
+    { 155800, 0x0857, /* 0x558402 */ { 1, 1, 4,  87 } }, 
+    { 157500, 0x422C, /* 0x2a8400 */ { 1, 1, 2,  44 } },
+    { 161793, 0x4571, /* 0x6f8403 */ { 1, 1, 5, 113 } }, 
+    { 162000, 0x0A71, /* 0x6f8403 */ { 1, 1, 5, 113 } },
+    { 175500, 0x4231, /* 0x2f8400 */ { 1, 1, 2,  49 } },
+    { 189000, 0x0542, /* 0x4d8401 */ { 1, 1, 3,  79 } },
+    { 202500, 0x0763, /* 0x6F8402 */ { 1, 1, 4, 113 } },
+    { 204800, 0x0764, /* 0x548401 */ { 1, 1, 3,  86 } },
+    { 218300, 0x043D, /* 0x3b8400 */ { 1, 1, 2,  61 } },
+    { 229500, 0x0660, /* 0x3e8400 */ { 1, 1, 2,  64 } }, /* Not tested on Pro } */
+    {      0,      0,                { 0, 0, 0,   0 } }
 };
 
 /*