--- 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 } }
};
/*