Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/video/sstfb.c (Version 2.6.31.13) and /linux/drivers/video/sstfb.c (Version 2.6.25.8)


  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.