summaryrefslogtreecommitdiff
path: root/linux-tdfxfb-fixes.patch
blob: dd80ee25261b1c19a693dbaf56e50cd88ad74bc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
This patch contains:
* fix for hardware cursor
  (Voodoo4/Voodoo5 specific problem? bottom 48 lines contained random data
   if cursor start address was not aligned down to even page boundary...)
* fix for logo colours
  (I'm not sure about hardware, but at least this driver doesn't support colour
   lookup tables in 16/24/32bpp, so visual must be TRUECOLOR, not DIRECTCOLOR)
* interlace support (works on Voodoo4 (50 Hz only?), problably Voodoo[35] too)
* partial doublescan support (hardware cursor still doesn't work correctly,
  but such modes doesn't just turn monitor out-of-sync)

        -- Jakub Bogusz <qboosh@pld.org.pl>
	
--- linux-2.4.20/drivers/video/tdfxfb.c.orig	Mon Feb 25 20:38:07 2002
+++ linux-2.4.20/drivers/video/tdfxfb.c	Mon Dec  2 23:19:54 2002
@@ -208,6 +208,7 @@
 #define VGAINIT1_MASK			0x1fffff
 #define VIDCFG_VIDPROC_ENABLE		BIT(0)
 #define VIDCFG_CURS_X11			BIT(1)
+#define VIDCFG_INTERLACE		BIT(3)
 #define VIDCFG_HALF_MODE		BIT(4)
 #define VIDCFG_DESK_ENABLE		BIT(7)
 #define VIDCFG_CLUT_BYPASS		BIT(10)
@@ -238,6 +239,7 @@
 #define TDFXF_VSYNC_ACT_LOW	0x08
 #define TDFXF_LINE_DOUBLE	0x10
 #define TDFXF_VIDEO_ENABLE	0x20
+#define TDFXF_INTERLACE		0x40
 
 #define TDFXF_HSYNC_MASK	0x03
 #define TDFXF_VSYNC_MASK	0x0c
@@ -1321,10 +1323,17 @@
   hbs = hd;
   hbe = ht;
 
-  vd  = par->vdispend - 1;
-  vs  = par->vsyncsta - 1;
-  ve  = par->vsyncend - 1;
-  vt  = par->vtotal   - 2;
+  if (par->video & TDFXF_LINE_DOUBLE) {
+    vd = (par->vdispend << 1) - 1;
+    vs = (par->vsyncsta << 1) - 1;
+    ve = (par->vsyncend << 1) - 1;
+    vt = (par->vtotal   << 1) - 2;
+  } else {
+    vd = par->vdispend - 1;
+    vs = par->vsyncsta - 1;
+    ve = par->vsyncend - 1;
+    vt = par->vtotal   - 2;
+  }
   vbs = vd;
   vbe = vt;
   
@@ -1429,9 +1438,6 @@
     VGAINIT0_EXTSHIFTOUT;
   reg.vgainit1 = tdfx_inl(VGAINIT1) & 0x1fffff;
 
-  fb_info.cursor.enable=reg.vidcfg | VIDCFG_HWCURSOR_ENABLE;
-  fb_info.cursor.disable=reg.vidcfg;
-   
   reg.stride    = par->width*cpp;
   reg.cursloc   = 0;
    
@@ -1450,9 +1456,20 @@
   reg.gfxpll = do_calc_pll(..., &fout);
 #endif
 
-  reg.screensize = par->width | (par->height << 12);
-  reg.vidcfg &= ~VIDCFG_HALF_MODE;
+  if (par->video & TDFXF_LINE_DOUBLE) {
+    reg.screensize = par->width | (par->height << 13);
+    reg.vidcfg |= VIDCFG_HALF_MODE;
+    reg.crt[0x09] |= 0x80;
+  } else {
+    reg.screensize = par->width | (par->height << 12);
+    reg.vidcfg &= ~VIDCFG_HALF_MODE;
+  }
+  if (par->video & TDFXF_INTERLACE)
+    reg.vidcfg |= VIDCFG_INTERLACE;
 
+  fb_info.cursor.enable=reg.vidcfg | VIDCFG_HWCURSOR_ENABLE;
+  fb_info.cursor.disable=reg.vidcfg;
+   
   reg.miscinit0 = tdfx_inl(MISCINIT0);
 
 #if defined(__BIG_ENDIAN)
@@ -1496,11 +1513,6 @@
     return -EINVAL;
   }
 
-  if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-    DPRINTK("interlace not supported\n");
-    return -EINVAL;
-  }
-
   if(var->xoffset) {
     DPRINTK("xoffset not supported\n");
     return -EINVAL;
@@ -1516,9 +1528,10 @@
     return -EINVAL;
   }
 
-  /* fixme: does Voodoo3 support interlace? Banshee doesn't */
-  if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-    DPRINTK("interlace not supported\n");
+  /* Banshee doesn't support interlace, but Voodoo4 and probably Voodoo3 do. */
+  if(((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+     && (i->dev == PCI_DEVICE_ID_3DFX_BANSHEE)) {
+    DPRINTK("interlace not supported on Banshee\n");
     return -EINVAL;
   }
 
@@ -1578,6 +1591,8 @@
       par->video |= TDFXF_VSYNC_ACT_LOW;
     if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
       par->video |= TDFXF_LINE_DOUBLE;
+    else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+      par->video |= TDFXF_INTERLACE;
     if(var->activate == FB_ACTIVATE_NOW)
       par->video |= TDFXF_VIDEO_ENABLE;
   }
@@ -1639,6 +1654,8 @@
     v.sync |= FB_SYNC_VERT_HIGH_ACT;
   if(par->video & TDFXF_LINE_DOUBLE)
     v.vmode = FB_VMODE_DOUBLE;
+  else if(par->video & TDFXF_INTERLACE)
+    v.vmode = FB_VMODE_INTERLACED;
   *var = v;
   return 0;
 }
@@ -1672,7 +1689,7 @@
   fix->line_length = par->lpitch;
   fix->visual      = (par->bpp == 8) 
                      ? FB_VISUAL_PSEUDOCOLOR
-                     : FB_VISUAL_DIRECTCOLOR;
+                     : FB_VISUAL_TRUECOLOR;
 
   fix->xpanstep    = 0; 
   fix->ypanstep    = nopan ? 0 : 1;
@@ -2386,7 +2403,9 @@
 static void tdfxfb_hwcursor_init(void)
 {
    unsigned int start;
-   start = (fb_info.bufbase_size-1024) & PAGE_MASK;
+   start = (fb_info.bufbase_size-1024) & (PAGE_MASK << 1);
+   	/* even page boundary - on Voodoo4 4500 bottom 48 lines
+	 * contained trash when just page boundary was used... */
    fb_info.bufbase_size=start; 
    fb_info.cursor.cursorimage=fb_info.bufbase_size;
    printk("tdfxfb: reserving 1024 bytes for the hwcursor at %p\n",