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