Diff markup
1 /* 1 /*
2 * linux/drivers/video/sstfb.c -- voodoo graph 2 * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
3 * 3 *
4 * Copyright (c) 2000-2002 Ghozlane Toumi 4 * Copyright (c) 2000-2002 Ghozlane Toumi <gtoumi@laposte.net>
5 * 5 *
6 * Created 15 Jan 2000 by Ghozlane Toumi 6 * Created 15 Jan 2000 by Ghozlane Toumi
7 * 7 *
8 * Contributions (and many thanks) : 8 * Contributions (and many thanks) :
9 * 9 *
10 * 03/2001 James Simmons <jsimmons@infradead 10 * 03/2001 James Simmons <jsimmons@infradead.org>
11 * 04/2001 Paul Mundt <lethal@chaoticdrea 11 * 04/2001 Paul Mundt <lethal@chaoticdreams.org>
12 * 05/2001 Urs Ganse <ursg@uni.de> 12 * 05/2001 Urs Ganse <ursg@uni.de>
13 * (initial work on voodoo2 port, interla 13 * (initial work on voodoo2 port, interlace)
14 * 09/2002 Helge Deller <deller@gmx.de> 14 * 09/2002 Helge Deller <deller@gmx.de>
15 * (enable driver on big-endian machines 15 * (enable driver on big-endian machines (hppa), ioctl fixes)
16 * 12/2002 Helge Deller <deller@gmx.de> 16 * 12/2002 Helge Deller <deller@gmx.de>
17 * (port driver to new frambuffer infrast 17 * (port driver to new frambuffer infrastructure)
18 * 01/2003 Helge Deller <deller@gmx.de> 18 * 01/2003 Helge Deller <deller@gmx.de>
19 * (initial work on fb hardware accelerat 19 * (initial work on fb hardware acceleration for voodoo2)
20 * 08/2006 Alan Cox <alan@redhat.com> 20 * 08/2006 Alan Cox <alan@redhat.com>
21 * Remove never finished and bogus 24/32b 21 * Remove never finished and bogus 24/32bit support
22 * Clean up macro abuse 22 * Clean up macro abuse
23 * Minor tidying for format. 23 * Minor tidying for format.
24 * 12/2006 Helge Deller <deller@gmx.de> 24 * 12/2006 Helge Deller <deller@gmx.de>
25 * add /sys/class/graphics/fbX/vgapass sy 25 * add /sys/class/graphics/fbX/vgapass sysfs-interface
26 * add module option "mode_option" to set 26 * add module option "mode_option" to set initial screen mode
27 * use fbdev default videomode database 27 * use fbdev default videomode database
28 * remove debug functions from ioctl 28 * remove debug functions from ioctl
29 */ 29 */
30 30
31 /* 31 /*
32 * The voodoo1 has the following memory mapped 32 * The voodoo1 has the following memory mapped address space:
33 * 0x000000 - 0x3fffff : registers 33 * 0x000000 - 0x3fffff : registers (4MB)
34 * 0x400000 - 0x7fffff : linear frame buffer 34 * 0x400000 - 0x7fffff : linear frame buffer (4MB)
35 * 0x800000 - 0xffffff : texture memory 35 * 0x800000 - 0xffffff : texture memory (8MB)
36 */ 36 */
37 37
38 /* 38 /*
39 * misc notes, TODOs, toASKs, and deep thought 39 * misc notes, TODOs, toASKs, and deep thoughts
40 40
41 -TODO: at one time or another test that the mo 41 -TODO: at one time or another test that the mode is acceptable by the monitor
42 -ASK: Can I choose different ordering for the 42 -ASK: Can I choose different ordering for the color bitfields (rgba argb ...)
43 which one should i use ? is there any pr 43 which one should i use ? is there any preferred one ? It seems ARGB is
44 the one ... 44 the one ...
45 -TODO: in set_var check the validity of timin 45 -TODO: in set_var check the validity of timings (hsync vsync)...
46 -TODO: check and recheck the use of sst_wait_i 46 -TODO: check and recheck the use of sst_wait_idle : we don't flush the fifo via
47 a nop command. so it's ok as long as th 47 a nop command. so it's ok as long as the commands we pass don't go
48 through the fifo. warning: issuing a no 48 through the fifo. warning: issuing a nop command seems to need pci_fifo
49 -FIXME: in case of failure in the init sequenc 49 -FIXME: in case of failure in the init sequence, be sure we return to a safe
50 state. 50 state.
51 - FIXME: Use accelerator for 2D scroll 51 - FIXME: Use accelerator for 2D scroll
52 -FIXME: 4MB boards have banked memory (FbiInit 52 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
53 */ 53 */
54 54
55 /* 55 /*
56 * debug info 56 * debug info
57 * SST_DEBUG : enable debugging 57 * SST_DEBUG : enable debugging
58 * SST_DEBUG_REG : debug registers 58 * SST_DEBUG_REG : debug registers
59 * 0 : no debug 59 * 0 : no debug
60 * 1 : dac calls, [un]set_bits, FbiInit 60 * 1 : dac calls, [un]set_bits, FbiInit
61 * 2 : insane debug level (log every registe 61 * 2 : insane debug level (log every register read/write)
62 * SST_DEBUG_FUNC : functions 62 * SST_DEBUG_FUNC : functions
63 * 0 : no debug 63 * 0 : no debug
64 * 1 : function call / debug ioctl 64 * 1 : function call / debug ioctl
65 * 2 : variables 65 * 2 : variables
66 * 3 : flood . you don't want to do that. tr 66 * 3 : flood . you don't want to do that. trust me.
67 * SST_DEBUG_VAR : debug display/var structs 67 * SST_DEBUG_VAR : debug display/var structs
68 * 0 : no debug 68 * 0 : no debug
69 * 1 : dumps display, fb_var 69 * 1 : dumps display, fb_var
70 * 70 *
71 * sstfb specific ioctls: 71 * sstfb specific ioctls:
72 * toggle vga (0x46db) : toggle v 72 * toggle vga (0x46db) : toggle vga_pass_through
73 */ 73 */
74 74
75 #undef SST_DEBUG 75 #undef SST_DEBUG
76 76
77 77
78 /* 78 /*
79 * Includes 79 * Includes
80 */ 80 */
81 81
82 #include <linux/string.h> 82 #include <linux/string.h>
83 #include <linux/kernel.h> 83 #include <linux/kernel.h>
84 #include <linux/module.h> 84 #include <linux/module.h>
85 #include <linux/fb.h> 85 #include <linux/fb.h>
86 #include <linux/pci.h> 86 #include <linux/pci.h>
87 #include <linux/delay.h> 87 #include <linux/delay.h>
88 #include <linux/init.h> 88 #include <linux/init.h>
89 #include <linux/slab.h> 89 #include <linux/slab.h>
90 #include <asm/io.h> 90 #include <asm/io.h>
91 #include <linux/uaccess.h> 91 #include <linux/uaccess.h>
92 #include <video/sstfb.h> 92 #include <video/sstfb.h>
93 93
94 94
95 /* initialized by setup */ 95 /* initialized by setup */
96 96
97 static int vgapass; /* enable VGA 97 static int vgapass; /* enable VGA passthrough cable */
98 static int mem; /* mem size in 98 static int mem; /* mem size in MB, 0 = autodetect */
99 static int clipping = 1; /* use clippin 99 static int clipping = 1; /* use clipping (slower, safer) */
100 static int gfxclk; /* force FBI f 100 static int gfxclk; /* force FBI freq in Mhz . Dangerous */
101 static int slowpci; /* slow PCI se 101 static int slowpci; /* slow PCI settings */
102 102
103 /* 103 /*
104 Possible default video modes: 800x600@60, 64 104 Possible default video modes: 800x600@60, 640x480@75, 1024x768@76, 640x480@60
105 */ 105 */
106 #define DEFAULT_VIDEO_MODE "640x480@60" 106 #define DEFAULT_VIDEO_MODE "640x480@60"
107 107
108 static char *mode_option __devinitdata = DEFAU 108 static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE;
109 109
110 enum { 110 enum {
111 ID_VOODOO1 = 0, 111 ID_VOODOO1 = 0,
112 ID_VOODOO2 = 1, 112 ID_VOODOO2 = 1,
113 }; 113 };
114 114
115 #define IS_VOODOO2(par) ((par)->type == ID_VOO 115 #define IS_VOODOO2(par) ((par)->type == ID_VOODOO2)
116 116
117 static struct sst_spec voodoo_spec[] __devinit 117 static struct sst_spec voodoo_spec[] __devinitdata = {
118 { .name = "Voodoo Graphics", .default_gfx_clo 118 { .name = "Voodoo Graphics", .default_gfx_clock = 50000, .max_gfxclk = 60 },
119 { .name = "Voodoo2", .default_gfx_clo 119 { .name = "Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 },
120 }; 120 };
121 121
122 122
123 /* 123 /*
124 * debug functions 124 * debug functions
125 */ 125 */
126 126
127 #if (SST_DEBUG_REG > 0) 127 #if (SST_DEBUG_REG > 0)
128 static void sst_dbg_print_read_reg(u32 reg, u3 128 static void sst_dbg_print_read_reg(u32 reg, u32 val) {
129 const char *regname; 129 const char *regname;
130 switch (reg) { 130 switch (reg) {
131 case FBIINIT0: regname = "FbiInit0"; 131 case FBIINIT0: regname = "FbiInit0"; break;
132 case FBIINIT1: regname = "FbiInit1"; 132 case FBIINIT1: regname = "FbiInit1"; break;
133 case FBIINIT2: regname = "FbiInit2"; 133 case FBIINIT2: regname = "FbiInit2"; break;
134 case FBIINIT3: regname = "FbiInit3"; 134 case FBIINIT3: regname = "FbiInit3"; break;
135 case FBIINIT4: regname = "FbiInit4"; 135 case FBIINIT4: regname = "FbiInit4"; break;
136 case FBIINIT5: regname = "FbiInit5"; 136 case FBIINIT5: regname = "FbiInit5"; break;
137 case FBIINIT6: regname = "FbiInit6"; 137 case FBIINIT6: regname = "FbiInit6"; break;
138 default: regname = NULL; 138 default: regname = NULL; break;
139 } 139 }
140 if (regname == NULL) 140 if (regname == NULL)
141 r_ddprintk("sst_read(%#x): %#x 141 r_ddprintk("sst_read(%#x): %#x\n", reg, val);
142 else 142 else
143 r_dprintk(" sst_read(%s): %#x\ 143 r_dprintk(" sst_read(%s): %#x\n", regname, val);
144 } 144 }
145 145
146 static void sst_dbg_print_write_reg(u32 reg, u 146 static void sst_dbg_print_write_reg(u32 reg, u32 val) {
147 const char *regname; 147 const char *regname;
148 switch (reg) { 148 switch (reg) {
149 case FBIINIT0: regname = "FbiInit0"; 149 case FBIINIT0: regname = "FbiInit0"; break;
150 case FBIINIT1: regname = "FbiInit1"; 150 case FBIINIT1: regname = "FbiInit1"; break;
151 case FBIINIT2: regname = "FbiInit2"; 151 case FBIINIT2: regname = "FbiInit2"; break;
152 case FBIINIT3: regname = "FbiInit3"; 152 case FBIINIT3: regname = "FbiInit3"; break;
153 case FBIINIT4: regname = "FbiInit4"; 153 case FBIINIT4: regname = "FbiInit4"; break;
154 case FBIINIT5: regname = "FbiInit5"; 154 case FBIINIT5: regname = "FbiInit5"; break;
155 case FBIINIT6: regname = "FbiInit6"; 155 case FBIINIT6: regname = "FbiInit6"; break;
156 default: regname = NULL; 156 default: regname = NULL; break;
157 } 157 }
158 if (regname == NULL) 158 if (regname == NULL)
159 r_ddprintk("sst_write(%#x, %#x 159 r_ddprintk("sst_write(%#x, %#x)\n", reg, val);
160 else 160 else
161 r_dprintk(" sst_write(%s, %#x) 161 r_dprintk(" sst_write(%s, %#x)\n", regname, val);
162 } 162 }
163 #else /* (SST_DEBUG_REG > 0) */ 163 #else /* (SST_DEBUG_REG > 0) */
164 # define sst_dbg_print_read_reg(reg, val) 164 # define sst_dbg_print_read_reg(reg, val) do {} while(0)
165 # define sst_dbg_print_write_reg(reg, val) 165 # define sst_dbg_print_write_reg(reg, val) do {} while(0)
166 #endif /* (SST_DEBUG_REG > 0) */ 166 #endif /* (SST_DEBUG_REG > 0) */
167 167
168 /* 168 /*
169 * hardware access functions 169 * hardware access functions
170 */ 170 */
171 171
172 /* register access */ 172 /* register access */
173 #define sst_read(reg) __sst_read(par 173 #define sst_read(reg) __sst_read(par->mmio_vbase, reg)
174 #define sst_write(reg,val) __sst_write(pa 174 #define sst_write(reg,val) __sst_write(par->mmio_vbase, reg, val)
175 #define sst_set_bits(reg,val) __sst_set_bits 175 #define sst_set_bits(reg,val) __sst_set_bits(par->mmio_vbase, reg, val)
176 #define sst_unset_bits(reg,val) __sst_unset_bi 176 #define sst_unset_bits(reg,val) __sst_unset_bits(par->mmio_vbase, reg, val)
177 #define sst_dac_read(reg) __sst_dac_read 177 #define sst_dac_read(reg) __sst_dac_read(par->mmio_vbase, reg)
178 #define sst_dac_write(reg,val) __sst_dac_writ 178 #define sst_dac_write(reg,val) __sst_dac_write(par->mmio_vbase, reg, val)
179 #define dac_i_read(reg) __dac_i_read(p 179 #define dac_i_read(reg) __dac_i_read(par->mmio_vbase, reg)
180 #define dac_i_write(reg,val) __dac_i_write( 180 #define dac_i_write(reg,val) __dac_i_write(par->mmio_vbase, reg, val)
181 181
182 static inline u32 __sst_read(u8 __iomem *vbase 182 static inline u32 __sst_read(u8 __iomem *vbase, u32 reg)
183 { 183 {
184 u32 ret = readl(vbase + reg); 184 u32 ret = readl(vbase + reg);
185 sst_dbg_print_read_reg(reg, ret); 185 sst_dbg_print_read_reg(reg, ret);
186 return ret; 186 return ret;
187 } 187 }
188 188
189 static inline void __sst_write(u8 __iomem *vba 189 static inline void __sst_write(u8 __iomem *vbase, u32 reg, u32 val)
190 { 190 {
191 sst_dbg_print_write_reg(reg, val); 191 sst_dbg_print_write_reg(reg, val);
192 writel(val, vbase + reg); 192 writel(val, vbase + reg);
193 } 193 }
194 194
195 static inline void __sst_set_bits(u8 __iomem * 195 static inline void __sst_set_bits(u8 __iomem *vbase, u32 reg, u32 val)
196 { 196 {
197 r_dprintk("sst_set_bits(%#x, %#x)\n", 197 r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
198 __sst_write(vbase, reg, __sst_read(vba 198 __sst_write(vbase, reg, __sst_read(vbase, reg) | val);
199 } 199 }
200 200
201 static inline void __sst_unset_bits(u8 __iomem 201 static inline void __sst_unset_bits(u8 __iomem *vbase, u32 reg, u32 val)
202 { 202 {
203 r_dprintk("sst_unset_bits(%#x, %#x)\n" 203 r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
204 __sst_write(vbase, reg, __sst_read(vba 204 __sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
205 } 205 }
206 206
207 /* 207 /*
208 * wait for the fbi chip. ASK: what happens if 208 * wait for the fbi chip. ASK: what happens if the fbi is stuck ?
209 * 209 *
210 * the FBI is supposed to be ready if we recei 210 * the FBI is supposed to be ready if we receive 5 time
211 * in a row a "idle" answer to our requests 211 * in a row a "idle" answer to our requests
212 */ 212 */
213 213
214 #define sst_wait_idle() __sst_wait_idle(par->m 214 #define sst_wait_idle() __sst_wait_idle(par->mmio_vbase)
215 215
216 static int __sst_wait_idle(u8 __iomem *vbase) 216 static int __sst_wait_idle(u8 __iomem *vbase)
217 { 217 {
218 int count = 0; 218 int count = 0;
219 219
220 /* if (doFBINOP) __sst_write(vbase, NO 220 /* if (doFBINOP) __sst_write(vbase, NOPCMD, 0); */
221 221
222 while(1) { 222 while(1) {
223 if (__sst_read(vbase, STATUS) 223 if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
224 f_dddprintk("status: b 224 f_dddprintk("status: busy\n");
225 /* FIXME basicaly, this is a busy wait. maybe 225 /* FIXME basicaly, this is a busy wait. maybe not that good. oh well;
226 * this is a small loop after all. 226 * this is a small loop after all.
227 * Or maybe we should use mdelay() or udelay() 227 * Or maybe we should use mdelay() or udelay() here instead ? */
228 count = 0; 228 count = 0;
229 } else { 229 } else {
230 count++; 230 count++;
231 f_dddprintk("status: i 231 f_dddprintk("status: idle(%d)\n", count);
232 } 232 }
233 if (count >= 5) return 1; 233 if (count >= 5) return 1;
234 /* XXX do something to avoid hanging the mach 234 /* XXX do something to avoid hanging the machine if the voodoo is out */
235 } 235 }
236 } 236 }
237 237
238 238
239 /* dac access */ 239 /* dac access */
240 /* dac_read should be remaped to FbiInit2 (via 240 /* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
241 static u8 __sst_dac_read(u8 __iomem *vbase, u8 241 static u8 __sst_dac_read(u8 __iomem *vbase, u8 reg)
242 { 242 {
243 u8 ret; 243 u8 ret;
244 244
245 reg &= 0x07; 245 reg &= 0x07;
246 __sst_write(vbase, DAC_DATA, ((u32)reg 246 __sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
247 __sst_wait_idle(vbase); 247 __sst_wait_idle(vbase);
248 /* udelay(10); */ 248 /* udelay(10); */
249 ret = __sst_read(vbase, DAC_READ) & 0x 249 ret = __sst_read(vbase, DAC_READ) & 0xff;
250 r_dprintk("sst_dac_read(%#x): %#x\n", 250 r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
251 251
252 return ret; 252 return ret;
253 } 253 }
254 254
255 static void __sst_dac_write(u8 __iomem *vbase, 255 static void __sst_dac_write(u8 __iomem *vbase, u8 reg, u8 val)
256 { 256 {
257 r_dprintk("sst_dac_write(%#x, %#x)\n", 257 r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
258 reg &= 0x07; 258 reg &= 0x07;
259 __sst_write(vbase, DAC_DATA,(((u32)reg 259 __sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
260 __sst_wait_idle(vbase); 260 __sst_wait_idle(vbase);
261 } 261 }
262 262
263 /* indexed access to ti/att dacs */ 263 /* indexed access to ti/att dacs */
264 static u32 __dac_i_read(u8 __iomem *vbase, u8 264 static u32 __dac_i_read(u8 __iomem *vbase, u8 reg)
265 { 265 {
266 u32 ret; 266 u32 ret;
267 267
268 __sst_dac_write(vbase, DACREG_ADDR_I, 268 __sst_dac_write(vbase, DACREG_ADDR_I, reg);
269 ret = __sst_dac_read(vbase, DACREG_DAT 269 ret = __sst_dac_read(vbase, DACREG_DATA_I);
270 r_dprintk("sst_dac_read_i(%#x): %#x\n" 270 r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
271 return ret; 271 return ret;
272 } 272 }
273 static void __dac_i_write(u8 __iomem *vbase, u 273 static void __dac_i_write(u8 __iomem *vbase, u8 reg,u8 val)
274 { 274 {
275 r_dprintk("sst_dac_write_i(%#x, %#x)\n 275 r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
276 __sst_dac_write(vbase, DACREG_ADDR_I, 276 __sst_dac_write(vbase, DACREG_ADDR_I, reg);
277 __sst_dac_write(vbase, DACREG_DATA_I, 277 __sst_dac_write(vbase, DACREG_DATA_I, val);
278 } 278 }
279 279
280 /* compute the m,n,p , returns the real freq 280 /* compute the m,n,p , returns the real freq
281 * (ics datasheet : N <-> N1 , P <-> N2) 281 * (ics datasheet : N <-> N1 , P <-> N2)
282 * 282 *
283 * Fout= Fref * (M+2)/( 2^P * (N+2)) 283 * Fout= Fref * (M+2)/( 2^P * (N+2))
284 * we try to get close to the asked freq 284 * we try to get close to the asked freq
285 * with P as high, and M as low as possible 285 * with P as high, and M as low as possible
286 * range: 286 * range:
287 * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N 287 * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N <= 63
288 * ics : 1 <= M <= 127; 0 <= P <= 3; 1<= N 288 * ics : 1 <= M <= 127; 0 <= P <= 3; 1<= N <= 31
289 * we'll use the lowest limitation, should be 289 * we'll use the lowest limitation, should be precise enouth
290 */ 290 */
291 static int sst_calc_pll(const int freq, int *f 291 static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
292 { 292 {
293 int m, m2, n, p, best_err, fout; 293 int m, m2, n, p, best_err, fout;
294 int best_n = -1; 294 int best_n = -1;
295 int best_m = -1; 295 int best_m = -1;
296 296
297 best_err = freq; 297 best_err = freq;
298 p = 3; 298 p = 3;
299 /* f * 2^P = vco should be less than V 299 /* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/
300 while (((1 << p) * freq > VCO_MAX) && 300 while (((1 << p) * freq > VCO_MAX) && (p >= 0))
301 p--; 301 p--;
302 if (p == -1) 302 if (p == -1)
303 return -EINVAL; 303 return -EINVAL;
304 for (n = 1; n < 32; n++) { 304 for (n = 1; n < 32; n++) {
305 /* calc 2 * m so we can round 305 /* calc 2 * m so we can round it later*/
306 m2 = (2 * freq * (1 << p) * (n 306 m2 = (2 * freq * (1 << p) * (n + 2) ) / DAC_FREF - 4 ;
307 307
308 m = (m2 % 2 ) ? m2/2+1 : m2/2 308 m = (m2 % 2 ) ? m2/2+1 : m2/2 ;
309 if (m >= 128) 309 if (m >= 128)
310 break; 310 break;
311 fout = (DAC_FREF * (m + 2)) / 311 fout = (DAC_FREF * (m + 2)) / ((1 << p) * (n + 2));
312 if ((abs(fout - freq) < best_e 312 if ((abs(fout - freq) < best_err) && (m > 0)) {
313 best_n = n; 313 best_n = n;
314 best_m = m; 314 best_m = m;
315 best_err = abs(fout - 315 best_err = abs(fout - freq);
316 /* we get the lowest m 316 /* we get the lowest m , allowing 0.5% error in freq*/
317 if (200*best_err < fre 317 if (200*best_err < freq) break;
318 } 318 }
319 } 319 }
320 if (best_n == -1) /* unlikely, but wh 320 if (best_n == -1) /* unlikely, but who knows ? */
321 return -EINVAL; 321 return -EINVAL;
322 t->p = p; 322 t->p = p;
323 t->n = best_n; 323 t->n = best_n;
324 t->m = best_m; 324 t->m = best_m;
325 *freq_out = (DAC_FREF * (t->m + 2)) / 325 *freq_out = (DAC_FREF * (t->m + 2)) / ((1 << t->p) * (t->n + 2));
326 f_ddprintk ("m: %d, n: %d, p: %d, F: % 326 f_ddprintk ("m: %d, n: %d, p: %d, F: %dKhz\n",
327 t->m, t->n, t->p, *freq_out) 327 t->m, t->n, t->p, *freq_out);
328 return 0; 328 return 0;
329 } 329 }
330 330
331 /* 331 /*
332 * clear lfb screen 332 * clear lfb screen
333 */ 333 */
334 static void sstfb_clear_screen(struct fb_info 334 static void sstfb_clear_screen(struct fb_info *info)
335 { 335 {
336 /* clear screen */ 336 /* clear screen */
337 fb_memset(info->screen_base, 0, info-> 337 fb_memset(info->screen_base, 0, info->fix.smem_len);
338 } 338 }
339 339
340 340
341 /** 341 /**
342 * sstfb_check_var - Optional function. 342 * sstfb_check_var - Optional function. Validates a var passed in.
343 * @var: frame buffer variable screen str 343 * @var: frame buffer variable screen structure
344 * @info: frame buffer structure that rep 344 * @info: frame buffer structure that represents a single frame buffer
345 * 345 *
346 * Limit to the abilities of a single chi 346 * Limit to the abilities of a single chip as SLI is not supported
347 * by this driver. 347 * by this driver.
348 */ 348 */
349 349
350 static int sstfb_check_var(struct fb_var_scree 350 static int sstfb_check_var(struct fb_var_screeninfo *var,
351 struct fb_info *info) 351 struct fb_info *info)
352 { 352 {
353 struct sstfb_par *par = info->par; 353 struct sstfb_par *par = info->par;
354 int hSyncOff = var->xres + var->righ 354 int hSyncOff = var->xres + var->right_margin + var->left_margin;
355 int vSyncOff = var->yres + var->lowe 355 int vSyncOff = var->yres + var->lower_margin + var->upper_margin;
356 int vBackPorch = var->left_margin, yDi 356 int vBackPorch = var->left_margin, yDim = var->yres;
357 int vSyncOn = var->vsync_len; 357 int vSyncOn = var->vsync_len;
358 int tiles_in_X, real_length; 358 int tiles_in_X, real_length;
359 unsigned int freq; 359 unsigned int freq;
360 360
361 if (sst_calc_pll(PICOS2KHZ(var->pixclo 361 if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) {
362 printk(KERN_ERR "sstfb: Pixclo 362 printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n",
363 PICOS2KHZ(var- 363 PICOS2KHZ(var->pixclock));
364 return -EINVAL; 364 return -EINVAL;
365 } 365 }
366 var->pixclock = KHZ2PICOS(freq); 366 var->pixclock = KHZ2PICOS(freq);
367 367
368 if (var->vmode & FB_VMODE_INTERLACED) 368 if (var->vmode & FB_VMODE_INTERLACED)
369 vBackPorch += (vBackPorch % 2) 369 vBackPorch += (vBackPorch % 2);
370 if (var->vmode & FB_VMODE_DOUBLE) { 370 if (var->vmode & FB_VMODE_DOUBLE) {
371 vBackPorch <<= 1; 371 vBackPorch <<= 1;
372 yDim <<=1; 372 yDim <<=1;
373 vSyncOn <<=1; 373 vSyncOn <<=1;
374 vSyncOff <<=1; 374 vSyncOff <<=1;
375 } 375 }
376 376
377 switch (var->bits_per_pixel) { 377 switch (var->bits_per_pixel) {
378 case 0 ... 16 : 378 case 0 ... 16 :
379 var->bits_per_pixel = 16; 379 var->bits_per_pixel = 16;
380 break; 380 break;
381 default : 381 default :
382 printk(KERN_ERR "sstfb: Unsupp 382 printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel);
383 return -EINVAL; 383 return -EINVAL;
384 } 384 }
385 385
386 /* validity tests */ 386 /* validity tests */
387 if (var->xres <= 1 || yDim <= 0 || var 387 if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1 ||
388 hSyncOff <= 1 || var->left_margin 388 hSyncOff <= 1 || var->left_margin <= 2 || vSyncOn <= 0 ||
389 vSyncOff <= 0 || vBackPorch <= 0) 389 vSyncOff <= 0 || vBackPorch <= 0) {
390 return -EINVAL; 390 return -EINVAL;
391 } 391 }
392 392
393 if (IS_VOODOO2(par)) { 393 if (IS_VOODOO2(par)) {
394 /* Voodoo 2 limits */ 394 /* Voodoo 2 limits */
395 tiles_in_X = (var->xres + 63 ) 395 tiles_in_X = (var->xres + 63 ) / 64 * 2;
396 396
397 if (var->xres > POW2(11) || y 397 if (var->xres > POW2(11) || yDim >= POW2(11)) {
398 printk(KERN_ERR "sstfb 398 printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
399 var->xres, va 399 var->xres, var->yres);
400 return -EINVAL; 400 return -EINVAL;
401 } 401 }
402 402
403 if (var->hsync_len > POW2(9) | 403 if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) ||
404 var->left_margin - 2 >= PO 404 var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) ||
405 vSyncOff >= POW2(13) || vB 405 vSyncOff >= POW2(13) || vBackPorch >= POW2(9) ||
406 tiles_in_X >= POW2(6) || t 406 tiles_in_X >= POW2(6) || tiles_in_X <= 0) {
407 printk(KERN_ERR "sstfb 407 printk(KERN_ERR "sstfb: Unsupported timings\n");
408 return -EINVAL; 408 return -EINVAL;
409 } 409 }
410 } else { 410 } else {
411 /* Voodoo limits */ 411 /* Voodoo limits */
412 tiles_in_X = (var->xres + 63 ) 412 tiles_in_X = (var->xres + 63 ) / 64;
413 413
414 if (var->vmode) { 414 if (var->vmode) {
415 printk(KERN_ERR "sstfb 415 printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n",
416 var->vmode); 416 var->vmode);
417 return -EINVAL; 417 return -EINVAL;
418 } 418 }
419 if (var->xres > POW2(10) || va 419 if (var->xres > POW2(10) || var->yres >= POW2(10)) {
420 printk(KERN_ERR "sstfb 420 printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
421 var->xres, va 421 var->xres, var->yres);
422 return -EINVAL; 422 return -EINVAL;
423 } 423 }
424 if (var->hsync_len > POW2(8) | 424 if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) ||
425 var->left_margin - 2 >= PO 425 var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) ||
426 vSyncOff >= POW2(12) || vB 426 vSyncOff >= POW2(12) || vBackPorch >= POW2(8) ||
427 tiles_in_X >= POW2(4) || t 427 tiles_in_X >= POW2(4) || tiles_in_X <= 0) {
428 printk(KERN_ERR "sstfb 428 printk(KERN_ERR "sstfb: Unsupported timings\n");
429 return -EINVAL; 429 return -EINVAL;
430 } 430 }
431 } 431 }
432 432
433 /* it seems that the fbi uses tiles of 433 /* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem */
434 /* FIXME: i don't like this... looks w 434 /* FIXME: i don't like this... looks wrong */
435 real_length = tiles_in_X * (IS_VOODOO 435 real_length = tiles_in_X * (IS_VOODOO2(par) ? 32 : 64 )
436 * ((var->bits_per_pixel 436 * ((var->bits_per_pixel == 16) ? 2 : 4);
437 437
438 if (real_length * yDim > info->fix.sme 438 if (real_length * yDim > info->fix.smem_len) {
439 printk(KERN_ERR "sstfb: Not en 439 printk(KERN_ERR "sstfb: Not enough video memory\n");
440 return -ENOMEM; 440 return -ENOMEM;
441 } 441 }
442 442
443 var->sync &= (FB_SYNC_HOR_HIGH_ACT | F 443 var->sync &= (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
444 var->vmode &= (FB_VMODE_INTERLACED | F 444 var->vmode &= (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE);
445 var->xoffset = 0; 445 var->xoffset = 0;
446 var->yoffset = 0; 446 var->yoffset = 0;
447 var->height = -1; 447 var->height = -1;
448 var->width = -1; 448 var->width = -1;
449 449
450 /* 450 /*
451 * correct the color bit fields 451 * correct the color bit fields
452 */ 452 */
453 /* var->{red|green|blue}.msb_right = 0 453 /* var->{red|green|blue}.msb_right = 0; */
454 454
455 switch (var->bits_per_pixel) { 455 switch (var->bits_per_pixel) {
456 case 16: /* RGB 565 LfbMode 0 456 case 16: /* RGB 565 LfbMode 0 */
457 var->red.length = 5; 457 var->red.length = 5;
458 var->green.length = 6; 458 var->green.length = 6;
459 var->blue.length = 5; 459 var->blue.length = 5;
460 var->transp.length = 0; 460 var->transp.length = 0;
461 461
462 var->red.offset = 11; 462 var->red.offset = 11;
463 var->green.offset = 5; 463 var->green.offset = 5;
464 var->blue.offset = 0; 464 var->blue.offset = 0;
465 var->transp.offset = 0; 465 var->transp.offset = 0;
466 break; 466 break;
467 default: 467 default:
468 return -EINVAL; 468 return -EINVAL;
469 } 469 }
470 return 0; 470 return 0;
471 } 471 }
472 472
473 /** 473 /**
474 * sstfb_set_par - Optional function. Al 474 * sstfb_set_par - Optional function. Alters the hardware state.
475 * @info: frame buffer structure that rep 475 * @info: frame buffer structure that represents a single frame buffer
476 */ 476 */
477 static int sstfb_set_par(struct fb_info *info) 477 static int sstfb_set_par(struct fb_info *info)
478 { 478 {
479 struct sstfb_par *par = info->par; 479 struct sstfb_par *par = info->par;
480 u32 lfbmode, fbiinit1, fbiinit2, fbiin 480 u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
481 struct pci_dev *sst_dev = par->dev; 481 struct pci_dev *sst_dev = par->dev;
482 unsigned int freq; 482 unsigned int freq;
483 int ntiles; 483 int ntiles;
484 484
485 par->hSyncOff = info->var.xres + inf 485 par->hSyncOff = info->var.xres + info->var.right_margin + info->var.left_margin;
486 486
487 par->yDim = info->var.yres; 487 par->yDim = info->var.yres;
488 par->vSyncOn = info->var.vsync_len; 488 par->vSyncOn = info->var.vsync_len;
489 par->vSyncOff = info->var.yres + inf 489 par->vSyncOff = info->var.yres + info->var.lower_margin + info->var.upper_margin;
490 par->vBackPorch = info->var.upper_marg 490 par->vBackPorch = info->var.upper_margin;
491 491
492 /* We need par->pll */ 492 /* We need par->pll */
493 sst_calc_pll(PICOS2KHZ(info->var.pixcl 493 sst_calc_pll(PICOS2KHZ(info->var.pixclock), &freq, &par->pll);
494 494
495 if (info->var.vmode & FB_VMODE_INTERLA 495 if (info->var.vmode & FB_VMODE_INTERLACED)
496 par->vBackPorch += (par->vBack 496 par->vBackPorch += (par->vBackPorch % 2);
497 if (info->var.vmode & FB_VMODE_DOUBLE) 497 if (info->var.vmode & FB_VMODE_DOUBLE) {
498 par->vBackPorch <<= 1; 498 par->vBackPorch <<= 1;
499 par->yDim <<=1; 499 par->yDim <<=1;
500 par->vSyncOn <<=1; 500 par->vSyncOn <<=1;
501 par->vSyncOff <<=1; 501 par->vSyncOff <<=1;
502 } 502 }
503 503
504 if (IS_VOODOO2(par)) { 504 if (IS_VOODOO2(par)) {
505 /* voodoo2 has 32 pixel wide t 505 /* voodoo2 has 32 pixel wide tiles , BUT stange things
506 happen with odd number of t 506 happen with odd number of tiles */
507 par->tiles_in_X = (info->var.x 507 par->tiles_in_X = (info->var.xres + 63 ) / 64 * 2;
508 } else { 508 } else {
509 /* voodoo1 has 64 pixels wide 509 /* voodoo1 has 64 pixels wide tiles. */
510 par->tiles_in_X = (info->var.x 510 par->tiles_in_X = (info->var.xres + 63 ) / 64;
511 } 511 }
512 512
513 f_ddprintk("hsync_len hSyncOff vsync_l 513 f_ddprintk("hsync_len hSyncOff vsync_len vSyncOff\n");
514 f_ddprintk("%-7d %-8d %-7d %-8d\n", 514 f_ddprintk("%-7d %-8d %-7d %-8d\n",
515 info->var.hsync_len, par->h 515 info->var.hsync_len, par->hSyncOff,
516 par->vSyncOn, par->vSyncOff 516 par->vSyncOn, par->vSyncOff);
517 f_ddprintk("left_margin upper_margin x 517 f_ddprintk("left_margin upper_margin xres yres Freq\n");
518 f_ddprintk("%-10d %-10d %-4d %-4d %-8l 518 f_ddprintk("%-10d %-10d %-4d %-4d %-8ld\n",
519 info->var.left_margin, info 519 info->var.left_margin, info->var.upper_margin,
520 info->var.xres, info->var.y 520 info->var.xres, info->var.yres, PICOS2KHZ(info->var.pixclock));
521 521
522 sst_write(NOPCMD, 0); 522 sst_write(NOPCMD, 0);
523 sst_wait_idle(); 523 sst_wait_idle();
524 pci_write_config_dword(sst_dev, PCI_IN 524 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
525 sst_set_bits(FBIINIT1, VIDEO_RESET); 525 sst_set_bits(FBIINIT1, VIDEO_RESET);
526 sst_set_bits(FBIINIT0, FBI_RESET | FIF 526 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
527 sst_unset_bits(FBIINIT2, EN_DRAM_REFRE 527 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
528 sst_wait_idle(); 528 sst_wait_idle();
529 529
530 /*sst_unset_bits (FBIINIT0, FBI_RESET) 530 /*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
531 531
532 sst_write(BACKPORCH, par->vBackPorch < 532 sst_write(BACKPORCH, par->vBackPorch << 16 | (info->var.left_margin - 2));
533 sst_write(VIDEODIMENSIONS, par->yDim < 533 sst_write(VIDEODIMENSIONS, par->yDim << 16 | (info->var.xres - 1));
534 sst_write(HSYNC, (par->hSyncOff - 1) < 534 sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (info->var.hsync_len - 1));
535 sst_write(VSYNC, par->vSyncOff < 535 sst_write(VSYNC, par->vSyncOff << 16 | par->vSyncOn);
536 536
537 fbiinit2 = sst_read(FBIINIT2); 537 fbiinit2 = sst_read(FBIINIT2);
538 fbiinit3 = sst_read(FBIINIT3); 538 fbiinit3 = sst_read(FBIINIT3);
539 539
540 /* everything is reset. we enable fbii 540 /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */
541 pci_write_config_dword(sst_dev, PCI_IN 541 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
542 PCI_EN_INIT_WR 542 PCI_EN_INIT_WR | PCI_REMAP_DAC );
543 543
544 par->dac_sw.set_vidmod(info, info->var 544 par->dac_sw.set_vidmod(info, info->var.bits_per_pixel);
545 545
546 /* set video clock */ 546 /* set video clock */
547 par->dac_sw.set_pll(info, &par->pll, V 547 par->dac_sw.set_pll(info, &par->pll, VID_CLOCK);
548 548
549 /* disable fbiinit2/3 remap */ 549 /* disable fbiinit2/3 remap */
550 pci_write_config_dword(sst_dev, PCI_IN 550 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
551 PCI_EN_INIT_WR) 551 PCI_EN_INIT_WR);
552 552
553 /* restore fbiinit2/3 */ 553 /* restore fbiinit2/3 */
554 sst_write(FBIINIT2,fbiinit2); 554 sst_write(FBIINIT2,fbiinit2);
555 sst_write(FBIINIT3,fbiinit3); 555 sst_write(FBIINIT3,fbiinit3);
556 556
557 fbiinit1 = (sst_read(FBIINIT1) & VIDEO 557 fbiinit1 = (sst_read(FBIINIT1) & VIDEO_MASK)
558 | EN_DATA_OE 558 | EN_DATA_OE
559 | EN_BLANK_OE 559 | EN_BLANK_OE
560 | EN_HVSYNC_OE 560 | EN_HVSYNC_OE
561 | EN_DCLK_OE 561 | EN_DCLK_OE
562 /* | (15 << TILES_IN_X_SHIFT) 562 /* | (15 << TILES_IN_X_SHIFT) */
563 | SEL_INPUT_VCLK_2X 563 | SEL_INPUT_VCLK_2X
564 /* | (2 << VCLK_2X_SEL_DEL_SH 564 /* | (2 << VCLK_2X_SEL_DEL_SHIFT)
565 | (2 << VCLK_DEL_SHIFT) */ 565 | (2 << VCLK_DEL_SHIFT) */;
566 /* try with vclk_in_delay =0 (bits 29:30) , vc 566 /* try with vclk_in_delay =0 (bits 29:30) , vclk_out_delay =0 (bits(27:28)
567 in (near) future set them accordingly to revi 567 in (near) future set them accordingly to revision + resolution (cf glide)
568 first understand what it stands for :) 568 first understand what it stands for :)
569 FIXME: there are some artefacts... check for 569 FIXME: there are some artefacts... check for the vclk_in_delay
570 lets try with 6ns delay in both vclk_out & in 570 lets try with 6ns delay in both vclk_out & in...
571 doh... they're still there :\ 571 doh... they're still there :\
572 */ 572 */
573 573
574 ntiles = par->tiles_in_X; 574 ntiles = par->tiles_in_X;
575 if (IS_VOODOO2(par)) { 575 if (IS_VOODOO2(par)) {
576 fbiinit1 |= ((ntiles & 0x20) > 576 fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
577 | ((ntiles & 0x1e) 577 | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT;
578 /* as the only value of importance for us in f 578 /* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
579 and as reading fbinit 6 will return crap (s 579 and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just
580 write our value. BTW due to the dac unable 580 write our value. BTW due to the dac unable to read odd number of tiles, this
581 field is always null ... */ 581 field is always null ... */
582 fbiinit6 = (ntiles & 0x1) << T 582 fbiinit6 = (ntiles & 0x1) << TILES_IN_X_LSB_SHIFT;
583 } 583 }
584 else 584 else
585 fbiinit1 |= ntiles << TILES_IN 585 fbiinit1 |= ntiles << TILES_IN_X_SHIFT;
586 586
587 switch (info->var.bits_per_pixel) { 587 switch (info->var.bits_per_pixel) {
588 case 16: 588 case 16:
589 fbiinit1 |= SEL_SOURCE_VCLK_2 589 fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL;
590 break; 590 break;
591 default: 591 default:
592 return -EINVAL; 592 return -EINVAL;
593 } 593 }
594 sst_write(FBIINIT1, fbiinit1); 594 sst_write(FBIINIT1, fbiinit1);
595 if (IS_VOODOO2(par)) { 595 if (IS_VOODOO2(par)) {
596 sst_write(FBIINIT6, fbiinit6); 596 sst_write(FBIINIT6, fbiinit6);
597 fbiinit5=sst_read(FBIINIT5) & 597 fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ;
598 if (info->var.vmode & FB_VMODE 598 if (info->var.vmode & FB_VMODE_INTERLACED)
599 fbiinit5 |= INTERLACE; 599 fbiinit5 |= INTERLACE;
600 if (info->var.vmode & FB_VMODE 600 if (info->var.vmode & FB_VMODE_DOUBLE)
601 fbiinit5 |= VDOUBLESCA 601 fbiinit5 |= VDOUBLESCAN;
602 if (info->var.sync & FB_SYNC_H 602 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
603 fbiinit5 |= HSYNC_HIGH 603 fbiinit5 |= HSYNC_HIGH;
604 if (info->var.sync & FB_SYNC_V 604 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
605 fbiinit5 |= VSYNC_HIGH 605 fbiinit5 |= VSYNC_HIGH;
606 sst_write(FBIINIT5, fbiinit5); 606 sst_write(FBIINIT5, fbiinit5);
607 } 607 }
608 sst_wait_idle(); 608 sst_wait_idle();
609 sst_unset_bits(FBIINIT1, VIDEO_RESET); 609 sst_unset_bits(FBIINIT1, VIDEO_RESET);
610 sst_unset_bits(FBIINIT0, FBI_RESET | F 610 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
611 sst_set_bits(FBIINIT2, EN_DRAM_REFRESH 611 sst_set_bits(FBIINIT2, EN_DRAM_REFRESH);
612 /* disables fbiinit writes */ 612 /* disables fbiinit writes */
613 pci_write_config_dword(sst_dev, PCI_IN 613 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
614 614
615 /* set lfbmode : set mode + front buff 615 /* set lfbmode : set mode + front buffer for reads/writes
616 + disable pipeline */ 616 + disable pipeline */
617 switch (info->var.bits_per_pixel) { 617 switch (info->var.bits_per_pixel) {
618 case 16: 618 case 16:
619 lfbmode = LFB_565; 619 lfbmode = LFB_565;
620 break; 620 break;
621 default: 621 default:
622 return -EINVAL; 622 return -EINVAL;
623 } 623 }
624 624
625 #if defined(__BIG_ENDIAN) 625 #if defined(__BIG_ENDIAN)
626 /* Enable byte-swizzle functionality i 626 /* Enable byte-swizzle functionality in hardware.
627 * With this enabled, all our read- an 627 * With this enabled, all our read- and write-accesses to
628 * the voodoo framebuffer can be done 628 * the voodoo framebuffer can be done in native format, and
629 * the hardware will automatically con 629 * the hardware will automatically convert it to little-endian.
630 * - tested on HP-PARISC, Helge Deller 630 * - tested on HP-PARISC, Helge Deller <deller@gmx.de> */
631 lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB 631 lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB_BYTE_SWIZZLE_WR |
632 LFB_WORD_SWIZZLE_RD | LFB 632 LFB_WORD_SWIZZLE_RD | LFB_BYTE_SWIZZLE_RD );
633 #endif 633 #endif
634 634
635 if (clipping) { 635 if (clipping) {
636 sst_write(LFBMODE, lfbmode | E 636 sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE);
637 /* 637 /*
638 * Set "clipping" dimensions. If clipp 638 * Set "clipping" dimensions. If clipping is disabled and
639 * writes to offscreen areas of the fr 639 * writes to offscreen areas of the framebuffer are performed,
640 * the "behaviour is undefined" (_very 640 * the "behaviour is undefined" (_very_ undefined) - Urs
641 */ 641 */
642 /* btw, it requires enabling pixel pip 642 /* btw, it requires enabling pixel pipeline in LFBMODE .
643 off screen read/writes will just wr 643 off screen read/writes will just wrap and read/print pixels
644 on screen. Ugly but not that danger 644 on screen. Ugly but not that dangerous */
645 f_ddprintk("setting clipping d 645 f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
646 info->var.xres - 1 646 info->var.xres - 1, par->yDim - 1);
647 647
648 sst_write(CLIP_LEFT_RIGHT, inf 648 sst_write(CLIP_LEFT_RIGHT, info->var.xres);
649 sst_write(CLIP_LOWY_HIGHY, par 649 sst_write(CLIP_LOWY_HIGHY, par->yDim);
650 sst_set_bits(FBZMODE, EN_CLIPP 650 sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
651 } else { 651 } else {
652 /* no clipping : direct access 652 /* no clipping : direct access, no pipeline */
653 sst_write(LFBMODE, lfbmode); 653 sst_write(LFBMODE, lfbmode);
654 } 654 }
655 return 0; 655 return 0;
656 } 656 }
657 657
658 /** 658 /**
659 * sstfb_setcolreg - Optional function. S 659 * sstfb_setcolreg - Optional function. Sets a color register.
660 * @regno: hardware colormap register 660 * @regno: hardware colormap register
661 * @red: frame buffer colormap structure 661 * @red: frame buffer colormap structure
662 * @green: The green value which can be u 662 * @green: The green value which can be up to 16 bits wide
663 * @blue: The blue value which can be up 663 * @blue: The blue value which can be up to 16 bits wide.
664 * @transp: If supported the alpha value 664 * @transp: If supported the alpha value which can be up to 16 bits wide.
665 * @info: frame buffer info structure 665 * @info: frame buffer info structure
666 */ 666 */
667 static int sstfb_setcolreg(u_int regno, u_int 667 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
668 u_int transp, struc 668 u_int transp, struct fb_info *info)
669 { 669 {
670 struct sstfb_par *par = info->par; 670 struct sstfb_par *par = info->par;
671 u32 col; 671 u32 col;
672 672
673 f_dddprintk("sstfb_setcolreg\n"); 673 f_dddprintk("sstfb_setcolreg\n");
674 f_dddprintk("%-2d rgbt: %#x, %#x, %#x, 674 f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n",
675 regno, red, green, blue, t 675 regno, red, green, blue, transp);
676 if (regno > 15) 676 if (regno > 15)
677 return 0; 677 return 0;
678 678
679 red >>= (16 - info->var.red.length) 679 red >>= (16 - info->var.red.length);
680 green >>= (16 - info->var.green.lengt 680 green >>= (16 - info->var.green.length);
681 blue >>= (16 - info->var.blue.length 681 blue >>= (16 - info->var.blue.length);
682 transp >>= (16 - info->var.transp.leng 682 transp >>= (16 - info->var.transp.length);
683 col = (red << info->var.red.offset) 683 col = (red << info->var.red.offset)
684 | (green << info->var.green.offset 684 | (green << info->var.green.offset)
685 | (blue << info->var.blue.offset) 685 | (blue << info->var.blue.offset)
686 | (transp << info->var.transp.offs 686 | (transp << info->var.transp.offset);
687 687
688 par->palette[regno] = col; 688 par->palette[regno] = col;
689 689
690 return 0; 690 return 0;
691 } 691 }
692 692
693 static void sstfb_setvgapass( struct fb_info * 693 static void sstfb_setvgapass( struct fb_info *info, int enable )
694 { 694 {
695 struct sstfb_par *par = info->par; 695 struct sstfb_par *par = info->par;
696 struct pci_dev *sst_dev = par->dev; 696 struct pci_dev *sst_dev = par->dev;
697 u32 fbiinit0, tmp; 697 u32 fbiinit0, tmp;
698 698
699 enable = enable ? 1:0; 699 enable = enable ? 1:0;
700 if (par->vgapass == enable) 700 if (par->vgapass == enable)
701 return; 701 return;
702 par->vgapass = enable; 702 par->vgapass = enable;
703 703
704 pci_read_config_dword(sst_dev, PCI_INI 704 pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
705 pci_write_config_dword(sst_dev, PCI_IN 705 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
706 tmp | PCI_EN_IN 706 tmp | PCI_EN_INIT_WR );
707 fbiinit0 = sst_read (FBIINIT0); 707 fbiinit0 = sst_read (FBIINIT0);
708 if (par->vgapass) { 708 if (par->vgapass) {
709 sst_write(FBIINIT0, fbiinit0 & 709 sst_write(FBIINIT0, fbiinit0 & ~DIS_VGA_PASSTHROUGH);
710 printk(KERN_INFO "fb%d: Enabli 710 printk(KERN_INFO "fb%d: Enabling VGA pass-through\n", info->node );
711 } else { 711 } else {
712 sst_write(FBIINIT0, fbiinit0 | 712 sst_write(FBIINIT0, fbiinit0 | DIS_VGA_PASSTHROUGH);
713 printk(KERN_INFO "fb%d: Disabl 713 printk(KERN_INFO "fb%d: Disabling VGA pass-through\n", info->node );
714 } 714 }
715 pci_write_config_dword(sst_dev, PCI_IN 715 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
716 } 716 }
717 717
718 static ssize_t store_vgapass(struct device *de 718 static ssize_t store_vgapass(struct device *device, struct device_attribute *attr,
719 const char *buf, size_ 719 const char *buf, size_t count)
720 { 720 {
721 struct fb_info *info = dev_get_drvdata 721 struct fb_info *info = dev_get_drvdata(device);
722 char ** last = NULL; 722 char ** last = NULL;
723 int val; 723 int val;
724 724
725 val = simple_strtoul(buf, last, 0); 725 val = simple_strtoul(buf, last, 0);
726 sstfb_setvgapass(info, val); 726 sstfb_setvgapass(info, val);
727 727
728 return count; 728 return count;
729 } 729 }
730 730
731 static ssize_t show_vgapass(struct device *dev 731 static ssize_t show_vgapass(struct device *device, struct device_attribute *attr,
732 char *buf) 732 char *buf)
733 { 733 {
734 struct fb_info *info = dev_get_drvdata 734 struct fb_info *info = dev_get_drvdata(device);
735 struct sstfb_par *par = info->par; 735 struct sstfb_par *par = info->par;
736 return snprintf(buf, PAGE_SIZE, "%d\n" 736 return snprintf(buf, PAGE_SIZE, "%d\n", par->vgapass);
737 } 737 }
738 738
739 static struct device_attribute device_attrs[] 739 static struct device_attribute device_attrs[] = {
740 __ATTR(vgapass, S_IRUGO|S_IWUSR, show_ 740 __ATTR(vgapass, S_IRUGO|S_IWUSR, show_vgapass, store_vgapass)
741 }; 741 };
742 742
743 static int sstfb_ioctl(struct fb_info *info, u 743 static int sstfb_ioctl(struct fb_info *info, unsigned int cmd,
744 unsigned long arg) 744 unsigned long arg)
745 { 745 {
746 struct sstfb_par *par; 746 struct sstfb_par *par;
747 u32 val; 747 u32 val;
748 748
749 switch (cmd) { 749 switch (cmd) {
750 /* set/get VGA pass_through mode */ 750 /* set/get VGA pass_through mode */
751 case SSTFB_SET_VGAPASS: 751 case SSTFB_SET_VGAPASS:
752 if (copy_from_user(&val, (void 752 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
753 return -EFAULT; 753 return -EFAULT;
754 sstfb_setvgapass(info, val); 754 sstfb_setvgapass(info, val);
755 return 0; 755 return 0;
756 case SSTFB_GET_VGAPASS: 756 case SSTFB_GET_VGAPASS:
757 par = info->par; 757 par = info->par;
758 val = par->vgapass; 758 val = par->vgapass;
759 if (copy_to_user((void __user 759 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
760 return -EFAULT; 760 return -EFAULT;
761 return 0; 761 return 0;
762 } 762 }
763 763
764 return -EINVAL; 764 return -EINVAL;
765 } 765 }
766 766
767 767
768 /* 768 /*
769 * Screen-to-Screen BitBlt 2D command (for the 769 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) - Voodoo2 only
770 */ 770 */
771 #if 0 771 #if 0
772 static void sstfb_copyarea(struct fb_info *inf 772 static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
773 { 773 {
774 struct sstfb_par *par = info->par; 774 struct sstfb_par *par = info->par;
775 u32 stride = info->fix.line_length; 775 u32 stride = info->fix.line_length;
776 776
777 if (!IS_VOODOO2(par)) 777 if (!IS_VOODOO2(par))
778 return; 778 return;
779 779
780 sst_write(BLTSRCBASEADDR, 0); 780 sst_write(BLTSRCBASEADDR, 0);
781 sst_write(BLTDSTBASEADDR, 0); 781 sst_write(BLTDSTBASEADDR, 0);
782 sst_write(BLTROP, BLTROP_COPY); 782 sst_write(BLTROP, BLTROP_COPY);
783 sst_write(BLTXYSTRIDES, stride | (stri 783 sst_write(BLTXYSTRIDES, stride | (stride << 16));
784 sst_write(BLTSRCXY, area->sx | (area-> 784 sst_write(BLTSRCXY, area->sx | (area->sy << 16));
785 sst_write(BLTDSTXY, area->dx | (area-> 785 sst_write(BLTDSTXY, area->dx | (area->dy << 16));
786 sst_write(BLTSIZE, area->width | (area 786 sst_write(BLTSIZE, area->width | (area->height << 16));
787 sst_write(BLTCOMMAND, BLT_SCR2SCR_BITB 787 sst_write(BLTCOMMAND, BLT_SCR2SCR_BITBLT | LAUNCH_BITBLT |
788 (BLT_16BPP_FMT << 3) /* | BIT( 788 (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) );
789 sst_wait_idle(); 789 sst_wait_idle();
790 } 790 }
791 #endif 791 #endif
792 792
793 793
794 /* 794 /*
795 * FillRect 2D command (solidfill or invert (v 795 * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
796 */ 796 */
797 #if 0 797 #if 0
798 static void sstfb_fillrect(struct fb_info *inf 798 static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
799 { 799 {
800 struct sstfb_par *par = info->par; 800 struct sstfb_par *par = info->par;
801 u32 stride = info->fix.line_length; 801 u32 stride = info->fix.line_length;
802 802
803 if (!IS_VOODOO2(par)) 803 if (!IS_VOODOO2(par))
804 return; 804 return;
805 805
806 sst_write(BLTCLIPX, info->var.xres); 806 sst_write(BLTCLIPX, info->var.xres);
807 sst_write(BLTCLIPY, info->var.yres); 807 sst_write(BLTCLIPY, info->var.yres);
808 808
809 sst_write(BLTDSTBASEADDR, 0); 809 sst_write(BLTDSTBASEADDR, 0);
810 sst_write(BLTCOLOR, rect->color); 810 sst_write(BLTCOLOR, rect->color);
811 sst_write(BLTROP, rect->rop == ROP_COP 811 sst_write(BLTROP, rect->rop == ROP_COPY ? BLTROP_COPY : BLTROP_XOR);
812 sst_write(BLTXYSTRIDES, stride | (stri 812 sst_write(BLTXYSTRIDES, stride | (stride << 16));
813 sst_write(BLTDSTXY, rect->dx | (rect-> 813 sst_write(BLTDSTXY, rect->dx | (rect->dy << 16));
814 sst_write(BLTSIZE, rect->width | (rect 814 sst_write(BLTSIZE, rect->width | (rect->height << 16));
815 sst_write(BLTCOMMAND, BLT_RECFILL_BITB 815 sst_write(BLTCOMMAND, BLT_RECFILL_BITBLT | LAUNCH_BITBLT
816 | (BLT_16BPP_FMT << 3) /* | B 816 | (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) );
817 sst_wait_idle(); 817 sst_wait_idle();
818 } 818 }
819 #endif 819 #endif
820 820
821 821
822 822
823 /* 823 /*
824 * get lfb size 824 * get lfb size
825 */ 825 */
826 static int __devinit sst_get_memsize(struct fb 826 static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
827 { 827 {
828 u8 __iomem *fbbase_virt = info->screen 828 u8 __iomem *fbbase_virt = info->screen_base;
829 829
830 /* force memsize */ 830 /* force memsize */
831 if (mem >= 1 && mem <= 4) { 831 if (mem >= 1 && mem <= 4) {
832 *memsize = (mem * 0x100000); 832 *memsize = (mem * 0x100000);
833 printk(KERN_INFO "supplied mem 833 printk(KERN_INFO "supplied memsize: %#x\n", *memsize);
834 return 1; 834 return 1;
835 } 835 }
836 836
837 writel(0xdeadbeef, fbbase_virt); 837 writel(0xdeadbeef, fbbase_virt);
838 writel(0xdeadbeef, fbbase_virt+0x10000 838 writel(0xdeadbeef, fbbase_virt+0x100000);
839 writel(0xdeadbeef, fbbase_virt+0x20000 839 writel(0xdeadbeef, fbbase_virt+0x200000);
840 f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: % 840 f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: %#x\n",
841 readl(fbbase_virt), readl(f 841 readl(fbbase_virt), readl(fbbase_virt + 0x100000),
842 readl(fbbase_virt + 0x20000 842 readl(fbbase_virt + 0x200000));
843 843
844 writel(0xabcdef01, fbbase_virt); 844 writel(0xabcdef01, fbbase_virt);
845 845
846 f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: % 846 f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: %#x\n",
847 readl(fbbase_virt), readl(f 847 readl(fbbase_virt), readl(fbbase_virt + 0x100000),
848 readl(fbbase_virt + 0x20000 848 readl(fbbase_virt + 0x200000));
849 849
850 /* checks for 4mb lfb, then 2, then de 850 /* checks for 4mb lfb, then 2, then defaults to 1 */
851 if (readl(fbbase_virt + 0x200000) == 0 851 if (readl(fbbase_virt + 0x200000) == 0xdeadbeef)
852 *memsize = 0x400000; 852 *memsize = 0x400000;
853 else if (readl(fbbase_virt + 0x100000) 853 else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef)
854 *memsize = 0x200000; 854 *memsize = 0x200000;
855 else 855 else
856 *memsize = 0x100000; 856 *memsize = 0x100000;
857 f_ddprintk("detected memsize: %dMB\n", 857 f_ddprintk("detected memsize: %dMB\n", *memsize >> 20);
858 return 1; 858 return 1;
859 } 859 }
860 860
861 861
862 /* 862 /*
863 * DAC detection routines 863 * DAC detection routines
864 */ 864 */
865 865
866 /* fbi should be idle, and fifo emty and mem d 866 /* fbi should be idle, and fifo emty and mem disabled */
867 /* supposed to detect AT&T ATT20C409 and Ti TV 867 /* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
868 868
869 static int __devinit sst_detect_att(struct fb_ 869 static int __devinit sst_detect_att(struct fb_info *info)
870 { 870 {
871 struct sstfb_par *par = info->par; 871 struct sstfb_par *par = info->par;
872 int i, mir, dir; 872 int i, mir, dir;
873 873
874 for (i = 0; i < 3; i++) { 874 for (i = 0; i < 3; i++) {
875 sst_dac_write(DACREG_WMA, 0); 875 sst_dac_write(DACREG_WMA, 0); /* backdoor */
876 sst_dac_read(DACREG_RMR); 876 sst_dac_read(DACREG_RMR); /* read 4 times RMR */
877 sst_dac_read(DACREG_RMR); 877 sst_dac_read(DACREG_RMR);
878 sst_dac_read(DACREG_RMR); 878 sst_dac_read(DACREG_RMR);
879 sst_dac_read(DACREG_RMR); 879 sst_dac_read(DACREG_RMR);
880 /* the fifth time, CR0 is rea 880 /* the fifth time, CR0 is read */
881 sst_dac_read(DACREG_RMR); 881 sst_dac_read(DACREG_RMR);
882 /* the 6th, manufacturer id re 882 /* the 6th, manufacturer id register */
883 mir = sst_dac_read(DACREG_RMR) 883 mir = sst_dac_read(DACREG_RMR);
884 /*the 7th, device ID register 884 /*the 7th, device ID register */
885 dir = sst_dac_read(DACREG_RMR) 885 dir = sst_dac_read(DACREG_RMR);
886 f_ddprintk("mir: %#x, dir: %#x 886 f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
887 if (mir == DACREG_MIR_ATT && d 887 if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) {
888 return 1; 888 return 1;
889 } 889 }
890 } 890 }
891 return 0; 891 return 0;
892 } 892 }
893 893
894 static int __devinit sst_detect_ti(struct fb_i 894 static int __devinit sst_detect_ti(struct fb_info *info)
895 { 895 {
896 struct sstfb_par *par = info->par; 896 struct sstfb_par *par = info->par;
897 int i, mir, dir; 897 int i, mir, dir;
898 898
899 for (i = 0; i<3; i++) { 899 for (i = 0; i<3; i++) {
900 sst_dac_write(DACREG_WMA, 0); 900 sst_dac_write(DACREG_WMA, 0); /* backdoor */
901 sst_dac_read(DACREG_RMR); 901 sst_dac_read(DACREG_RMR); /* read 4 times RMR */
902 sst_dac_read(DACREG_RMR); 902 sst_dac_read(DACREG_RMR);
903 sst_dac_read(DACREG_RMR); 903 sst_dac_read(DACREG_RMR);
904 sst_dac_read(DACREG_RMR); 904 sst_dac_read(DACREG_RMR);
905 /* the fifth time, CR0 is rea 905 /* the fifth time, CR0 is read */
906 sst_dac_read(DACREG_RMR); 906 sst_dac_read(DACREG_RMR);
907 /* the 6th, manufacturer id re 907 /* the 6th, manufacturer id register */
908 mir = sst_dac_read(DACREG_RMR) 908 mir = sst_dac_read(DACREG_RMR);
909 /*the 7th, device ID register 909 /*the 7th, device ID register */
910 dir = sst_dac_read(DACREG_RMR) 910 dir = sst_dac_read(DACREG_RMR);
911 f_ddprintk("mir: %#x, dir: %#x 911 f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
912 if ((mir == DACREG_MIR_TI ) && 912 if ((mir == DACREG_MIR_TI ) && (dir == DACREG_DIR_TI)) {
913 return 1; 913 return 1;
914 } 914 }
915 } 915 }
916 return 0; 916 return 0;
917 } 917 }
918 918
919 /* 919 /*
920 * try to detect ICS5342 ramdac 920 * try to detect ICS5342 ramdac
921 * we get the 1st byte (M value) of preset f1, 921 * we get the 1st byte (M value) of preset f1,f7 and fB
922 * why those 3 ? mmmh... for now, i'll do it t 922 * why those 3 ? mmmh... for now, i'll do it the glide way...
923 * and ask questions later. anyway, it seems t 923 * and ask questions later. anyway, it seems that all the freq registers are
924 * realy at their default state (cf specs) so 924 * realy at their default state (cf specs) so i ask again, why those 3 regs ?
925 * mmmmh.. it seems that's much more ugly than 925 * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for
926 * pll programming, so in fact, we *hope* that 926 * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be
927 * touched... 927 * touched...
928 * is it realy safe ? how can i reset this ram 928 * is it realy safe ? how can i reset this ramdac ? geee...
929 */ 929 */
930 static int __devinit sst_detect_ics(struct fb_ 930 static int __devinit sst_detect_ics(struct fb_info *info)
931 { 931 {
932 struct sstfb_par *par = info->par; 932 struct sstfb_par *par = info->par;
933 int m_clk0_1, m_clk0_7, m_clk1_b; 933 int m_clk0_1, m_clk0_7, m_clk1_b;
934 int n_clk0_1, n_clk0_7, n_clk1_b; 934 int n_clk0_1, n_clk0_7, n_clk1_b;
935 int i; 935 int i;
936 936
937 for (i = 0; i<5; i++ ) { 937 for (i = 0; i<5; i++ ) {
938 sst_dac_write(DACREG_ICS_PLLRM 938 sst_dac_write(DACREG_ICS_PLLRMA, 0x1); /* f1 */
939 m_clk0_1 = sst_dac_read(DACREG 939 m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
940 n_clk0_1 = sst_dac_read(DACREG 940 n_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
941 sst_dac_write(DACREG_ICS_PLLRM 941 sst_dac_write(DACREG_ICS_PLLRMA, 0x7); /* f7 */
942 m_clk0_7 = sst_dac_read(DACREG 942 m_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
943 n_clk0_7 = sst_dac_read(DACREG 943 n_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
944 sst_dac_write(DACREG_ICS_PLLRM 944 sst_dac_write(DACREG_ICS_PLLRMA, 0xb); /* fB */
945 m_clk1_b= sst_dac_read(DACREG_ 945 m_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
946 n_clk1_b= sst_dac_read(DACREG_ 946 n_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
947 f_ddprintk("m_clk0_1: %#x, m_c 947 f_ddprintk("m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#x\n",
948 m_clk0_1, m_clk0_7, m_ 948 m_clk0_1, m_clk0_7, m_clk1_b);
949 f_ddprintk("n_clk0_1: %#x, n_c 949 f_ddprintk("n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#x\n",
950 n_clk0_1, n_clk0_7, n_ 950 n_clk0_1, n_clk0_7, n_clk1_b);
951 if (( m_clk0_1 == DACREG_ICS 951 if (( m_clk0_1 == DACREG_ICS_PLL_CLK0_1_INI)
952 && (m_clk0_7 == DACREG_ICS 952 && (m_clk0_7 == DACREG_ICS_PLL_CLK0_7_INI)
953 && (m_clk1_b == DACREG_ICS 953 && (m_clk1_b == DACREG_ICS_PLL_CLK1_B_INI)) {
954 return 1; 954 return 1;
955 } 955 }
956 } 956 }
957 return 0; 957 return 0;
958 } 958 }
959 959
960 960
961 /* 961 /*
962 * gfx, video, pci fifo should be reset, dram 962 * gfx, video, pci fifo should be reset, dram refresh disabled
963 * see detect_dac 963 * see detect_dac
964 */ 964 */
965 965
966 static int sst_set_pll_att_ti(struct fb_info * 966 static int sst_set_pll_att_ti(struct fb_info *info,
967 const struct pll_timing *t, co 967 const struct pll_timing *t, const int clock)
968 { 968 {
969 struct sstfb_par *par = info->par; 969 struct sstfb_par *par = info->par;
970 u8 cr0, cc; 970 u8 cr0, cc;
971 971
972 /* enable indexed mode */ 972 /* enable indexed mode */
973 sst_dac_write(DACREG_WMA, 0); /* bac 973 sst_dac_write(DACREG_WMA, 0); /* backdoor */
974 sst_dac_read(DACREG_RMR); /* 1 t 974 sst_dac_read(DACREG_RMR); /* 1 time: RMR */
975 sst_dac_read(DACREG_RMR); /* 2 R 975 sst_dac_read(DACREG_RMR); /* 2 RMR */
976 sst_dac_read(DACREG_RMR); /* 3 / 976 sst_dac_read(DACREG_RMR); /* 3 // */
977 sst_dac_read(DACREG_RMR); /* 4 / 977 sst_dac_read(DACREG_RMR); /* 4 // */
978 cr0 = sst_dac_read(DACREG_RMR); /* 5 C 978 cr0 = sst_dac_read(DACREG_RMR); /* 5 CR0 */
979 979
980 sst_dac_write(DACREG_WMA, 0); 980 sst_dac_write(DACREG_WMA, 0);
981 sst_dac_read(DACREG_RMR); 981 sst_dac_read(DACREG_RMR);
982 sst_dac_read(DACREG_RMR); 982 sst_dac_read(DACREG_RMR);
983 sst_dac_read(DACREG_RMR); 983 sst_dac_read(DACREG_RMR);
984 sst_dac_read(DACREG_RMR); 984 sst_dac_read(DACREG_RMR);
985 sst_dac_write(DACREG_RMR, (cr0 & 0xf0) 985 sst_dac_write(DACREG_RMR, (cr0 & 0xf0)
986 | DACREG_CR0_EN_INDEXED 986 | DACREG_CR0_EN_INDEXED
987 | DACREG_CR0_8BIT 987 | DACREG_CR0_8BIT
988 | DACREG_CR0_PWDOWN ); 988 | DACREG_CR0_PWDOWN );
989 /* so, now we are in indexed mode . du 989 /* so, now we are in indexed mode . dunno if its common, but
990 i find this way of doing things a l 990 i find this way of doing things a little bit weird :p */
991 991
992 udelay(300); 992 udelay(300);
993 cc = dac_i_read(DACREG_CC_I); 993 cc = dac_i_read(DACREG_CC_I);
994 switch (clock) { 994 switch (clock) {
995 case VID_CLOCK: 995 case VID_CLOCK:
996 dac_i_write(DACREG_AC0_I, t->m 996 dac_i_write(DACREG_AC0_I, t->m);
997 dac_i_write(DACREG_AC1_I, t->p 997 dac_i_write(DACREG_AC1_I, t->p << 6 | t->n);
998 dac_i_write(DACREG_CC_I, 998 dac_i_write(DACREG_CC_I,
999 (cc & 0x0f) | DACR 999 (cc & 0x0f) | DACREG_CC_CLKA | DACREG_CC_CLKA_C);
1000 break; 1000 break;
1001 case GFX_CLOCK: 1001 case GFX_CLOCK:
1002 dac_i_write(DACREG_BD0_I, t-> 1002 dac_i_write(DACREG_BD0_I, t->m);
1003 dac_i_write(DACREG_BD1_I, t-> 1003 dac_i_write(DACREG_BD1_I, t->p << 6 | t->n);
1004 dac_i_write(DACREG_CC_I, 1004 dac_i_write(DACREG_CC_I,
1005 (cc & 0xf0) | DAC 1005 (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D);
1006 break; 1006 break;
1007 default: 1007 default:
1008 dprintk("%s: wrong clock code 1008 dprintk("%s: wrong clock code '%d'\n",
1009 __func__, clock); !! 1009 __FUNCTION__, clock);
1010 return 0; 1010 return 0;
1011 } 1011 }
1012 udelay(300); 1012 udelay(300);
1013 1013
1014 /* power up the dac & return to "norm 1014 /* power up the dac & return to "normal" non-indexed mode */
1015 dac_i_write(DACREG_CR0_I, 1015 dac_i_write(DACREG_CR0_I,
1016 cr0 & ~DACREG_CR0_PWDOWN 1016 cr0 & ~DACREG_CR0_PWDOWN & ~DACREG_CR0_EN_INDEXED);
1017 return 1; 1017 return 1;
1018 } 1018 }
1019 1019
1020 static int sst_set_pll_ics(struct fb_info *in 1020 static int sst_set_pll_ics(struct fb_info *info,
1021 const struct pll_timing *t, c 1021 const struct pll_timing *t, const int clock)
1022 { 1022 {
1023 struct sstfb_par *par = info->par; 1023 struct sstfb_par *par = info->par;
1024 u8 pll_ctrl; 1024 u8 pll_ctrl;
1025 1025
1026 sst_dac_write(DACREG_ICS_PLLRMA, DACR 1026 sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
1027 pll_ctrl = sst_dac_read(DACREG_ICS_PL 1027 pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA);
1028 switch(clock) { 1028 switch(clock) {
1029 case VID_CLOCK: 1029 case VID_CLOCK:
1030 sst_dac_write(DACREG_ICS_PLLW 1030 sst_dac_write(DACREG_ICS_PLLWMA, 0x0); /* CLK0, f0 */
1031 sst_dac_write(DACREG_ICS_PLLD 1031 sst_dac_write(DACREG_ICS_PLLDATA, t->m);
1032 sst_dac_write(DACREG_ICS_PLLD 1032 sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
1033 /* selects freq f0 for clock 1033 /* selects freq f0 for clock 0 */
1034 sst_dac_write(DACREG_ICS_PLLW 1034 sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
1035 sst_dac_write(DACREG_ICS_PLLD 1035 sst_dac_write(DACREG_ICS_PLLDATA,
1036 (pll_ctrl & 0xd 1036 (pll_ctrl & 0xd8)
1037 | DACREG_ICS_CL 1037 | DACREG_ICS_CLK0
1038 | DACREG_ICS_CL 1038 | DACREG_ICS_CLK0_0);
1039 break; 1039 break;
1040 case GFX_CLOCK : 1040 case GFX_CLOCK :
1041 sst_dac_write(DACREG_ICS_PLLW 1041 sst_dac_write(DACREG_ICS_PLLWMA, 0xa); /* CLK1, fA */
1042 sst_dac_write(DACREG_ICS_PLLD 1042 sst_dac_write(DACREG_ICS_PLLDATA, t->m);
1043 sst_dac_write(DACREG_ICS_PLLD 1043 sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
1044 /* selects freq fA for clock 1044 /* selects freq fA for clock 1 */
1045 sst_dac_write(DACREG_ICS_PLLW 1045 sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
1046 sst_dac_write(DACREG_ICS_PLLD 1046 sst_dac_write(DACREG_ICS_PLLDATA,
1047 (pll_ctrl & 0xe 1047 (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A);
1048 break; 1048 break;
1049 default: 1049 default:
1050 dprintk("%s: wrong clock code 1050 dprintk("%s: wrong clock code '%d'\n",
1051 __func__, clock); !! 1051 __FUNCTION__, clock);
1052 return 0; 1052 return 0;
1053 } 1053 }
1054 udelay(300); 1054 udelay(300);
1055 return 1; 1055 return 1;
1056 } 1056 }
1057 1057
1058 static void sst_set_vidmod_att_ti(struct fb_i 1058 static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
1059 { 1059 {
1060 struct sstfb_par *par = info->par; 1060 struct sstfb_par *par = info->par;
1061 u8 cr0; 1061 u8 cr0;
1062 1062
1063 sst_dac_write(DACREG_WMA, 0); /* ba 1063 sst_dac_write(DACREG_WMA, 0); /* backdoor */
1064 sst_dac_read(DACREG_RMR); /* re 1064 sst_dac_read(DACREG_RMR); /* read 4 times RMR */
1065 sst_dac_read(DACREG_RMR); 1065 sst_dac_read(DACREG_RMR);
1066 sst_dac_read(DACREG_RMR); 1066 sst_dac_read(DACREG_RMR);
1067 sst_dac_read(DACREG_RMR); 1067 sst_dac_read(DACREG_RMR);
1068 /* the fifth time, CR0 is read */ 1068 /* the fifth time, CR0 is read */
1069 cr0 = sst_dac_read(DACREG_RMR); 1069 cr0 = sst_dac_read(DACREG_RMR);
1070 1070
1071 sst_dac_write(DACREG_WMA, 0); /* ba 1071 sst_dac_write(DACREG_WMA, 0); /* backdoor */
1072 sst_dac_read(DACREG_RMR); /* re 1072 sst_dac_read(DACREG_RMR); /* read 4 times RMR */
1073 sst_dac_read(DACREG_RMR); 1073 sst_dac_read(DACREG_RMR);
1074 sst_dac_read(DACREG_RMR); 1074 sst_dac_read(DACREG_RMR);
1075 sst_dac_read(DACREG_RMR); 1075 sst_dac_read(DACREG_RMR);
1076 /* cr0 */ 1076 /* cr0 */
1077 switch(bpp) { 1077 switch(bpp) {
1078 case 16: 1078 case 16:
1079 sst_dac_write(DACREG_RMR, (cr 1079 sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
1080 break; 1080 break;
1081 default: 1081 default:
1082 dprintk("%s: bad depth '%u'\n !! 1082 dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
1083 break; 1083 break;
1084 } 1084 }
1085 } 1085 }
1086 1086
1087 static void sst_set_vidmod_ics(struct fb_info 1087 static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
1088 { 1088 {
1089 struct sstfb_par *par = info->par; 1089 struct sstfb_par *par = info->par;
1090 1090
1091 switch(bpp) { 1091 switch(bpp) {
1092 case 16: 1092 case 16:
1093 sst_dac_write(DACREG_ICS_CMD, 1093 sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
1094 break; 1094 break;
1095 default: 1095 default:
1096 dprintk("%s: bad depth '%u'\n !! 1096 dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
1097 break; 1097 break;
1098 } 1098 }
1099 } 1099 }
1100 1100
1101 /* 1101 /*
1102 * detect dac type 1102 * detect dac type
1103 * prerequisite : write to FbiInitx enabled, 1103 * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
1104 * dram refresh disabled, FbiInit remaped. 1104 * dram refresh disabled, FbiInit remaped.
1105 * TODO: mmh.. maybe i shoud put the "prerequ 1105 * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
1106 */ 1106 */
1107 1107
1108 1108
1109 static struct dac_switch dacs[] __devinitdata 1109 static struct dac_switch dacs[] __devinitdata = {
1110 { .name = "TI TVP3409 1110 { .name = "TI TVP3409",
1111 .detect = sst_detect_ 1111 .detect = sst_detect_ti,
1112 .set_pll = sst_set_pll 1112 .set_pll = sst_set_pll_att_ti,
1113 .set_vidmod = sst_set_vid 1113 .set_vidmod = sst_set_vidmod_att_ti },
1114 1114
1115 { .name = "AT&T ATT20 1115 { .name = "AT&T ATT20C409",
1116 .detect = sst_detect_ 1116 .detect = sst_detect_att,
1117 .set_pll = sst_set_pll 1117 .set_pll = sst_set_pll_att_ti,
1118 .set_vidmod = sst_set_vid 1118 .set_vidmod = sst_set_vidmod_att_ti },
1119 { .name = "ICS ICS534 1119 { .name = "ICS ICS5342",
1120 .detect = sst_detect_ 1120 .detect = sst_detect_ics,
1121 .set_pll = sst_set_pll 1121 .set_pll = sst_set_pll_ics,
1122 .set_vidmod = sst_set_vid 1122 .set_vidmod = sst_set_vidmod_ics },
1123 }; 1123 };
1124 1124
1125 static int __devinit sst_detect_dactype(struc 1125 static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
1126 { 1126 {
1127 int i, ret = 0; 1127 int i, ret = 0;
1128 1128
1129 for (i = 0; i < ARRAY_SIZE(dacs); i++ 1129 for (i = 0; i < ARRAY_SIZE(dacs); i++) {
1130 ret = dacs[i].detect(info); 1130 ret = dacs[i].detect(info);
1131 if (ret) 1131 if (ret)
1132 break; 1132 break;
1133 } 1133 }
1134 if (!ret) 1134 if (!ret)
1135 return 0; 1135 return 0;
1136 f_dprintk("%s found %s\n", __func__, !! 1136 f_dprintk("%s found %s\n", __FUNCTION__, dacs[i].name);
1137 par->dac_sw = dacs[i]; 1137 par->dac_sw = dacs[i];
1138 return 1; 1138 return 1;
1139 } 1139 }
1140 1140
1141 /* 1141 /*
1142 * Internal Routines 1142 * Internal Routines
1143 */ 1143 */
1144 static int __devinit sst_init(struct fb_info 1144 static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
1145 { 1145 {
1146 u32 fbiinit0, fbiinit1, fbiinit4; 1146 u32 fbiinit0, fbiinit1, fbiinit4;
1147 struct pci_dev *dev = par->dev; 1147 struct pci_dev *dev = par->dev;
1148 struct pll_timing gfx_timings; 1148 struct pll_timing gfx_timings;
1149 struct sst_spec *spec; 1149 struct sst_spec *spec;
1150 int Fout; 1150 int Fout;
1151 int gfx_clock; 1151 int gfx_clock;
1152 1152
1153 spec = &voodoo_spec[par->type]; 1153 spec = &voodoo_spec[par->type];
1154 f_ddprintk(" fbiinit0 fbiinit1 fb 1154 f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 "
1155 " fbiinit6\n"); 1155 " fbiinit6\n");
1156 f_ddprintk("%0#10x %0#10x %0#10x %0#1 1156 f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",
1157 sst_read(FBIINIT0), sst_r 1157 sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),
1158 sst_read(FBIINIT3), sst_r 1158 sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));
1159 /* disable video clock */ 1159 /* disable video clock */
1160 pci_write_config_dword(dev, PCI_VCLK_ 1160 pci_write_config_dword(dev, PCI_VCLK_DISABLE, 0);
1161 1161
1162 /* enable writing to init registers, 1162 /* enable writing to init registers, disable pci fifo */
1163 pci_write_config_dword(dev, PCI_INIT_ 1163 pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
1164 /* reset video */ 1164 /* reset video */
1165 sst_set_bits(FBIINIT1, VIDEO_RESET); 1165 sst_set_bits(FBIINIT1, VIDEO_RESET);
1166 sst_wait_idle(); 1166 sst_wait_idle();
1167 /* reset gfx + pci fifo */ 1167 /* reset gfx + pci fifo */
1168 sst_set_bits(FBIINIT0, FBI_RESET | FI 1168 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
1169 sst_wait_idle(); 1169 sst_wait_idle();
1170 1170
1171 /* unreset fifo */ 1171 /* unreset fifo */
1172 /*sst_unset_bits(FBIINIT0, FIFO_RESET 1172 /*sst_unset_bits(FBIINIT0, FIFO_RESET);
1173 sst_wait_idle();*/ 1173 sst_wait_idle();*/
1174 /* unreset FBI */ 1174 /* unreset FBI */
1175 /*sst_unset_bits(FBIINIT0, FBI_RESET) 1175 /*sst_unset_bits(FBIINIT0, FBI_RESET);
1176 sst_wait_idle();*/ 1176 sst_wait_idle();*/
1177 1177
1178 /* disable dram refresh */ 1178 /* disable dram refresh */
1179 sst_unset_bits(FBIINIT2, EN_DRAM_REFR 1179 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
1180 sst_wait_idle(); 1180 sst_wait_idle();
1181 /* remap fbinit2/3 to dac */ 1181 /* remap fbinit2/3 to dac */
1182 pci_write_config_dword(dev, PCI_INIT_ 1182 pci_write_config_dword(dev, PCI_INIT_ENABLE,
1183 PCI_EN_INIT_W 1183 PCI_EN_INIT_WR | PCI_REMAP_DAC );
1184 /* detect dac type */ 1184 /* detect dac type */
1185 if (!sst_detect_dactype(info, par)) { 1185 if (!sst_detect_dactype(info, par)) {
1186 printk(KERN_ERR "sstfb: unkno 1186 printk(KERN_ERR "sstfb: unknown dac type.\n");
1187 //FIXME watch it: we are not 1187 //FIXME watch it: we are not in a safe state, bad bad bad.
1188 return 0; 1188 return 0;
1189 } 1189 }
1190 1190
1191 /* set graphic clock */ 1191 /* set graphic clock */
1192 gfx_clock = spec->default_gfx_clock; 1192 gfx_clock = spec->default_gfx_clock;
1193 if ((gfxclk >10 ) && (gfxclk < spec-> 1193 if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
1194 printk(KERN_INFO "sstfb: Usin 1194 printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
1195 gfx_clock = gfxclk *1000; 1195 gfx_clock = gfxclk *1000;
1196 } else if (gfxclk) { 1196 } else if (gfxclk) {
1197 printk(KERN_WARNING "sstfb: % 1197 printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
1198 } 1198 }
1199 1199
1200 sst_calc_pll(gfx_clock, &Fout, &gfx_t 1200 sst_calc_pll(gfx_clock, &Fout, &gfx_timings);
1201 par->dac_sw.set_pll(info, &gfx_timing 1201 par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
1202 1202
1203 /* disable fbiinit remap */ 1203 /* disable fbiinit remap */
1204 pci_write_config_dword(dev, PCI_INIT_ 1204 pci_write_config_dword(dev, PCI_INIT_ENABLE,
1205 PCI_EN_INIT_WR 1205 PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
1206 /* defaults init registers */ 1206 /* defaults init registers */
1207 /* FbiInit0: unreset gfx, unreset fif 1207 /* FbiInit0: unreset gfx, unreset fifo */
1208 fbiinit0 = FBIINIT0_DEFAULT; 1208 fbiinit0 = FBIINIT0_DEFAULT;
1209 fbiinit1 = FBIINIT1_DEFAULT; 1209 fbiinit1 = FBIINIT1_DEFAULT;
1210 fbiinit4 = FBIINIT4_DEFAULT; 1210 fbiinit4 = FBIINIT4_DEFAULT;
1211 par->vgapass = vgapass; 1211 par->vgapass = vgapass;
1212 if (par->vgapass) 1212 if (par->vgapass)
1213 fbiinit0 &= ~DIS_VGA_PASSTHRO 1213 fbiinit0 &= ~DIS_VGA_PASSTHROUGH;
1214 else 1214 else
1215 fbiinit0 |= DIS_VGA_PASSTHROU 1215 fbiinit0 |= DIS_VGA_PASSTHROUGH;
1216 if (slowpci) { 1216 if (slowpci) {
1217 fbiinit1 |= SLOW_PCI_WRITES; 1217 fbiinit1 |= SLOW_PCI_WRITES;
1218 fbiinit4 |= SLOW_PCI_READS; 1218 fbiinit4 |= SLOW_PCI_READS;
1219 } else { 1219 } else {
1220 fbiinit1 &= ~SLOW_PCI_WRITES; 1220 fbiinit1 &= ~SLOW_PCI_WRITES;
1221 fbiinit4 &= ~SLOW_PCI_READS; 1221 fbiinit4 &= ~SLOW_PCI_READS;
1222 } 1222 }
1223 sst_write(FBIINIT0, fbiinit0); 1223 sst_write(FBIINIT0, fbiinit0);
1224 sst_wait_idle(); 1224 sst_wait_idle();
1225 sst_write(FBIINIT1, fbiinit1); 1225 sst_write(FBIINIT1, fbiinit1);
1226 sst_wait_idle(); 1226 sst_wait_idle();
1227 sst_write(FBIINIT2, FBIINIT2_DEFAULT) 1227 sst_write(FBIINIT2, FBIINIT2_DEFAULT);
1228 sst_wait_idle(); 1228 sst_wait_idle();
1229 sst_write(FBIINIT3, FBIINIT3_DEFAULT) 1229 sst_write(FBIINIT3, FBIINIT3_DEFAULT);
1230 sst_wait_idle(); 1230 sst_wait_idle();
1231 sst_write(FBIINIT4, fbiinit4); 1231 sst_write(FBIINIT4, fbiinit4);
1232 sst_wait_idle(); 1232 sst_wait_idle();
1233 if (IS_VOODOO2(par)) { 1233 if (IS_VOODOO2(par)) {
1234 sst_write(FBIINIT6, FBIINIT6_ 1234 sst_write(FBIINIT6, FBIINIT6_DEFAULT);
1235 sst_wait_idle(); 1235 sst_wait_idle();
1236 } 1236 }
1237 1237
1238 pci_write_config_dword(dev, PCI_INIT_ 1238 pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
1239 pci_write_config_dword(dev, PCI_VCLK_ 1239 pci_write_config_dword(dev, PCI_VCLK_ENABLE, 0);
1240 return 1; 1240 return 1;
1241 } 1241 }
1242 1242
1243 static void __devexit sst_shutdown(struct fb 1243 static void __devexit sst_shutdown(struct fb_info *info)
1244 { 1244 {
1245 struct sstfb_par *par = info->par; 1245 struct sstfb_par *par = info->par;
1246 struct pci_dev *dev = par->dev; 1246 struct pci_dev *dev = par->dev;
1247 struct pll_timing gfx_timings; 1247 struct pll_timing gfx_timings;
1248 int Fout; 1248 int Fout;
1249 1249
1250 /* reset video, gfx, fifo, disable dr 1250 /* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
1251 pci_write_config_dword(dev, PCI_INIT_ 1251 pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
1252 sst_set_bits(FBIINIT1, VIDEO_RESET | 1252 sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);
1253 sst_unset_bits(FBIINIT2, EN_DRAM_REFR 1253 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
1254 sst_set_bits(FBIINIT0, FBI_RESET | FI 1254 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
1255 sst_wait_idle(); 1255 sst_wait_idle();
1256 pci_write_config_dword(dev, PCI_INIT_ 1256 pci_write_config_dword(dev, PCI_INIT_ENABLE,
1257 PCI_EN_INIT_WR 1257 PCI_EN_INIT_WR | PCI_REMAP_DAC);
1258 /* set 20Mhz gfx clock */ 1258 /* set 20Mhz gfx clock */
1259 sst_calc_pll(20000, &Fout, &gfx_timin 1259 sst_calc_pll(20000, &Fout, &gfx_timings);
1260 par->dac_sw.set_pll(info, &gfx_timing 1260 par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
1261 /* TODO maybe shutdown the dac, vrefr 1261 /* TODO maybe shutdown the dac, vrefresh and so on... */
1262 pci_write_config_dword(dev, PCI_INIT_ 1262 pci_write_config_dword(dev, PCI_INIT_ENABLE,
1263 PCI_EN_INIT_WR 1263 PCI_EN_INIT_WR);
1264 sst_unset_bits(FBIINIT0, FBI_RESET | 1264 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | DIS_VGA_PASSTHROUGH);
1265 pci_write_config_dword(dev, PCI_VCLK_ 1265 pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
1266 /* maybe keep fbiinit* and PCI_INIT_e 1266 /* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct
1267 * from start ? */ 1267 * from start ? */
1268 pci_write_config_dword(dev, PCI_INIT_ 1268 pci_write_config_dword(dev, PCI_INIT_ENABLE, 0);
1269 1269
1270 } 1270 }
1271 1271
1272 /* 1272 /*
1273 * Interface to the world 1273 * Interface to the world
1274 */ 1274 */
1275 static int __devinit sstfb_setup(char *optio 1275 static int __devinit sstfb_setup(char *options)
1276 { 1276 {
1277 char *this_opt; 1277 char *this_opt;
1278 1278
1279 if (!options || !*options) 1279 if (!options || !*options)
1280 return 0; 1280 return 0;
1281 1281
1282 while ((this_opt = strsep(&options, " 1282 while ((this_opt = strsep(&options, ",")) != NULL) {
1283 if (!*this_opt) continue; 1283 if (!*this_opt) continue;
1284 1284
1285 f_ddprintk("option %s\n", thi 1285 f_ddprintk("option %s\n", this_opt);
1286 1286
1287 if (!strcmp(this_opt, "vganop 1287 if (!strcmp(this_opt, "vganopass"))
1288 vgapass = 0; 1288 vgapass = 0;
1289 else if (!strcmp(this_opt, "v 1289 else if (!strcmp(this_opt, "vgapass"))
1290 vgapass = 1; 1290 vgapass = 1;
1291 else if (!strcmp(this_opt, "c 1291 else if (!strcmp(this_opt, "clipping"))
1292 clipping = 1; 1292 clipping = 1;
1293 else if (!strcmp(this_opt, "n 1293 else if (!strcmp(this_opt, "noclipping"))
1294 clipping = 0; 1294 clipping = 0;
1295 else if (!strcmp(this_opt, "f 1295 else if (!strcmp(this_opt, "fastpci"))
1296 slowpci = 0; 1296 slowpci = 0;
1297 else if (!strcmp(this_opt, "s 1297 else if (!strcmp(this_opt, "slowpci"))
1298 slowpci = 1; 1298 slowpci = 1;
1299 else if (!strncmp(this_opt, " 1299 else if (!strncmp(this_opt, "mem:",4))
1300 mem = simple_strtoul 1300 mem = simple_strtoul (this_opt+4, NULL, 0);
1301 else if (!strncmp(this_opt, " 1301 else if (!strncmp(this_opt, "gfxclk:",7))
1302 gfxclk = simple_strto 1302 gfxclk = simple_strtoul (this_opt+7, NULL, 0);
1303 else 1303 else
1304 mode_option = this_op 1304 mode_option = this_opt;
1305 } 1305 }
1306 return 0; 1306 return 0;
1307 } 1307 }
1308 1308
1309 1309
1310 static struct fb_ops sstfb_ops = { 1310 static struct fb_ops sstfb_ops = {
1311 .owner = THIS_MODULE, 1311 .owner = THIS_MODULE,
1312 .fb_check_var = sstfb_check_var, 1312 .fb_check_var = sstfb_check_var,
1313 .fb_set_par = sstfb_set_par, 1313 .fb_set_par = sstfb_set_par,
1314 .fb_setcolreg = sstfb_setcolreg, 1314 .fb_setcolreg = sstfb_setcolreg,
1315 .fb_fillrect = cfb_fillrect, /* ss 1315 .fb_fillrect = cfb_fillrect, /* sstfb_fillrect */
1316 .fb_copyarea = cfb_copyarea, /* ss 1316 .fb_copyarea = cfb_copyarea, /* sstfb_copyarea */
1317 .fb_imageblit = cfb_imageblit, 1317 .fb_imageblit = cfb_imageblit,
1318 .fb_ioctl = sstfb_ioctl, 1318 .fb_ioctl = sstfb_ioctl,
1319 }; 1319 };
1320 1320
1321 static int __devinit sstfb_probe(struct pci_d 1321 static int __devinit sstfb_probe(struct pci_dev *pdev,
1322 const struct pci_devi 1322 const struct pci_device_id *id)
1323 { 1323 {
1324 struct fb_info *info; 1324 struct fb_info *info;
1325 struct fb_fix_screeninfo *fix; 1325 struct fb_fix_screeninfo *fix;
1326 struct sstfb_par *par; 1326 struct sstfb_par *par;
1327 struct sst_spec *spec; 1327 struct sst_spec *spec;
1328 int err; 1328 int err;
1329 1329
1330 /* Enable device in PCI config. */ 1330 /* Enable device in PCI config. */
1331 if ((err=pci_enable_device(pdev))) { 1331 if ((err=pci_enable_device(pdev))) {
1332 printk(KERN_ERR "cannot enabl 1332 printk(KERN_ERR "cannot enable device\n");
1333 return err; 1333 return err;
1334 } 1334 }
1335 1335
1336 /* Allocate the fb and par structures 1336 /* Allocate the fb and par structures. */
1337 info = framebuffer_alloc(sizeof(struc 1337 info = framebuffer_alloc(sizeof(struct sstfb_par), &pdev->dev);
1338 if (!info) 1338 if (!info)
1339 return -ENOMEM; 1339 return -ENOMEM;
1340 1340
1341 pci_set_drvdata(pdev, info); 1341 pci_set_drvdata(pdev, info);
1342 1342
1343 par = info->par; 1343 par = info->par;
1344 fix = &info->fix; 1344 fix = &info->fix;
1345 1345
1346 par->type = id->driver_data; 1346 par->type = id->driver_data;
1347 spec = &voodoo_spec[par->type]; 1347 spec = &voodoo_spec[par->type];
1348 f_ddprintk("found device : %s\n", spe 1348 f_ddprintk("found device : %s\n", spec->name);
1349 1349
1350 par->dev = pdev; 1350 par->dev = pdev;
1351 par->revision = pdev->revision; 1351 par->revision = pdev->revision;
1352 1352
1353 fix->mmio_start = pci_resource_start( 1353 fix->mmio_start = pci_resource_start(pdev,0);
1354 fix->mmio_len = 0x400000; 1354 fix->mmio_len = 0x400000;
1355 fix->smem_start = fix->mmio_start + 0 1355 fix->smem_start = fix->mmio_start + 0x400000;
1356 1356
1357 if (!request_mem_region(fix->mmio_sta 1357 if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) {
1358 printk(KERN_ERR "sstfb: canno 1358 printk(KERN_ERR "sstfb: cannot reserve mmio memory\n");
1359 goto fail_mmio_mem; 1359 goto fail_mmio_mem;
1360 } 1360 }
1361 1361
1362 if (!request_mem_region(fix->smem_sta 1362 if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) {
1363 printk(KERN_ERR "sstfb: canno 1363 printk(KERN_ERR "sstfb: cannot reserve fb memory\n");
1364 goto fail_fb_mem; 1364 goto fail_fb_mem;
1365 } 1365 }
1366 1366
1367 par->mmio_vbase = ioremap_nocache(fix 1367 par->mmio_vbase = ioremap_nocache(fix->mmio_start,
1368 fix-> 1368 fix->mmio_len);
1369 if (!par->mmio_vbase) { 1369 if (!par->mmio_vbase) {
1370 printk(KERN_ERR "sstfb: canno 1370 printk(KERN_ERR "sstfb: cannot remap register area %#lx\n",
1371 fix->mmio_start); 1371 fix->mmio_start);
1372 goto fail_mmio_remap; 1372 goto fail_mmio_remap;
1373 } 1373 }
1374 info->screen_base = ioremap_nocache(f 1374 info->screen_base = ioremap_nocache(fix->smem_start, 0x400000);
1375 if (!info->screen_base) { 1375 if (!info->screen_base) {
1376 printk(KERN_ERR "sstfb: canno 1376 printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n",
1377 fix->smem_start); 1377 fix->smem_start);
1378 goto fail_fb_remap; 1378 goto fail_fb_remap;
1379 } 1379 }
1380 1380
1381 if (!sst_init(info, par)) { 1381 if (!sst_init(info, par)) {
1382 printk(KERN_ERR "sstfb: Init 1382 printk(KERN_ERR "sstfb: Init failed\n");
1383 goto fail; 1383 goto fail;
1384 } 1384 }
1385 sst_get_memsize(info, &fix->smem_len) 1385 sst_get_memsize(info, &fix->smem_len);
1386 strlcpy(fix->id, spec->name, sizeof(f 1386 strlcpy(fix->id, spec->name, sizeof(fix->id));
1387 1387
1388 printk(KERN_INFO "%s (revision %d) wi 1388 printk(KERN_INFO "%s (revision %d) with %s dac\n",
1389 fix->id, par->revision, par-> 1389 fix->id, par->revision, par->dac_sw.name);
1390 printk(KERN_INFO "framebuffer at %#lx 1390 printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
1391 fix->smem_start, info->screen 1391 fix->smem_start, info->screen_base,
1392 fix->smem_len >> 20); 1392 fix->smem_len >> 20);
1393 1393
1394 f_ddprintk("regbase_virt: %#lx\n", pa 1394 f_ddprintk("regbase_virt: %#lx\n", par->mmio_vbase);
1395 f_ddprintk("membase_phys: %#lx\n", fi 1395 f_ddprintk("membase_phys: %#lx\n", fix->smem_start);
1396 f_ddprintk("fbbase_virt: %p\n", info- 1396 f_ddprintk("fbbase_virt: %p\n", info->screen_base);
1397 1397
1398 info->flags = FBINFO_DEFAULT; 1398 info->flags = FBINFO_DEFAULT;
1399 info->fbops = &sstfb_ops; 1399 info->fbops = &sstfb_ops;
1400 info->pseudo_palette = par->palette; 1400 info->pseudo_palette = par->palette;
1401 1401
1402 fix->type = FB_TYPE_PACKED_PIXE 1402 fix->type = FB_TYPE_PACKED_PIXELS;
1403 fix->visual = FB_VISUAL_TRUECOLOR 1403 fix->visual = FB_VISUAL_TRUECOLOR;
1404 fix->accel = FB_ACCEL_NONE; /* 1404 fix->accel = FB_ACCEL_NONE; /* FIXME */
1405 /* 1405 /*
1406 * According to the specs, the linele 1406 * According to the specs, the linelength must be of 1024 *pixels*
1407 * and the 24bpp mode is in fact a 32 1407 * and the 24bpp mode is in fact a 32 bpp mode (and both are in
1408 * fact dithered to 16bit). 1408 * fact dithered to 16bit).
1409 */ 1409 */
1410 fix->line_length = 2048; /* default v 1410 fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
1411 1411
1412 fb_find_mode(&info->var, info, mode_o 1412 fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16);
1413 1413
1414 if (sstfb_check_var(&info->var, info) 1414 if (sstfb_check_var(&info->var, info)) {
1415 printk(KERN_ERR "sstfb: inval 1415 printk(KERN_ERR "sstfb: invalid video mode.\n");
1416 goto fail; 1416 goto fail;
1417 } 1417 }
1418 1418
1419 if (sstfb_set_par(info)) { 1419 if (sstfb_set_par(info)) {
1420 printk(KERN_ERR "sstfb: can't 1420 printk(KERN_ERR "sstfb: can't set default video mode.\n");
1421 goto fail; 1421 goto fail;
1422 } 1422 }
1423 1423
1424 if (fb_alloc_cmap(&info->cmap, 256, 0 !! 1424 fb_alloc_cmap(&info->cmap, 256, 0);
1425 printk(KERN_ERR "sstfb: can't <<
1426 goto fail; <<
1427 } <<
1428 1425
1429 /* register fb */ 1426 /* register fb */
1430 info->device = &pdev->dev; 1427 info->device = &pdev->dev;
1431 if (register_framebuffer(info) < 0) { 1428 if (register_framebuffer(info) < 0) {
1432 printk(KERN_ERR "sstfb: can't 1429 printk(KERN_ERR "sstfb: can't register framebuffer.\n");
1433 goto fail_register; !! 1430 goto fail;
1434 } 1431 }
1435 1432
1436 sstfb_clear_screen(info); 1433 sstfb_clear_screen(info);
1437 1434
1438 if (device_create_file(info->dev, &de 1435 if (device_create_file(info->dev, &device_attrs[0]))
1439 printk(KERN_WARNING "sstfb: c 1436 printk(KERN_WARNING "sstfb: can't create sysfs entry.\n");
1440 1437
1441 1438
1442 printk(KERN_INFO "fb%d: %s frame buff 1439 printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n",
1443 info->node, fix->id, info->scr 1440 info->node, fix->id, info->screen_base);
1444 1441
1445 return 0; 1442 return 0;
1446 1443
1447 fail_register: <<
1448 fb_dealloc_cmap(&info->cmap); <<
1449 fail: 1444 fail:
>> 1445 fb_dealloc_cmap(&info->cmap);
1450 iounmap(info->screen_base); 1446 iounmap(info->screen_base);
1451 fail_fb_remap: 1447 fail_fb_remap:
1452 iounmap(par->mmio_vbase); 1448 iounmap(par->mmio_vbase);
1453 fail_mmio_remap: 1449 fail_mmio_remap:
1454 release_mem_region(fix->smem_start, 0 1450 release_mem_region(fix->smem_start, 0x400000);
1455 fail_fb_mem: 1451 fail_fb_mem:
1456 release_mem_region(fix->mmio_start, i 1452 release_mem_region(fix->mmio_start, info->fix.mmio_len);
1457 fail_mmio_mem: 1453 fail_mmio_mem:
1458 framebuffer_release(info); 1454 framebuffer_release(info);
1459 return -ENXIO; /* no voodoo detected 1455 return -ENXIO; /* no voodoo detected */
1460 } 1456 }
1461 1457
1462 static void __devexit sstfb_remove(struct pci 1458 static void __devexit sstfb_remove(struct pci_dev *pdev)
1463 { 1459 {
1464 struct sstfb_par *par; 1460 struct sstfb_par *par;
1465 struct fb_info *info; 1461 struct fb_info *info;
1466 1462
1467 info = pci_get_drvdata(pdev); 1463 info = pci_get_drvdata(pdev);
1468 par = info->par; 1464 par = info->par;
1469 1465
1470 device_remove_file(info->dev, &device 1466 device_remove_file(info->dev, &device_attrs[0]);
1471 sst_shutdown(info); 1467 sst_shutdown(info);
1472 iounmap(info->screen_base); 1468 iounmap(info->screen_base);
1473 iounmap(par->mmio_vbase); 1469 iounmap(par->mmio_vbase);
1474 release_mem_region(info->fix.smem_sta 1470 release_mem_region(info->fix.smem_start, 0x400000);
1475 release_mem_region(info->fix.mmio_sta 1471 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1476 fb_dealloc_cmap(&info->cmap); 1472 fb_dealloc_cmap(&info->cmap);
1477 unregister_framebuffer(info); 1473 unregister_framebuffer(info);
1478 framebuffer_release(info); 1474 framebuffer_release(info);
1479 } 1475 }
1480 1476
1481 1477
1482 static const struct pci_device_id sstfb_id_tb 1478 static const struct pci_device_id sstfb_id_tbl[] = {
1483 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_ 1479 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO ),
1484 .driver_data = ID_VOODOO1, }, 1480 .driver_data = ID_VOODOO1, },
1485 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_ 1481 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2),
1486 .driver_data = ID_VOODOO2, }, 1482 .driver_data = ID_VOODOO2, },
1487 { 0 }, 1483 { 0 },
1488 }; 1484 };
1489 1485
1490 static struct pci_driver sstfb_driver = { 1486 static struct pci_driver sstfb_driver = {
1491 .name = "sstfb", 1487 .name = "sstfb",
1492 .id_table = sstfb_id_tbl, 1488 .id_table = sstfb_id_tbl,
1493 .probe = sstfb_probe, 1489 .probe = sstfb_probe,
1494 .remove = __devexit_p(sstfb_r 1490 .remove = __devexit_p(sstfb_remove),
1495 }; 1491 };
1496 1492
1497 1493
1498 static int __devinit sstfb_init(void) 1494 static int __devinit sstfb_init(void)
1499 { 1495 {
1500 char *option = NULL; 1496 char *option = NULL;
1501 1497
1502 if (fb_get_options("sstfb", &option)) 1498 if (fb_get_options("sstfb", &option))
1503 return -ENODEV; 1499 return -ENODEV;
1504 sstfb_setup(option); 1500 sstfb_setup(option);
1505 1501
1506 return pci_register_driver(&sstfb_dri 1502 return pci_register_driver(&sstfb_driver);
1507 } 1503 }
1508 1504
1509 static void __devexit sstfb_exit(void) 1505 static void __devexit sstfb_exit(void)
1510 { 1506 {
1511 pci_unregister_driver(&sstfb_driver); 1507 pci_unregister_driver(&sstfb_driver);
1512 } 1508 }
1513 1509
1514 1510
1515 module_init(sstfb_init); 1511 module_init(sstfb_init);
1516 module_exit(sstfb_exit); 1512 module_exit(sstfb_exit);
1517 1513
1518 MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi < 1514 MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
1519 MODULE_DESCRIPTION("FBDev driver for 3dfx Voo 1515 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
1520 MODULE_LICENSE("GPL"); 1516 MODULE_LICENSE("GPL");
1521 1517
1522 module_param(mem, int, 0); 1518 module_param(mem, int, 0);
1523 MODULE_PARM_DESC(mem, "Size of frame buffer m 1519 MODULE_PARM_DESC(mem, "Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
1524 module_param(vgapass, bool, 0); 1520 module_param(vgapass, bool, 0);
1525 MODULE_PARM_DESC(vgapass, "Enable VGA PassThr 1521 MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough mode (0 or 1) (default=0)");
1526 module_param(clipping, bool, 0); 1522 module_param(clipping, bool, 0);
1527 MODULE_PARM_DESC(clipping, "Enable clipping ( 1523 MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
1528 module_param(gfxclk, int, 0); 1524 module_param(gfxclk, int, 0);
1529 MODULE_PARM_DESC(gfxclk, "Force graphic chip 1525 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
1530 module_param(slowpci, bool, 0); 1526 module_param(slowpci, bool, 0);
1531 MODULE_PARM_DESC(slowpci, "Uses slow PCI sett 1527 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
1532 module_param(mode_option, charp, 0); 1528 module_param(mode_option, charp, 0);
1533 MODULE_PARM_DESC(mode_option, "Initial video 1529 MODULE_PARM_DESC(mode_option, "Initial video mode (default=" DEFAULT_VIDEO_MODE ")");
1534 1530
1535 1531
|
This page was automatically generated by the
LXR engine.
|