summaryrefslogtreecommitdiff
path: root/drivers/video/tridentfb.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2008-07-23 21:30:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 10:47:35 -0700
commit6bdf1035602abf0564d24a7447eea1c149c4bcb1 (patch)
treeb1bd248dd77804f6c9f29040b89f640f477a5ad3 /drivers/video/tridentfb.c
parentc1724fecabfed504a4cfb87319ad3b9d3a8baa92 (diff)
tridentfb: fix clock settings for older Trident 96XX chips
The Xorg code shows that Trident models 9660, 9680 and 9682 require a different clock setting method. Add the second clock setting method for older models. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/tridentfb.c')
-rw-r--r--drivers/video/tridentfb.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index f3153a82f926..8ee4261abf3b 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -85,6 +85,11 @@ MODULE_PARM_DESC(fp, "Define if flatpanel is connected");
module_param(crt, int, 0);
MODULE_PARM_DESC(crt, "Define if CRT is connected");
+static int is_oldclock(int id)
+{
+ return (id == TGUI9660);
+}
+
static int is_blade(int id)
{
return (id == BLADE3D) ||
@@ -659,23 +664,33 @@ static void set_screen_start(struct tridentfb_par *par, int base)
static void set_vclk(struct tridentfb_par *par, unsigned long freq)
{
int m, n, k;
- unsigned long f, fi, d, di;
- unsigned char lo = 0, hi = 0;
+ unsigned long fi, d, di;
+ unsigned char best_m = 0, best_n = 0, best_k = 0;
+ unsigned char hi, lo;
d = 20000;
- for (k = 2; k >= 0; k--)
- for (m = 0; m < 63; m++)
- for (n = 0; n < 128; n++) {
+ for (k = 1; k >= 0; k--)
+ for (m = 0; m < 32; m++)
+ for (n = 0; n < 122; n++) {
fi = ((14318l * (n + 8)) / (m + 2)) >> k;
if ((di = abs(fi - freq)) < d) {
d = di;
- f = fi;
- lo = n;
- hi = (k << 6) | m;
+ best_n = n;
+ best_m = m;
+ best_k = k;
}
if (fi > freq)
break;
}
+
+ if (is_oldclock(par->chip_id)) {
+ lo = best_n | (best_m << 7);
+ hi = (best_m >> 1) | (best_k << 4);
+ } else {
+ lo = best_n;
+ hi = best_m | (best_k << 6);
+ }
+
if (is3Dchip(par->chip_id)) {
vga_mm_wseq(par->io_virt, ClockHigh, hi);
vga_mm_wseq(par->io_virt, ClockLow, lo);