Merge to Fedora kernel-2.6.7-1.441
[linux-2.6.git] / drivers / video / riva / fbdev.c
1 /*
2  * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver
3  *
4  * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
5  *
6  * Copyright 1999-2000 Jeff Garzik
7  *
8  * Contributors:
9  *
10  *      Ani Joshi:  Lots of debugging and cleanup work, really helped
11  *      get the driver going
12  *
13  *      Ferenc Bakonyi:  Bug fixes, cleanup, modularization
14  *
15  *      Jindrich Makovicka:  Accel code help, hw cursor, mtrr
16  *
17  *      Paul Richards:  Bug fixes, updates
18  *
19  * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
20  * Includes riva_hw.c from nVidia, see copyright below.
21  * KGI code provided the basis for state storage, init, and mode switching.
22  *
23  * This file is subject to the terms and conditions of the GNU General Public
24  * License.  See the file COPYING in the main directory of this archive
25  * for more details.
26  *
27  * Known bugs and issues:
28  *      restoring text mode fails
29  *      doublescan modes are broken
30  */
31
32 #include <linux/config.h>
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/errno.h>
36 #include <linux/string.h>
37 #include <linux/mm.h>
38 #include <linux/tty.h>
39 #include <linux/slab.h>
40 #include <linux/delay.h>
41 #include <linux/fb.h>
42 #include <linux/init.h>
43 #include <linux/pci.h>
44 #ifdef CONFIG_MTRR
45 #include <asm/mtrr.h>
46 #endif
47 #ifdef CONFIG_PPC_OF
48 #include <asm/prom.h>
49 #include <asm/pci-bridge.h>
50 #endif
51
52 #include "rivafb.h"
53 #include "nvreg.h"
54
55 #ifndef CONFIG_PCI              /* sanity check */
56 #error This driver requires PCI support.
57 #endif
58
59 /* version number of this driver */
60 #define RIVAFB_VERSION "0.9.5b"
61
62 /* ------------------------------------------------------------------------- *
63  *
64  * various helpful macros and constants
65  *
66  * ------------------------------------------------------------------------- */
67
68 #undef RIVAFBDEBUG
69 #ifdef RIVAFBDEBUG
70 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
71 #else
72 #define DPRINTK(fmt, args...)
73 #endif
74
75 #ifndef RIVA_NDEBUG
76 #define assert(expr) \
77         if(!(expr)) { \
78         printk( "Assertion failed! %s,%s,%s,line=%d\n",\
79         #expr,__FILE__,__FUNCTION__,__LINE__); \
80         BUG(); \
81         }
82 #else
83 #define assert(expr)
84 #endif
85
86 #define PFX "rivafb: "
87
88 /* macro that allows you to set overflow bits */
89 #define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
90 #define SetBit(n)               (1<<(n))
91 #define Set8Bits(value)         ((value)&0xff)
92
93 /* HW cursor parameters */
94 #define MAX_CURS                32
95
96 /* ------------------------------------------------------------------------- *
97  *
98  * prototypes
99  *
100  * ------------------------------------------------------------------------- */
101
102 static int rivafb_blank(int blank, struct fb_info *info);
103
104 /* ------------------------------------------------------------------------- *
105  *
106  * card identification
107  *
108  * ------------------------------------------------------------------------- */
109
110 enum riva_chips {
111         CH_RIVA_128 = 0,
112         CH_RIVA_TNT,
113         CH_RIVA_TNT2,
114         CH_RIVA_UTNT2,
115         CH_RIVA_VTNT2,
116         CH_RIVA_UVTNT2,
117         CH_RIVA_ITNT2,
118         CH_GEFORCE_SDR,
119         CH_GEFORCE_DDR,
120         CH_QUADRO,
121         CH_GEFORCE2_MX,
122         CH_GEFORCE2_MX2,
123         CH_GEFORCE2_GO,
124         CH_QUADRO2_MXR,
125         CH_GEFORCE2_GTS,
126         CH_GEFORCE2_GTS2,
127         CH_GEFORCE2_ULTRA,
128         CH_QUADRO2_PRO,
129         CH_GEFORCE4_MX_460,
130         CH_GEFORCE4_MX_440,
131         CH_GEFORCE4_MX_420,
132         CH_GEFORCE4_440_GO,
133         CH_GEFORCE4_420_GO,
134         CH_GEFORCE4_420_GO_M32,
135         CH_QUADRO4_500XGL,
136         CH_GEFORCE4_440_GO_M64,
137         CH_QUADRO4_200,
138         CH_QUADRO4_550XGL,
139         CH_QUADRO4_500_GOGL,
140         CH_IGEFORCE2,
141         CH_GEFORCE3,
142         CH_GEFORCE3_1,
143         CH_GEFORCE3_2,
144         CH_QUADRO_DDC,
145         CH_GEFORCE4_TI_4600,
146         CH_GEFORCE4_TI_4400,
147         CH_GEFORCE4_TI_4200,
148         CH_QUADRO4_900XGL,
149         CH_QUADRO4_750XGL,
150         CH_QUADRO4_700XGL
151 };
152
153 /* directly indexed by riva_chips enum, above */
154 static struct riva_chip_info {
155         const char *name;
156         unsigned arch_rev;
157 } riva_chip_info[] __initdata = {
158         { "RIVA-128", NV_ARCH_03 },
159         { "RIVA-TNT", NV_ARCH_04 },
160         { "RIVA-TNT2", NV_ARCH_04 },
161         { "RIVA-UTNT2", NV_ARCH_04 },
162         { "RIVA-VTNT2", NV_ARCH_04 },
163         { "RIVA-UVTNT2", NV_ARCH_04 },
164         { "RIVA-ITNT2", NV_ARCH_04 },
165         { "GeForce-SDR", NV_ARCH_10 },
166         { "GeForce-DDR", NV_ARCH_10 },
167         { "Quadro", NV_ARCH_10 },
168         { "GeForce2-MX", NV_ARCH_10 },
169         { "GeForce2-MX", NV_ARCH_10 },
170         { "GeForce2-GO", NV_ARCH_10 },
171         { "Quadro2-MXR", NV_ARCH_10 },
172         { "GeForce2-GTS", NV_ARCH_10 },
173         { "GeForce2-GTS", NV_ARCH_10 },
174         { "GeForce2-ULTRA", NV_ARCH_10 },
175         { "Quadro2-PRO", NV_ARCH_10 },
176         { "GeForce4-MX-460", NV_ARCH_20 },
177         { "GeForce4-MX-440", NV_ARCH_20 },
178         { "GeForce4-MX-420", NV_ARCH_20 },
179         { "GeForce4-440-GO", NV_ARCH_20 },
180         { "GeForce4-420-GO", NV_ARCH_20 },
181         { "GeForce4-420-GO-M32", NV_ARCH_20 },
182         { "Quadro4-500-XGL", NV_ARCH_20 },
183         { "GeForce4-440-GO-M64", NV_ARCH_20 },
184         { "Quadro4-200", NV_ARCH_20 },
185         { "Quadro4-550-XGL", NV_ARCH_20 },
186         { "Quadro4-500-GOGL", NV_ARCH_20 },
187         { "GeForce2", NV_ARCH_20 },
188         { "GeForce3", NV_ARCH_20 }, 
189         { "GeForce3 Ti 200", NV_ARCH_20 },
190         { "GeForce3 Ti 500", NV_ARCH_20 },
191         { "Quadro DDC", NV_ARCH_20 },
192         { "GeForce4 Ti 4600", NV_ARCH_20 },
193         { "GeForce4 Ti 4400", NV_ARCH_20 },
194         { "GeForce4 Ti 4200", NV_ARCH_20 },
195         { "Quadro4-900-XGL", NV_ARCH_20 },
196         { "Quadro4-750-XGL", NV_ARCH_20 },
197         { "Quadro4-700-XGL", NV_ARCH_20 }
198 };
199
200 static struct pci_device_id rivafb_pci_tbl[] = {
201         { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
202           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_128 },
203         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
204           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT },
205         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
206           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT2 },
207         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
208           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_UTNT2 },
209         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
210           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
211         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
212           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
213         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
214           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_ITNT2 },
215         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
216           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_SDR },
217         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
218           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_DDR },
219         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
220           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO },
221         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
222           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX },
223         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
224           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX2 },
225         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
226           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GO },
227         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
228           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_MXR },
229         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
230           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS },
231         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
232           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS2 },
233         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
234           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_ULTRA },
235         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
236           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_PRO },
237         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
238           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_460 },
239         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
240           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_440 },
241         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
242           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_420 },
243         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
244           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_440_GO },
245         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
246           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_420_GO },
247         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
248           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_420_GO_M32 },
249         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
250           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_500XGL },
251         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
252           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_440_GO_M64 },
253         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
254           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_200 },
255         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
256           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_550XGL },
257         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
258           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_500_GOGL },
259         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
260           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_IGEFORCE2 },
261         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
262           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3 },
263         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
264           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_1 },
265         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
266           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_2 },
267         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
268           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO_DDC },
269         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
270           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4600 },
271         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
272           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4400 },
273         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
274           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4200 },
275         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
276           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_900XGL },
277         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
278           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
279         { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
280           PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
281         { 0, } /* terminate list */
282 };
283 MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
284
285 /* ------------------------------------------------------------------------- *
286  *
287  * global variables
288  *
289  * ------------------------------------------------------------------------- */
290
291 /* command line data, set in rivafb_setup() */
292 static u32 pseudo_palette[17];
293 static int flatpanel __initdata = -1; /* Autodetect later */
294 static int forceCRTC __initdata = -1;
295 #ifdef CONFIG_MTRR
296 static int nomtrr __initdata = 0;
297 #endif
298
299 static char *mode_option __initdata = NULL;
300 static int  strictmode       = 0;
301
302 static struct fb_fix_screeninfo rivafb_fix = {
303         .id             = "nVidia",
304         .type           = FB_TYPE_PACKED_PIXELS,
305         .xpanstep       = 1,
306         .ypanstep       = 1,
307 };
308
309 static struct fb_var_screeninfo rivafb_default_var = {
310         .xres           = 640,
311         .yres           = 480,
312         .xres_virtual   = 640,
313         .yres_virtual   = 480,
314         .bits_per_pixel = 8,
315         .red            = {0, 8, 0},
316         .green          = {0, 8, 0},
317         .blue           = {0, 8, 0},
318         .transp         = {0, 0, 0},
319         .activate       = FB_ACTIVATE_NOW,
320         .height         = -1,
321         .width          = -1,
322         .accel_flags    = FB_ACCELF_TEXT,
323         .pixclock       = 39721,
324         .left_margin    = 40,
325         .right_margin   = 24,
326         .upper_margin   = 32,
327         .lower_margin   = 11,
328         .hsync_len      = 96,
329         .vsync_len      = 2,
330         .vmode          = FB_VMODE_NONINTERLACED
331 };
332
333 /* from GGI */
334 static const struct riva_regs reg_template = {
335         {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,        /* ATTR */
336          0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
337          0x41, 0x01, 0x0F, 0x00, 0x00},
338         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* CRT  */
339          0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
340          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3,        /* 0x10 */
341          0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* 0x20 */
343          0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* 0x30 */
345          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346          0x00,                                                  /* 0x40 */
347          },
348         {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,        /* GRA  */
349          0xFF},
350         {0x03, 0x01, 0x0F, 0x00, 0x0E},                         /* SEQ  */
351         0xEB                                                    /* MISC */
352 };
353
354 /* ------------------------------------------------------------------------- *
355  *
356  * MMIO access macros
357  *
358  * ------------------------------------------------------------------------- */
359
360 static inline void CRTCout(struct riva_par *par, unsigned char index,
361                            unsigned char val)
362 {
363         VGA_WR08(par->riva.PCIO, 0x3d4, index);
364         VGA_WR08(par->riva.PCIO, 0x3d5, val);
365 }
366
367 static inline unsigned char CRTCin(struct riva_par *par,
368                                    unsigned char index)
369 {
370         VGA_WR08(par->riva.PCIO, 0x3d4, index);
371         return (VGA_RD08(par->riva.PCIO, 0x3d5));
372 }
373
374 static inline void GRAout(struct riva_par *par, unsigned char index,
375                           unsigned char val)
376 {
377         VGA_WR08(par->riva.PVIO, 0x3ce, index);
378         VGA_WR08(par->riva.PVIO, 0x3cf, val);
379 }
380
381 static inline unsigned char GRAin(struct riva_par *par,
382                                   unsigned char index)
383 {
384         VGA_WR08(par->riva.PVIO, 0x3ce, index);
385         return (VGA_RD08(par->riva.PVIO, 0x3cf));
386 }
387
388 static inline void SEQout(struct riva_par *par, unsigned char index,
389                           unsigned char val)
390 {
391         VGA_WR08(par->riva.PVIO, 0x3c4, index);
392         VGA_WR08(par->riva.PVIO, 0x3c5, val);
393 }
394
395 static inline unsigned char SEQin(struct riva_par *par,
396                                   unsigned char index)
397 {
398         VGA_WR08(par->riva.PVIO, 0x3c4, index);
399         return (VGA_RD08(par->riva.PVIO, 0x3c5));
400 }
401
402 static inline void ATTRout(struct riva_par *par, unsigned char index,
403                            unsigned char val)
404 {
405         VGA_WR08(par->riva.PCIO, 0x3c0, index);
406         VGA_WR08(par->riva.PCIO, 0x3c0, val);
407 }
408
409 static inline unsigned char ATTRin(struct riva_par *par,
410                                    unsigned char index)
411 {
412         VGA_WR08(par->riva.PCIO, 0x3c0, index);
413         return (VGA_RD08(par->riva.PCIO, 0x3c1));
414 }
415
416 static inline void MISCout(struct riva_par *par, unsigned char val)
417 {
418         VGA_WR08(par->riva.PVIO, 0x3c2, val);
419 }
420
421 static inline unsigned char MISCin(struct riva_par *par)
422 {
423         return (VGA_RD08(par->riva.PVIO, 0x3cc));
424 }
425
426 static u8 byte_rev[256] = {
427         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
428         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
429         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
430         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
431         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
432         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
433         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
434         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
435         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
436         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
437         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
438         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
439         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
440         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
441         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
442         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
443         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
444         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
445         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
446         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
447         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
448         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
449         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
450         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
451         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
452         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
453         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
454         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
455         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
456         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
457         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
458         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
459 };
460
461 static inline void reverse_order(u32 *l)
462 {
463         u8 *a = (u8 *)l;
464         *a = byte_rev[*a], a++;
465         *a = byte_rev[*a], a++;
466         *a = byte_rev[*a], a++;
467         *a = byte_rev[*a];
468 }
469
470 /* ------------------------------------------------------------------------- *
471  *
472  * cursor stuff
473  *
474  * ------------------------------------------------------------------------- */
475
476 /**
477  * rivafb_load_cursor_image - load cursor image to hardware
478  * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
479  * @par:  pointer to private data
480  * @w:    width of cursor image in pixels
481  * @h:    height of cursor image in scanlines
482  * @bg:   background color (ARGB1555) - alpha bit determines opacity
483  * @fg:   foreground color (ARGB1555)
484  *
485  * DESCRIPTiON:
486  * Loads cursor image based on a monochrome source and mask bitmap.  The
487  * image bits determines the color of the pixel, 0 for background, 1 for
488  * foreground.  Only the affected region (as determined by @w and @h 
489  * parameters) will be updated.
490  *
491  * CALLED FROM:
492  * rivafb_cursor()
493  */
494 static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
495                                      u16 bg, u16 fg, u32 w, u32 h)
496 {
497         int i, j, k = 0;
498         u32 b, tmp;
499         u32 *data = (u32 *)data8;
500
501         for (i = 0; i < h; i++) {
502                 b = *data++;
503                 reverse_order(&b);
504                 
505                 for (j = 0; j < w/2; j++) {
506                         tmp = 0;
507 #if defined (__BIG_ENDIAN)
508                         tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
509                         b <<= 1;
510                         tmp |= (b & (1 << 31)) ? fg : bg;
511                         b <<= 1;
512 #else
513                         tmp = (b & 1) ? fg : bg;
514                         b >>= 1;
515                         tmp |= (b & 1) ? fg << 16 : bg << 16;
516                         b >>= 1;
517 #endif
518                         writel(tmp, &par->riva.CURSOR[k++]);
519                 }
520                 k += (MAX_CURS - w)/2;
521         }
522 }
523
524 /* ------------------------------------------------------------------------- *
525  *
526  * general utility functions
527  *
528  * ------------------------------------------------------------------------- */
529
530 /**
531  * riva_wclut - set CLUT entry
532  * @chip: pointer to RIVA_HW_INST object
533  * @regnum: register number
534  * @red: red component
535  * @green: green component
536  * @blue: blue component
537  *
538  * DESCRIPTION:
539  * Sets color register @regnum.
540  *
541  * CALLED FROM:
542  * rivafb_setcolreg()
543  */
544 static void riva_wclut(RIVA_HW_INST *chip,
545                        unsigned char regnum, unsigned char red,
546                        unsigned char green, unsigned char blue)
547 {
548         VGA_WR08(chip->PDIO, 0x3c8, regnum);
549         VGA_WR08(chip->PDIO, 0x3c9, red);
550         VGA_WR08(chip->PDIO, 0x3c9, green);
551         VGA_WR08(chip->PDIO, 0x3c9, blue);
552 }
553
554 /**
555  * riva_rclut - read fromCLUT register
556  * @chip: pointer to RIVA_HW_INST object
557  * @regnum: register number
558  * @red: red component
559  * @green: green component
560  * @blue: blue component
561  *
562  * DESCRIPTION:
563  * Reads red, green, and blue from color register @regnum.
564  *
565  * CALLED FROM:
566  * rivafb_setcolreg()
567  */
568 static void riva_rclut(RIVA_HW_INST *chip,
569                        unsigned char regnum, unsigned char *red,
570                        unsigned char *green, unsigned char *blue)
571 {
572         
573         VGA_WR08(chip->PDIO, 0x3c8, regnum);
574         *red = VGA_RD08(chip->PDIO, 0x3c9);
575         *green = VGA_RD08(chip->PDIO, 0x3c9);
576         *blue = VGA_RD08(chip->PDIO, 0x3c9);
577 }
578
579 /**
580  * riva_save_state - saves current chip state
581  * @par: pointer to riva_par object containing info for current riva board
582  * @regs: pointer to riva_regs object
583  *
584  * DESCRIPTION:
585  * Saves current chip state to @regs.
586  *
587  * CALLED FROM:
588  * rivafb_probe()
589  */
590 /* from GGI */
591 static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
592 {
593         int i;
594
595         par->riva.LockUnlock(&par->riva, 0);
596
597         par->riva.UnloadStateExt(&par->riva, &regs->ext);
598
599         regs->misc_output = MISCin(par);
600
601         for (i = 0; i < NUM_CRT_REGS; i++)
602                 regs->crtc[i] = CRTCin(par, i);
603
604         for (i = 0; i < NUM_ATC_REGS; i++)
605                 regs->attr[i] = ATTRin(par, i);
606
607         for (i = 0; i < NUM_GRC_REGS; i++)
608                 regs->gra[i] = GRAin(par, i);
609
610         for (i = 0; i < NUM_SEQ_REGS; i++)
611                 regs->seq[i] = SEQin(par, i);
612 }
613
614 /**
615  * riva_load_state - loads current chip state
616  * @par: pointer to riva_par object containing info for current riva board
617  * @regs: pointer to riva_regs object
618  *
619  * DESCRIPTION:
620  * Loads chip state from @regs.
621  *
622  * CALLED FROM:
623  * riva_load_video_mode()
624  * rivafb_probe()
625  * rivafb_remove()
626  */
627 /* from GGI */
628 static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
629 {
630         RIVA_HW_STATE *state = &regs->ext;
631         int i;
632
633         CRTCout(par, 0x11, 0x00);
634
635         par->riva.LockUnlock(&par->riva, 0);
636
637         par->riva.LoadStateExt(&par->riva, state);
638
639         MISCout(par, regs->misc_output);
640
641         for (i = 0; i < NUM_CRT_REGS; i++) {
642                 switch (i) {
643                 case 0x19:
644                 case 0x20 ... 0x40:
645                         break;
646                 default:
647                         CRTCout(par, i, regs->crtc[i]);
648                 }
649         }
650
651         for (i = 0; i < NUM_ATC_REGS; i++)
652                 ATTRout(par, i, regs->attr[i]);
653
654         for (i = 0; i < NUM_GRC_REGS; i++)
655                 GRAout(par, i, regs->gra[i]);
656
657         for (i = 0; i < NUM_SEQ_REGS; i++)
658                 SEQout(par, i, regs->seq[i]);
659 }
660
661 /**
662  * riva_load_video_mode - calculate timings
663  * @info: pointer to fb_info object containing info for current riva board
664  *
665  * DESCRIPTION:
666  * Calculate some timings and then send em off to riva_load_state().
667  *
668  * CALLED FROM:
669  * rivafb_set_par()
670  */
671 static void riva_load_video_mode(struct fb_info *info)
672 {
673         int bpp, width, hDisplaySize, hDisplay, hStart,
674             hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
675         int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
676         struct riva_par *par = (struct riva_par *) info->par;
677         struct riva_regs newmode;
678         
679         /* time to calculate */
680         rivafb_blank(1, info);
681
682         bpp = info->var.bits_per_pixel;
683         if (bpp == 16 && info->var.green.length == 5)
684                 bpp = 15;
685         width = info->var.xres_virtual;
686         hDisplaySize = info->var.xres;
687         hDisplay = (hDisplaySize / 8) - 1;
688         hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
689         hEnd = (hDisplaySize + info->var.right_margin +
690                 info->var.hsync_len) / 8 - 1;
691         hTotal = (hDisplaySize + info->var.right_margin +
692                   info->var.hsync_len + info->var.left_margin) / 8 - 5;
693         hBlankStart = hDisplay;
694         hBlankEnd = hTotal + 4;
695
696         height = info->var.yres_virtual;
697         vDisplay = info->var.yres - 1;
698         vStart = info->var.yres + info->var.lower_margin - 1;
699         vEnd = info->var.yres + info->var.lower_margin +
700                info->var.vsync_len - 1;
701         vTotal = info->var.yres + info->var.lower_margin +
702                  info->var.vsync_len + info->var.upper_margin + 2;
703         vBlankStart = vDisplay;
704         vBlankEnd = vTotal + 1;
705         dotClock = 1000000000 / info->var.pixclock;
706
707         memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
708
709         if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
710                 vTotal |= 1;
711
712         if (par->FlatPanel) {
713                 vStart = vTotal - 3;
714                 vEnd = vTotal - 2;
715                 vBlankStart = vStart;
716                 hStart = hTotal - 3;
717                 hEnd = hTotal - 2;
718                 hBlankEnd = hTotal + 4;
719         }
720
721         newmode.crtc[0x0] = Set8Bits (hTotal); 
722         newmode.crtc[0x1] = Set8Bits (hDisplay);
723         newmode.crtc[0x2] = Set8Bits (hBlankStart);
724         newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
725         newmode.crtc[0x4] = Set8Bits (hStart);
726         newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)
727                 | SetBitField (hEnd, 4: 0, 4:0);
728         newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
729         newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
730                 | SetBitField (vDisplay, 8: 8, 1:1)
731                 | SetBitField (vStart, 8: 8, 2:2)
732                 | SetBitField (vBlankStart, 8: 8, 3:3)
733                 | SetBit (4)
734                 | SetBitField (vTotal, 9: 9, 5:5)
735                 | SetBitField (vDisplay, 9: 9, 6:6)
736                 | SetBitField (vStart, 9: 9, 7:7);
737         newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)
738                 | SetBit (6);
739         newmode.crtc[0x10] = Set8Bits (vStart);
740         newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
741                 | SetBit (5);
742         newmode.crtc[0x12] = Set8Bits (vDisplay);
743         newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
744         newmode.crtc[0x15] = Set8Bits (vBlankStart);
745         newmode.crtc[0x16] = Set8Bits (vBlankEnd);
746
747         newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)
748                 | SetBitField(vBlankStart,10:10,3:3)
749                 | SetBitField(vStart,10:10,2:2)
750                 | SetBitField(vDisplay,10:10,1:1)
751                 | SetBitField(vTotal,10:10,0:0);
752         newmode.ext.horiz  = SetBitField(hTotal,8:8,0:0) 
753                 | SetBitField(hDisplay,8:8,1:1)
754                 | SetBitField(hBlankStart,8:8,2:2)
755                 | SetBitField(hStart,8:8,3:3);
756         newmode.ext.extra  = SetBitField(vTotal,11:11,0:0)
757                 | SetBitField(vDisplay,11:11,2:2)
758                 | SetBitField(vStart,11:11,4:4)
759                 | SetBitField(vBlankStart,11:11,6:6); 
760
761         if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
762                 int tmp = (hTotal >> 1) & ~1;
763                 newmode.ext.interlace = Set8Bits(tmp);
764                 newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
765         } else 
766                 newmode.ext.interlace = 0xff; /* interlace off */
767
768         if (par->riva.Architecture >= NV_ARCH_10)
769                 par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart);
770
771         if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
772                 newmode.misc_output &= ~0x40;
773         else
774                 newmode.misc_output |= 0x40;
775         if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
776                 newmode.misc_output &= ~0x80;
777         else
778                 newmode.misc_output |= 0x80;    
779
780         par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
781                                   hDisplaySize, height, dotClock);
782
783         newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
784         if (par->FlatPanel == 1) {
785                 newmode.ext.pixel |= (1 << 7);
786                 newmode.ext.scale |= (1 << 8);
787         }
788         if (par->SecondCRTC) {
789                 newmode.ext.head  = par->riva.PCRTC0[0x00000860/4] & ~0x00001000;
790                 newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000;
791                 newmode.ext.crtcOwner = 3;
792                 newmode.ext.pllsel |= 0x20000800;
793                 newmode.ext.vpll2 = newmode.ext.vpll;
794         } else if (par->riva.twoHeads) {
795                 newmode.ext.head  =  par->riva.PCRTC0[0x00000860/4] | 0x00001000;
796                 newmode.ext.head2 =  par->riva.PCRTC0[0x00002860/4] & ~0x00001000;
797                 newmode.ext.crtcOwner = 0;
798                 newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4];
799         }
800         if (par->FlatPanel == 1) {
801                 newmode.ext.pixel |= (1 << 7);
802                 newmode.ext.scale |= (1 << 8);
803         }
804         newmode.ext.cursorConfig = 0x02000100;
805         par->current_state = newmode;
806         riva_load_state(par, &par->current_state);
807         par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
808         rivafb_blank(0, info);
809 }
810
811 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
812 {
813         var->xres = var->xres_virtual = modedb->xres;
814         var->yres = modedb->yres;
815         if (var->yres_virtual < var->yres)
816             var->yres_virtual = var->yres;
817         var->xoffset = var->yoffset = 0;
818         var->pixclock = modedb->pixclock;
819         var->left_margin = modedb->left_margin;
820         var->right_margin = modedb->right_margin;
821         var->upper_margin = modedb->upper_margin;
822         var->lower_margin = modedb->lower_margin;
823         var->hsync_len = modedb->hsync_len;
824         var->vsync_len = modedb->vsync_len;
825         var->sync = modedb->sync;
826         var->vmode = modedb->vmode;
827 }
828
829 /**
830  * rivafb_do_maximize - 
831  * @info: pointer to fb_info object containing info for current riva board
832  * @var:
833  * @nom:
834  * @den:
835  *
836  * DESCRIPTION:
837  * .
838  *
839  * RETURNS:
840  * -EINVAL on failure, 0 on success
841  * 
842  *
843  * CALLED FROM:
844  * rivafb_check_var()
845  */
846 static int rivafb_do_maximize(struct fb_info *info,
847                               struct fb_var_screeninfo *var,
848                               int nom, int den)
849 {
850         static struct {
851                 int xres, yres;
852         } modes[] = {
853                 {1600, 1280},
854                 {1280, 1024},
855                 {1024, 768},
856                 {800, 600},
857                 {640, 480},
858                 {-1, -1}
859         };
860         int i;
861
862         /* use highest possible virtual resolution */
863         if (var->xres_virtual == -1 && var->yres_virtual == -1) {
864                 printk(KERN_WARNING PFX
865                        "using maximum available virtual resolution\n");
866                 for (i = 0; modes[i].xres != -1; i++) {
867                         if (modes[i].xres * nom / den * modes[i].yres <
868                             info->fix.smem_len)
869                                 break;
870                 }
871                 if (modes[i].xres == -1) {
872                         printk(KERN_ERR PFX
873                                "could not find a virtual resolution that fits into video memory!!\n");
874                         DPRINTK("EXIT - EINVAL error\n");
875                         return -EINVAL;
876                 }
877                 var->xres_virtual = modes[i].xres;
878                 var->yres_virtual = modes[i].yres;
879
880                 printk(KERN_INFO PFX
881                        "virtual resolution set to maximum of %dx%d\n",
882                        var->xres_virtual, var->yres_virtual);
883         } else if (var->xres_virtual == -1) {
884                 var->xres_virtual = (info->fix.smem_len * den /
885                         (nom * var->yres_virtual * 2)) & ~15;
886                 printk(KERN_WARNING PFX
887                        "setting virtual X resolution to %d\n", var->xres_virtual);
888         } else if (var->yres_virtual == -1) {
889                 var->xres_virtual = (var->xres_virtual + 15) & ~15;
890                 var->yres_virtual = info->fix.smem_len * den /
891                         (nom * var->xres_virtual * 2);
892                 printk(KERN_WARNING PFX
893                        "setting virtual Y resolution to %d\n", var->yres_virtual);
894         } else {
895                 var->xres_virtual = (var->xres_virtual + 15) & ~15;
896                 if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
897                         printk(KERN_ERR PFX
898                                "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
899                                var->xres, var->yres, var->bits_per_pixel);
900                         DPRINTK("EXIT - EINVAL error\n");
901                         return -EINVAL;
902                 }
903         }
904         
905         if (var->xres_virtual * nom / den >= 8192) {
906                 printk(KERN_WARNING PFX
907                        "virtual X resolution (%d) is too high, lowering to %d\n",
908                        var->xres_virtual, 8192 * den / nom - 16);
909                 var->xres_virtual = 8192 * den / nom - 16;
910         }
911         
912         if (var->xres_virtual < var->xres) {
913                 printk(KERN_ERR PFX
914                        "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
915                 return -EINVAL;
916         }
917
918         if (var->yres_virtual < var->yres) {
919                 printk(KERN_ERR PFX
920                        "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
921                 return -EINVAL;
922         }
923         if (var->xres_virtual > 0x7fff)
924             var->xres_virtual = 0x7fff;
925         if (var->yres_virtual > 0x7fff)
926             var->yres_virtual = 0x7fff;
927         return 0;
928 }
929
930 static void
931 riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
932 {
933         RIVA_FIFO_FREE(par->riva, Patt, 4);
934         par->riva.Patt->Color0        = clr0;
935         par->riva.Patt->Color1        = clr1;
936         par->riva.Patt->Monochrome[0] = pat0;
937         par->riva.Patt->Monochrome[1] = pat1;
938 }
939
940 /* acceleration routines */
941 inline void wait_for_idle(struct riva_par *par)
942 {
943         while (par->riva.Busy(&par->riva));
944 }
945
946 /*
947  * Set ROP.  Translate X rop into ROP3.  Internal routine.
948  */
949 static void
950 riva_set_rop_solid(struct riva_par *par, int rop)
951 {
952         riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
953         RIVA_FIFO_FREE(par->riva, Rop, 1);
954         par->riva.Rop->Rop3 = rop;
955
956 }
957
958 void riva_setup_accel(struct riva_par *par)
959 {
960         RIVA_FIFO_FREE(par->riva, Clip, 2);
961         par->riva.Clip->TopLeft     = 0x0;
962         par->riva.Clip->WidthHeight = 0x7fff7fff;
963         riva_set_rop_solid(par, 0xcc);
964         wait_for_idle(par);
965 }
966
967 /**
968  * riva_get_cmap_len - query current color map length
969  * @var: standard kernel fb changeable data
970  *
971  * DESCRIPTION:
972  * Get current color map length.
973  *
974  * RETURNS:
975  * Length of color map
976  *
977  * CALLED FROM:
978  * rivafb_setcolreg()
979  */
980 static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
981 {
982         int rc = 256;           /* reasonable default */
983
984         switch (var->green.length) {
985         case 8:
986                 rc = 256;       /* 256 entries (2^8), 8 bpp and RGB8888 */
987                 break;
988         case 5:
989                 rc = 32;        /* 32 entries (2^5), 16 bpp, RGB555 */
990                 break;
991         case 6:
992                 rc = 64;        /* 64 entries (2^6), 16 bpp, RGB565 */
993                 break;          
994         default:
995                 /* should not occur */
996                 break;
997         }
998         return rc;
999 }
1000
1001 /* ------------------------------------------------------------------------- *
1002  *
1003  * framebuffer operations
1004  *
1005  * ------------------------------------------------------------------------- */
1006
1007 static int rivafb_open(struct fb_info *info, int user)
1008 {
1009         struct riva_par *par = (struct riva_par *) info->par;
1010         int cnt = atomic_read(&par->ref_count);
1011
1012         if (!cnt) {
1013                 memset(&par->state, 0, sizeof(struct vgastate));
1014                 par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;
1015                 /* save the DAC for Riva128 */
1016                 if (par->riva.Architecture == NV_ARCH_03)
1017                         par->state.flags |= VGA_SAVE_CMAP;
1018                 save_vga(&par->state);
1019
1020                 RivaGetConfig(&par->riva, par->Chipset);
1021                 /* vgaHWunlock() + riva unlock (0x7F) */
1022                 CRTCout(par, 0x11, 0xFF);
1023                 par->riva.LockUnlock(&par->riva, 0);
1024         
1025                 riva_save_state(par, &par->initial_state);
1026         }
1027         atomic_inc(&par->ref_count);
1028         return 0;
1029 }
1030
1031 static int rivafb_release(struct fb_info *info, int user)
1032 {
1033         struct riva_par *par = (struct riva_par *) info->par;
1034         int cnt = atomic_read(&par->ref_count);
1035
1036         if (!cnt)
1037                 return -EINVAL;
1038         if (cnt == 1) {
1039                 par->riva.LockUnlock(&par->riva, 0);
1040                 par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1041                 riva_load_state(par, &par->initial_state);
1042                 restore_vga(&par->state);
1043                 par->riva.LockUnlock(&par->riva, 1);
1044         }
1045         atomic_dec(&par->ref_count);
1046         return 0;
1047 }
1048
1049 static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1050 {
1051         struct fb_monspecs *specs = &info->monspecs;
1052         int nom, den;           /* translating from pixels->bytes */
1053         int mode_valid = 0;
1054         
1055         switch (var->bits_per_pixel) {
1056         case 1 ... 8:
1057                 var->red.offset = var->green.offset = var->blue.offset = 0;
1058                 var->red.length = var->green.length = var->blue.length = 8;
1059                 var->bits_per_pixel = 8;
1060                 nom = den = 1;
1061                 break;
1062         case 9 ... 15:
1063                 var->green.length = 5;
1064                 /* fall through */
1065         case 16:
1066                 var->bits_per_pixel = 16;
1067                 if (var->green.length == 5) {
1068                         /* 0rrrrrgg gggbbbbb */
1069                         var->red.offset = 10;
1070                         var->green.offset = 5;
1071                         var->blue.offset = 0;
1072                         var->red.length = 5;
1073                         var->green.length = 5;
1074                         var->blue.length = 5;
1075                 } else {
1076                         /* rrrrrggg gggbbbbb */
1077                         var->red.offset = 11;
1078                         var->green.offset = 5;
1079                         var->blue.offset = 0;
1080                         var->red.length = 5;
1081                         var->green.length = 6;
1082                         var->blue.length = 5;
1083                 }
1084                 nom = 2;
1085                 den = 1;
1086                 break;
1087         case 17 ... 32:
1088                 var->red.length = var->green.length = var->blue.length = 8;
1089                 var->bits_per_pixel = 32;
1090                 var->red.offset = 16;
1091                 var->green.offset = 8;
1092                 var->blue.offset = 0;
1093                 nom = 4;
1094                 den = 1;
1095                 break;
1096         default:
1097                 printk(KERN_ERR PFX
1098                        "mode %dx%dx%d rejected...color depth not supported.\n",
1099                        var->xres, var->yres, var->bits_per_pixel);
1100                 DPRINTK("EXIT, returning -EINVAL\n");
1101                 return -EINVAL;
1102         }
1103
1104         if (!strictmode) {
1105                 if (!fb_validate_mode(var, info))
1106                         mode_valid = 1;
1107         }
1108
1109         /* find best mode from modedb */
1110         if (!mode_valid && specs->modedb_len) {
1111                 int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
1112
1113                 best_refresh = best = best_x = best_y = 0;
1114                 diff_x = diff_y = -1;
1115
1116                 for (i = 0; i < specs->modedb_len; i++) {
1117                         if (var->xres <= specs->modedb[i].xres &&
1118                             !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
1119                             specs->modedb[i].xres - var->xres < diff_x) {
1120                                 best_x = specs->modedb[i].xres;
1121                                 diff_x = best_x - var->xres;
1122                         }
1123                         if (!diff_x) break;
1124                 }
1125
1126                 if (diff_x != -1) {
1127                         for (i = 0; i < specs->modedb_len; i++) {
1128                                 if (best_x == specs->modedb[i].xres &&
1129                                     var->yres <= specs->modedb[i].yres &&
1130                                     !(specs->modedb[i].flag &
1131                                       FB_MODE_IS_CALCULATED) &&
1132                                     specs->modedb[i].yres-var->yres < diff_y) {
1133                                         best_y = specs->modedb[i].yres;
1134                                         diff_y = best_y - var->yres;
1135                                 }
1136                                 if (!diff_y) break;
1137                         }
1138                 }
1139
1140                 if (diff_y != -1) {
1141                         for (i = 0; i < specs->modedb_len; i++) {
1142                                 if (best_x == specs->modedb[i].xres &&
1143                                     best_y == specs->modedb[i].yres &&
1144                                     !(specs->modedb[i].flag &
1145                                       FB_MODE_IS_CALCULATED) &&
1146                                     specs->modedb[i].refresh > best_refresh) {
1147                                         best_refresh=specs->modedb[i].refresh;
1148                                         best = i;
1149                                 }
1150                         }
1151                 }
1152
1153                 if (best_refresh) {
1154                         riva_update_var(var, &specs->modedb[best]);
1155                         mode_valid = 1;
1156                 }
1157         }
1158
1159         /* calculate modeline if supported by monitor */
1160         if (!mode_valid && info->monspecs.gtf) {
1161                 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1162                         mode_valid = 1;
1163         }
1164         if (!mode_valid && info->monspecs.modedb_len)
1165                 return -EINVAL;
1166
1167         if (var->xres_virtual < var->xres)
1168                 var->xres_virtual = var->xres;
1169         if (var->yres_virtual <= var->yres)
1170                 var->yres_virtual = -1;
1171         if (rivafb_do_maximize(info, var, nom, den) < 0)
1172                 return -EINVAL;
1173
1174         if (var->xoffset < 0)
1175                 var->xoffset = 0;
1176         if (var->yoffset < 0)
1177                 var->yoffset = 0;
1178
1179         /* truncate xoffset and yoffset to maximum if too high */
1180         if (var->xoffset > var->xres_virtual - var->xres)
1181                 var->xoffset = var->xres_virtual - var->xres - 1;
1182
1183         if (var->yoffset > var->yres_virtual - var->yres)
1184                 var->yoffset = var->yres_virtual - var->yres - 1;
1185
1186         var->red.msb_right = 
1187             var->green.msb_right =
1188             var->blue.msb_right =
1189             var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1190         return 0;
1191 }
1192
1193 static int rivafb_set_par(struct fb_info *info)
1194 {
1195         struct riva_par *par = (struct riva_par *) info->par;
1196
1197         riva_load_video_mode(info);
1198         riva_setup_accel(par);
1199         
1200         info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1201         info->fix.visual = (info->var.bits_per_pixel == 8) ?
1202                                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1203         return 0;
1204 }
1205
1206 /**
1207  * rivafb_pan_display
1208  * @var: standard kernel fb changeable data
1209  * @con: TODO
1210  * @info: pointer to fb_info object containing info for current riva board
1211  *
1212  * DESCRIPTION:
1213  * Pan (or wrap, depending on the `vmode' field) the display using the
1214  * `xoffset' and `yoffset' fields of the `var' structure.
1215  * If the values don't fit, return -EINVAL.
1216  *
1217  * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1218  */
1219 static int rivafb_pan_display(struct fb_var_screeninfo *var,
1220                               struct fb_info *info)
1221 {
1222         struct riva_par *par = (struct riva_par *)info->par;
1223         unsigned int base;
1224
1225         if (var->xoffset > (var->xres_virtual - var->xres))
1226                 return -EINVAL;
1227         if (var->yoffset > (var->yres_virtual - var->yres))
1228                 return -EINVAL;
1229
1230         if (var->vmode & FB_VMODE_YWRAP) {
1231                 if (var->yoffset < 0
1232                     || var->yoffset >= info->var.yres_virtual
1233                     || var->xoffset) return -EINVAL;
1234         } else {
1235                 if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1236                     var->yoffset + info->var.yres > info->var.yres_virtual)
1237                         return -EINVAL;
1238         }
1239
1240         base = var->yoffset * info->fix.line_length + var->xoffset;
1241
1242         par->riva.SetStartAddress(&par->riva, base);
1243
1244         info->var.xoffset = var->xoffset;
1245         info->var.yoffset = var->yoffset;
1246
1247         if (var->vmode & FB_VMODE_YWRAP)
1248                 info->var.vmode |= FB_VMODE_YWRAP;
1249         else
1250                 info->var.vmode &= ~FB_VMODE_YWRAP;
1251         return 0;
1252 }
1253
1254 static int rivafb_blank(int blank, struct fb_info *info)
1255 {
1256         struct riva_par *par= (struct riva_par *)info->par;
1257         unsigned char tmp, vesa;
1258
1259         tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
1260         vesa = CRTCin(par, 0x1a) & ~0xc0;       /* sync on/off */
1261
1262         if (blank) {
1263                 tmp |= 0x20;
1264                 switch (blank - 1) {
1265                 case VESA_NO_BLANKING:
1266                         break;
1267                 case VESA_VSYNC_SUSPEND:
1268                         vesa |= 0x80;
1269                         break;
1270                 case VESA_HSYNC_SUSPEND:
1271                         vesa |= 0x40;
1272                         break;
1273                 case VESA_POWERDOWN:
1274                         vesa |= 0xc0;
1275                         break;
1276                 }
1277         }
1278         SEQout(par, 0x01, tmp);
1279         CRTCout(par, 0x1a, vesa);
1280         return 0;
1281 }
1282
1283 /**
1284  * rivafb_setcolreg
1285  * @regno: register index
1286  * @red: red component
1287  * @green: green component
1288  * @blue: blue component
1289  * @transp: transparency
1290  * @info: pointer to fb_info object containing info for current riva board
1291  *
1292  * DESCRIPTION:
1293  * Set a single color register. The values supplied have a 16 bit
1294  * magnitude.
1295  *
1296  * RETURNS:
1297  * Return != 0 for invalid regno.
1298  *
1299  * CALLED FROM:
1300  * fbcmap.c:fb_set_cmap()
1301  */
1302 static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1303                           unsigned blue, unsigned transp,
1304                           struct fb_info *info)
1305 {
1306         struct riva_par *par = (struct riva_par *)info->par;
1307         RIVA_HW_INST *chip = &par->riva;
1308         int i;
1309
1310         if (regno >= riva_get_cmap_len(&info->var))
1311                 return -EINVAL;
1312
1313         if (info->var.grayscale) {
1314                 /* gray = 0.30*R + 0.59*G + 0.11*B */
1315                 red = green = blue =
1316                     (red * 77 + green * 151 + blue * 28) >> 8;
1317         }
1318
1319         switch (info->var.bits_per_pixel) {
1320         case 8:
1321                 /* "transparent" stuff is completely ignored. */
1322                 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1323                 break;
1324         case 16:
1325                 if (info->var.green.length == 5) {
1326                         if (regno < 16) {
1327                                 /* 0rrrrrgg gggbbbbb */
1328                                 ((u32 *)info->pseudo_palette)[regno] =
1329                                         ((red & 0xf800) >> 1) |
1330                                         ((green & 0xf800) >> 6) |
1331                                         ((blue & 0xf800) >> 11);
1332                         }
1333                         for (i = 0; i < 8; i++) 
1334                                 riva_wclut(chip, regno*8+i, red >> 8,
1335                                            green >> 8, blue >> 8);
1336                 } else {
1337                         u8 r, g, b;
1338
1339                         if (regno < 16) {
1340                                 /* rrrrrggg gggbbbbb */
1341                                 ((u32 *)info->pseudo_palette)[regno] =
1342                                         ((red & 0xf800) >> 0) |
1343                                         ((green & 0xf800) >> 5) |
1344                                         ((blue & 0xf800) >> 11);
1345                         }
1346                         if (regno < 32) {
1347                                 for (i = 0; i < 8; i++) {
1348                                         riva_wclut(chip, regno*8+i, red >> 8, 
1349                                                    green >> 8, blue >> 8);
1350                                 }
1351                         }
1352                         for (i = 0; i < 4; i++) {
1353                                 riva_rclut(chip, regno*2+i, &r, &g, &b);
1354                                 riva_wclut(chip, regno*4+i, r, green >> 8, b);
1355                         }
1356                 }
1357                 break;
1358         case 32:
1359                 if (regno < 16) {
1360                         ((u32 *)info->pseudo_palette)[regno] =
1361                                 ((red & 0xff00) << 8) |
1362                                 ((green & 0xff00)) | ((blue & 0xff00) >> 8);
1363                         
1364                 }
1365                 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1366                 break;
1367         default:
1368                 /* do nothing */
1369                 break;
1370         }
1371         return 0;
1372 }
1373
1374 /**
1375  * rivafb_fillrect - hardware accelerated color fill function
1376  * @info: pointer to fb_info structure
1377  * @rect: pointer to fb_fillrect structure
1378  *
1379  * DESCRIPTION:
1380  * This function fills up a region of framebuffer memory with a solid
1381  * color with a choice of two different ROP's, copy or invert.
1382  *
1383  * CALLED FROM:
1384  * framebuffer hook
1385  */
1386 static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1387 {
1388         struct riva_par *par = (struct riva_par *) info->par;
1389         u_int color, rop = 0;
1390
1391         if (info->var.bits_per_pixel == 8)
1392                 color = rect->color;
1393         else
1394                 color = ((u32 *)info->pseudo_palette)[rect->color];
1395
1396         switch (rect->rop) {
1397         case ROP_XOR:
1398                 rop = 0x66;
1399                 break;
1400         case ROP_COPY:
1401         default:
1402                 rop = 0xCC;
1403                 break;
1404         }
1405
1406         riva_set_rop_solid(par, rop);
1407
1408         RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1409         par->riva.Bitmap->Color1A = color;
1410
1411         RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1412         par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
1413                         (rect->dx << 16) | rect->dy;
1414         mb();
1415         par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
1416                         (rect->width << 16) | rect->height;
1417         mb();
1418         riva_set_rop_solid(par, 0xcc);
1419
1420 }
1421
1422 /**
1423  * rivafb_copyarea - hardware accelerated blit function
1424  * @info: pointer to fb_info structure
1425  * @region: pointer to fb_copyarea structure
1426  *
1427  * DESCRIPTION:
1428  * This copies an area of pixels from one location to another
1429  *
1430  * CALLED FROM:
1431  * framebuffer hook
1432  */
1433 static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1434 {
1435         struct riva_par *par = (struct riva_par *) info->par;
1436
1437         RIVA_FIFO_FREE(par->riva, Blt, 3);
1438         par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
1439         par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
1440         mb();
1441         par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
1442         mb();
1443 }
1444
1445 static inline void convert_bgcolor_16(u32 *col)
1446 {
1447         *col = ((*col & 0x00007C00) << 9)
1448                 | ((*col & 0x000003E0) << 6)
1449                 | ((*col & 0x0000001F) << 3)
1450                 |          0xFF000000;
1451         mb();
1452 }
1453
1454 /**
1455  * rivafb_imageblit: hardware accelerated color expand function
1456  * @info: pointer to fb_info structure
1457  * @image: pointer to fb_image structure
1458  *
1459  * DESCRIPTION:
1460  * If the source is a monochrome bitmap, the function fills up a a region
1461  * of framebuffer memory with pixels whose color is determined by the bit
1462  * setting of the bitmap, 1 - foreground, 0 - background.
1463  *
1464  * If the source is not a monochrome bitmap, color expansion is not done.
1465  * In this case, it is channeled to a software function.
1466  *
1467  * CALLED FROM:
1468  * framebuffer hook
1469  */
1470 static void rivafb_imageblit(struct fb_info *info, 
1471                              const struct fb_image *image)
1472 {
1473         struct riva_par *par = (struct riva_par *) info->par;
1474         u32 fgx = 0, bgx = 0, width, tmp;
1475         u8 *cdat = (u8 *) image->data;
1476         volatile u32 *d;
1477         int i, size;
1478
1479         if (image->depth != 1) {
1480                 cfb_imageblit(info, image);
1481                 return;
1482         }
1483
1484         switch (info->var.bits_per_pixel) {
1485         case 8:
1486                 fgx = image->fg_color;
1487                 bgx = image->bg_color;
1488                 break;
1489         case 16:
1490                 fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1491                 bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1492                 if (info->var.green.length == 6)
1493                         convert_bgcolor_16(&bgx);       
1494                 break;
1495         case 32:
1496                 fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1497                 bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1498                 break;
1499         }
1500
1501         RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1502         par->riva.Bitmap->ClipE.TopLeft     = 
1503                 (image->dy << 16) | (image->dx & 0xFFFF);
1504         par->riva.Bitmap->ClipE.BottomRight = 
1505                 (((image->dy + image->height) << 16) |
1506                  ((image->dx + image->width) & 0xffff));
1507         par->riva.Bitmap->Color0E           = bgx;
1508         par->riva.Bitmap->Color1E           = fgx;
1509         par->riva.Bitmap->WidthHeightInE    = 
1510                 (image->height << 16) | ((image->width + 31) & ~31);
1511         par->riva.Bitmap->WidthHeightOutE   = 
1512                 (image->height << 16) | ((image->width + 31) & ~31);
1513         par->riva.Bitmap->PointE            = 
1514                 (image->dy << 16) | (image->dx & 0xFFFF);
1515
1516         d = &par->riva.Bitmap->MonochromeData01E;
1517
1518         width = (image->width + 31)/32;
1519         size = width * image->height;
1520         while (size >= 16) {
1521                 RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1522                 for (i = 0; i < 16; i++) {
1523                         tmp = *((u32 *)cdat);
1524                         cdat = (u8 *)((u32 *)cdat + 1);
1525                         reverse_order(&tmp);
1526                         d[i] = tmp;
1527                 }
1528                 size -= 16;
1529         }
1530         if (size) {
1531                 RIVA_FIFO_FREE(par->riva, Bitmap, size);
1532                 for (i = 0; i < size; i++) {
1533                         tmp = *((u32 *) cdat);
1534                         cdat = (u8 *)((u32 *)cdat + 1);
1535                         reverse_order(&tmp);
1536                         d[i] = tmp;
1537                 }
1538         }
1539 }
1540
1541 /**
1542  * rivafb_cursor - hardware cursor function
1543  * @info: pointer to info structure
1544  * @cursor: pointer to fbcursor structure
1545  *
1546  * DESCRIPTION:
1547  * A cursor function that supports displaying a cursor image via hardware.
1548  * Within the kernel, copy and invert rops are supported.  If exported
1549  * to user space, only the copy rop will be supported.
1550  *
1551  * CALLED FROM
1552  * framebuffer hook
1553  */
1554 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1555 {
1556         struct riva_par *par = (struct riva_par *) info->par;
1557         u8 data[MAX_CURS * MAX_CURS/8];
1558         u16 fg, bg;
1559         int i;
1560
1561         par->riva.ShowHideCursor(&par->riva, 0);
1562
1563         if (cursor->set & FB_CUR_SETPOS) {
1564                 u32 xx, yy, temp;
1565
1566                 info->cursor.image.dx = cursor->image.dx;
1567                 info->cursor.image.dy = cursor->image.dy;
1568                 yy = cursor->image.dy - info->var.yoffset;
1569                 xx = cursor->image.dx - info->var.xoffset;
1570                 temp = xx & 0xFFFF;
1571                 temp |= yy << 16;
1572
1573                 par->riva.PRAMDAC[0x0000300/4] = temp;
1574         }
1575
1576         if (cursor->set & FB_CUR_SETSIZE) {
1577                 info->cursor.image.height = cursor->image.height;
1578                 info->cursor.image.width = cursor->image.width;
1579                 memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1580         }
1581
1582         if (cursor->set & FB_CUR_SETCMAP) {
1583                 info->cursor.image.bg_color = cursor->image.bg_color;
1584                 info->cursor.image.fg_color = cursor->image.fg_color;
1585         }
1586
1587         if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
1588                 u32 bg_idx = info->cursor.image.bg_color;
1589                 u32 fg_idx = info->cursor.image.fg_color;
1590                 u32 s_pitch = (info->cursor.image.width+7) >> 3;
1591                 u32 d_pitch = MAX_CURS/8;
1592                 u8 *dat = (u8 *) cursor->image.data;
1593                 u8 *msk = (u8 *) info->cursor.mask;
1594                 u8 src[64];     
1595                 
1596                 info->cursor.image.data = cursor->image.data;
1597                 switch (info->cursor.rop) {
1598                 case ROP_XOR:
1599                         for (i = 0; i < s_pitch * info->cursor.image.height;
1600                              i++)
1601                                 src[i] = dat[i] ^ msk[i];
1602                         break;
1603                 case ROP_COPY:
1604                 default:
1605                         for (i = 0; i < s_pitch * info->cursor.image.height;
1606                              i++)
1607                                 src[i] = dat[i] & msk[i];
1608                         break;
1609                 }
1610                 
1611                 fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
1612                                     s_pitch, info->cursor.image.height);
1613
1614                 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1615                      ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1616                      ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
1617
1618                 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1619                      ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1620                      ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
1621
1622                 par->riva.LockUnlock(&par->riva, 0);
1623
1624                 rivafb_load_cursor_image(par, data, bg, fg,
1625                                          info->cursor.image.width, 
1626                                          info->cursor.image.height);
1627         }
1628         if (info->cursor.enable)
1629                 par->riva.ShowHideCursor(&par->riva, 1);
1630         return 0;
1631 }
1632
1633 static int rivafb_sync(struct fb_info *info)
1634 {
1635         struct riva_par *par = (struct riva_par *)info->par;
1636
1637         wait_for_idle(par);
1638         return 0;
1639 }
1640
1641 /* ------------------------------------------------------------------------- *
1642  *
1643  * initialization helper functions
1644  *
1645  * ------------------------------------------------------------------------- */
1646
1647 /* kernel interface */
1648 static struct fb_ops riva_fb_ops = {
1649         .owner          = THIS_MODULE,
1650         .fb_open        = rivafb_open,
1651         .fb_release     = rivafb_release,
1652         .fb_check_var   = rivafb_check_var,
1653         .fb_set_par     = rivafb_set_par,
1654         .fb_setcolreg   = rivafb_setcolreg,
1655         .fb_pan_display = rivafb_pan_display,
1656         .fb_blank       = rivafb_blank,
1657         .fb_fillrect    = rivafb_fillrect,
1658         .fb_copyarea    = rivafb_copyarea,
1659         .fb_imageblit   = rivafb_imageblit,
1660         .fb_cursor      = rivafb_cursor,        
1661         .fb_sync        = rivafb_sync,
1662 };
1663
1664 static int __devinit riva_set_fbinfo(struct fb_info *info)
1665 {
1666         unsigned int cmap_len;
1667
1668         info->flags = FBINFO_DEFAULT
1669                     | FBINFO_HWACCEL_XPAN
1670                     | FBINFO_HWACCEL_YPAN
1671                     | FBINFO_HWACCEL_COPYAREA
1672                     | FBINFO_HWACCEL_FILLRECT
1673                     | FBINFO_HWACCEL_IMAGEBLIT;
1674         info->var = rivafb_default_var;
1675         info->fix.visual = (info->var.bits_per_pixel == 8) ?
1676                                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1677         info->pseudo_palette = pseudo_palette;
1678
1679         cmap_len = riva_get_cmap_len(&info->var);
1680         fb_alloc_cmap(&info->cmap, cmap_len, 0);        
1681
1682         info->pixmap.size = 64 * 1024;
1683         info->pixmap.buf_align = 4;
1684         info->pixmap.scan_align = 4;
1685         info->pixmap.flags = FB_PIXMAP_SYSTEM;
1686         info->var.yres_virtual = -1;
1687         return (rivafb_check_var(&info->var, info));
1688 }
1689
1690 #ifdef CONFIG_PPC_OF
1691 static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1692 {
1693         struct riva_par *par = (struct riva_par *) info->par;
1694         struct device_node *dp;
1695         unsigned char *pedid = NULL;
1696         unsigned char *disptype = NULL;
1697         static char *propnames[] = {
1698                 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
1699         int i;
1700
1701         dp = pci_device_to_OF_node(pd);
1702         for (; dp != NULL; dp = dp->child) {
1703                 disptype = (unsigned char *)get_property(dp, "display-type", NULL);
1704                 if (disptype == NULL)
1705                         continue;
1706                 if (strncmp(disptype, "LCD", 3) != 0)
1707                         continue;
1708                 for (i = 0; propnames[i] != NULL; ++i) {
1709                         pedid = (unsigned char *)
1710                                 get_property(dp, propnames[i], NULL);
1711                         if (pedid != NULL) {
1712                 par->EDID = pedid;
1713                 return 1;
1714                         }
1715                 }
1716         }
1717                 return 0;
1718 }
1719 #endif /* CONFIG_PPC_OF */
1720
1721 static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
1722 {
1723         struct fb_monspecs *specs = &info->monspecs;
1724         struct fb_videomode modedb;
1725
1726         /* respect mode options */
1727         if (mode_option) {
1728                 fb_find_mode(var, info, mode_option,
1729                              specs->modedb, specs->modedb_len,
1730                              NULL, 8);
1731         } else if (specs->modedb != NULL) {
1732                 /* get preferred timing */
1733                 if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
1734                         int i;
1735
1736                         for (i = 0; i < specs->modedb_len; i++) {
1737                                 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1738                                         modedb = specs->modedb[i];
1739                                         break;
1740                                 }
1741                         }
1742                 } else {
1743                         /* otherwise, get first mode in database */
1744                         modedb = specs->modedb[0];
1745                 }
1746                 var->bits_per_pixel = 8;
1747                 riva_update_var(var, &modedb);
1748         }
1749         var->accel_flags |= FB_ACCELF_TEXT;
1750 }
1751
1752
1753 static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1754 {
1755 #ifdef CONFIG_PPC_OF
1756         if (!riva_get_EDID_OF(info, pdev))
1757                 printk("rivafb: could not retrieve EDID from OF\n");
1758 #else
1759         /* XXX use other methods later */
1760 #ifdef CONFIG_FB_RIVA_I2C
1761         struct riva_par *par = (struct riva_par *) info->par;
1762
1763         riva_create_i2c_busses(par);
1764         riva_probe_i2c_connector(par, 1, &par->EDID);
1765         riva_delete_i2c_busses(par);
1766 #endif
1767 #endif
1768 }
1769
1770
1771 static void riva_get_edidinfo(struct fb_info *info)
1772 {
1773         struct fb_var_screeninfo *var = &rivafb_default_var;
1774         struct riva_par *par = (struct riva_par *) info->par;
1775
1776         fb_edid_to_monspecs(par->EDID, &info->monspecs);
1777         riva_update_default_var(var, info);
1778
1779         /* if user specified flatpanel, we respect that */
1780         if (info->monspecs.input & FB_DISP_DDI)
1781                 par->FlatPanel = 1;
1782 }
1783
1784 /* ------------------------------------------------------------------------- *
1785  *
1786  * PCI bus
1787  *
1788  * ------------------------------------------------------------------------- */
1789
1790 static int __devinit rivafb_probe(struct pci_dev *pd,
1791                                 const struct pci_device_id *ent)
1792 {
1793         struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1794         struct riva_par *default_par;
1795         struct fb_info *info;
1796
1797         assert(pd != NULL);
1798         assert(rci != NULL);
1799
1800         info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
1801         if (!info)
1802                 goto err_out;
1803
1804         default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
1805         if (!default_par)
1806                 goto err_out_kfree;
1807
1808         memset(info, 0, sizeof(struct fb_info));
1809         memset(default_par, 0, sizeof(struct riva_par));
1810         default_par->pdev = pd;
1811
1812         info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
1813         if (info->pixmap.addr == NULL)
1814                 goto err_out_kfree1;
1815         memset(info->pixmap.addr, 0, 64 * 1024);
1816
1817         strcat(rivafb_fix.id, rci->name);
1818         default_par->riva.Architecture = rci->arch_rev;
1819
1820         default_par->Chipset = (pd->vendor << 16) | pd->device;
1821         printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1822         
1823         default_par->FlatPanel = flatpanel;
1824         if (flatpanel == 1)
1825                 printk(KERN_INFO PFX "flatpanel support enabled\n");
1826         default_par->forceCRTC = forceCRTC;
1827         
1828         rivafb_fix.mmio_len = pci_resource_len(pd, 0);
1829         rivafb_fix.smem_len = pci_resource_len(pd, 1);
1830
1831         {
1832                 /* enable IO and mem if not already done */
1833                 unsigned short cmd;
1834
1835                 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1836                 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1837                 pci_write_config_word(pd, PCI_COMMAND, cmd);
1838         }
1839         
1840         rivafb_fix.mmio_start = pci_resource_start(pd, 0);
1841         rivafb_fix.smem_start = pci_resource_start(pd, 1);
1842
1843         if (!request_mem_region(rivafb_fix.mmio_start,
1844                                 rivafb_fix.mmio_len, "rivafb")) {
1845                 printk(KERN_ERR PFX "cannot reserve MMIO region\n");
1846                 goto err_out_kfree2;
1847         }
1848
1849         default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
1850                                          rivafb_fix.mmio_len);
1851         if (!default_par->ctrl_base) {
1852                 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1853                 goto err_out_free_base0;
1854         }
1855
1856         info->par = default_par;
1857
1858         switch (default_par->riva.Architecture) {
1859         case NV_ARCH_03:
1860                 /* Riva128's PRAMIN is in the "framebuffer" space
1861                  * Since these cards were never made with more than 8 megabytes
1862                  * we can safely allocate this separately.
1863                  */
1864                 if (!request_mem_region(rivafb_fix.smem_start + 0x00C00000,
1865                                          0x00008000, "rivafb")) {
1866                         printk(KERN_ERR PFX "cannot reserve PRAMIN region\n");
1867                         goto err_out_iounmap_ctrl;
1868                 }
1869                 default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
1870                 if (!default_par->riva.PRAMIN) {
1871                         printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
1872                         goto err_out_free_nv3_pramin;
1873                 }
1874                 rivafb_fix.accel = FB_ACCEL_NV3;
1875                 break;
1876         case NV_ARCH_04:
1877         case NV_ARCH_10:
1878         case NV_ARCH_20:
1879                 default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
1880                 default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
1881                 rivafb_fix.accel = FB_ACCEL_NV4;
1882                 break;
1883         }
1884
1885         riva_common_setup(default_par);
1886
1887         if (default_par->riva.Architecture == NV_ARCH_03) {
1888                 default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
1889         }
1890
1891         rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
1892         default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
1893
1894         if (!request_mem_region(rivafb_fix.smem_start,
1895                                 rivafb_fix.smem_len, "rivafb")) {
1896                 printk(KERN_ERR PFX "cannot reserve FB region\n");
1897                 goto err_out_iounmap_nv3_pramin;
1898         }
1899         
1900         info->screen_base = ioremap(rivafb_fix.smem_start,
1901                                     rivafb_fix.smem_len);
1902         if (!info->screen_base) {
1903                 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1904                 goto err_out_free_base1;
1905         }
1906
1907 #ifdef CONFIG_MTRR
1908         if (!nomtrr) {
1909                 default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
1910                                                   rivafb_fix.smem_len,
1911                                                   MTRR_TYPE_WRCOMB, 1);
1912                 if (default_par->mtrr.vram < 0) {
1913                         printk(KERN_ERR PFX "unable to setup MTRR\n");
1914                 } else {
1915                         default_par->mtrr.vram_valid = 1;
1916                         /* let there be speed */
1917                         printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
1918                 }
1919         }
1920 #endif /* CONFIG_MTRR */
1921
1922         info->fbops = &riva_fb_ops;
1923         info->fix = rivafb_fix;
1924         riva_get_EDID(info, pd);
1925         riva_get_edidinfo(info);
1926
1927         if (riva_set_fbinfo(info) < 0) {
1928                 printk(KERN_ERR PFX "error setting initial video mode\n");
1929                 goto err_out_iounmap_fb;
1930         }
1931
1932         if (register_framebuffer(info) < 0) {
1933                 printk(KERN_ERR PFX
1934                         "error registering riva framebuffer\n");
1935                 goto err_out_iounmap_fb;
1936         }
1937
1938         pci_set_drvdata(pd, info);
1939
1940         printk(KERN_INFO PFX
1941                 "PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
1942                 default_par->riva.Architecture,
1943                 RIVAFB_VERSION,
1944                 info->fix.id,
1945                 info->fix.smem_len / (1024 * 1024),
1946                 info->fix.smem_start);
1947         return 0;
1948
1949 err_out_iounmap_fb:
1950         iounmap(info->screen_base);
1951 err_out_free_base1:
1952         release_mem_region(rivafb_fix.smem_start, rivafb_fix.smem_len);
1953 err_out_iounmap_nv3_pramin:
1954         if (default_par->riva.Architecture == NV_ARCH_03) 
1955                 iounmap((caddr_t)default_par->riva.PRAMIN);
1956 err_out_free_nv3_pramin:
1957         if (default_par->riva.Architecture == NV_ARCH_03)
1958                 release_mem_region(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
1959 err_out_iounmap_ctrl:
1960         iounmap(default_par->ctrl_base);
1961 err_out_free_base0:
1962         release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
1963 err_out_kfree2:
1964         kfree(info->pixmap.addr);
1965 err_out_kfree1:
1966         kfree(default_par);
1967 err_out_kfree:
1968         kfree(info);
1969 err_out:
1970         return -ENODEV;
1971 }
1972
1973 static void __exit rivafb_remove(struct pci_dev *pd)
1974 {
1975         struct fb_info *info = pci_get_drvdata(pd);
1976         struct riva_par *par = (struct riva_par *) info->par;
1977         
1978         if (!info)
1979                 return;
1980
1981         unregister_framebuffer(info);
1982 #ifdef CONFIG_MTRR
1983         if (par->mtrr.vram_valid)
1984                 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1985                          info->fix.smem_len);
1986 #endif /* CONFIG_MTRR */
1987
1988         iounmap(par->ctrl_base);
1989         iounmap(info->screen_base);
1990
1991         release_mem_region(info->fix.mmio_start,
1992                            info->fix.mmio_len);
1993         release_mem_region(info->fix.smem_start,
1994                            info->fix.smem_len);
1995
1996         if (par->riva.Architecture == NV_ARCH_03) {
1997                 iounmap((caddr_t)par->riva.PRAMIN);
1998                 release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
1999         }
2000         kfree(info->pixmap.addr);
2001         kfree(par);
2002         kfree(info);
2003         pci_set_drvdata(pd, NULL);
2004 }
2005
2006 /* ------------------------------------------------------------------------- *
2007  *
2008  * initialization
2009  *
2010  * ------------------------------------------------------------------------- */
2011
2012 #ifndef MODULE
2013 int __init rivafb_setup(char *options)
2014 {
2015         char *this_opt;
2016
2017         if (!options || !*options)
2018                 return 0;
2019
2020         while ((this_opt = strsep(&options, ",")) != NULL) {
2021                 if (!strncmp(this_opt, "forceCRTC", 9)) {
2022                         char *p;
2023                         
2024                         p = this_opt + 9;
2025                         if (!*p || !*(++p)) continue; 
2026                         forceCRTC = *p - '0';
2027                         if (forceCRTC < 0 || forceCRTC > 1) 
2028                                 forceCRTC = -1;
2029                 } else if (!strncmp(this_opt, "flatpanel", 9)) {
2030                         flatpanel = 1;
2031 #ifdef CONFIG_MTRR
2032                 } else if (!strncmp(this_opt, "nomtrr", 6)) {
2033                         nomtrr = 1;
2034 #endif
2035                 } else if (!strncmp(this_opt, "strictmode", 10)) {
2036                         strictmode = 1;
2037                 } else
2038                         mode_option = this_opt;
2039         }
2040         return 0;
2041 }
2042 #endif /* !MODULE */
2043
2044 static struct pci_driver rivafb_driver = {
2045         .name           = "rivafb",
2046         .id_table       = rivafb_pci_tbl,
2047         .probe          = rivafb_probe,
2048         .remove         = __exit_p(rivafb_remove),
2049 };
2050
2051
2052
2053 /* ------------------------------------------------------------------------- *
2054  *
2055  * modularization
2056  *
2057  * ------------------------------------------------------------------------- */
2058
2059 int __init rivafb_init(void)
2060 {
2061         if (pci_register_driver(&rivafb_driver) > 0)
2062                 return 0;
2063         pci_unregister_driver(&rivafb_driver);
2064         return -ENODEV;
2065 }
2066
2067
2068 #ifdef MODULE
2069 static void __exit rivafb_exit(void)
2070 {
2071         pci_unregister_driver(&rivafb_driver);
2072 }
2073
2074 module_init(rivafb_init);
2075 module_exit(rivafb_exit);
2076
2077 MODULE_PARM(flatpanel, "i");
2078 MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2079 MODULE_PARM(forceCRTC, "i");
2080 MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2081
2082 #ifdef CONFIG_MTRR
2083 MODULE_PARM(nomtrr, "i");
2084 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2085 MODULE_PARM(strictmode, "i");
2086 MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
2087 #endif
2088 #endif /* MODULE */
2089
2090 MODULE_AUTHOR("Ani Joshi, maintainer");
2091 MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
2092 MODULE_LICENSE("GPL");