2 * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver
4 * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
6 * Copyright 1999-2000 Jeff Garzik
10 * Ani Joshi: Lots of debugging and cleanup work, really helped
11 * get the driver going
13 * Ferenc Bakonyi: Bug fixes, cleanup, modularization
15 * Jindrich Makovicka: Accel code help, hw cursor, mtrr
17 * Paul Richards: Bug fixes, updates
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.
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
27 * Known bugs and issues:
28 * restoring text mode fails
29 * doublescan modes are broken
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>
38 #include <linux/tty.h>
39 #include <linux/slab.h>
40 #include <linux/delay.h>
42 #include <linux/init.h>
43 #include <linux/pci.h>
49 #include <asm/pci-bridge.h>
55 #ifndef CONFIG_PCI /* sanity check */
56 #error This driver requires PCI support.
59 /* version number of this driver */
60 #define RIVAFB_VERSION "0.9.5b"
62 /* ------------------------------------------------------------------------- *
64 * various helpful macros and constants
66 * ------------------------------------------------------------------------- */
70 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
72 #define DPRINTK(fmt, args...)
76 #define assert(expr) \
78 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
79 #expr,__FILE__,__FUNCTION__,__LINE__); \
86 #define PFX "rivafb: "
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)
93 /* HW cursor parameters */
96 /* ------------------------------------------------------------------------- *
100 * ------------------------------------------------------------------------- */
102 static int rivafb_blank(int blank, struct fb_info *info);
104 /* ------------------------------------------------------------------------- *
106 * card identification
108 * ------------------------------------------------------------------------- */
134 CH_GEFORCE4_420_GO_M32,
136 CH_GEFORCE4_440_GO_M64,
153 /* directly indexed by riva_chips enum, above */
154 static struct riva_chip_info {
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 }
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 */
283 MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
285 /* ------------------------------------------------------------------------- *
289 * ------------------------------------------------------------------------- */
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;
296 static int nomtrr __initdata = 0;
299 static char *mode_option __initdata = NULL;
300 static int strictmode = 0;
302 static struct fb_fix_screeninfo rivafb_fix = {
304 .type = FB_TYPE_PACKED_PIXELS,
309 static struct fb_var_screeninfo rivafb_default_var = {
319 .activate = FB_ACTIVATE_NOW,
322 .accel_flags = FB_ACCELF_TEXT,
330 .vmode = FB_VMODE_NONINTERLACED
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,
348 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */
350 {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */
354 /* ------------------------------------------------------------------------- *
358 * ------------------------------------------------------------------------- */
360 static inline void CRTCout(struct riva_par *par, unsigned char index,
363 VGA_WR08(par->riva.PCIO, 0x3d4, index);
364 VGA_WR08(par->riva.PCIO, 0x3d5, val);
367 static inline unsigned char CRTCin(struct riva_par *par,
370 VGA_WR08(par->riva.PCIO, 0x3d4, index);
371 return (VGA_RD08(par->riva.PCIO, 0x3d5));
374 static inline void GRAout(struct riva_par *par, unsigned char index,
377 VGA_WR08(par->riva.PVIO, 0x3ce, index);
378 VGA_WR08(par->riva.PVIO, 0x3cf, val);
381 static inline unsigned char GRAin(struct riva_par *par,
384 VGA_WR08(par->riva.PVIO, 0x3ce, index);
385 return (VGA_RD08(par->riva.PVIO, 0x3cf));
388 static inline void SEQout(struct riva_par *par, unsigned char index,
391 VGA_WR08(par->riva.PVIO, 0x3c4, index);
392 VGA_WR08(par->riva.PVIO, 0x3c5, val);
395 static inline unsigned char SEQin(struct riva_par *par,
398 VGA_WR08(par->riva.PVIO, 0x3c4, index);
399 return (VGA_RD08(par->riva.PVIO, 0x3c5));
402 static inline void ATTRout(struct riva_par *par, unsigned char index,
405 VGA_WR08(par->riva.PCIO, 0x3c0, index);
406 VGA_WR08(par->riva.PCIO, 0x3c0, val);
409 static inline unsigned char ATTRin(struct riva_par *par,
412 VGA_WR08(par->riva.PCIO, 0x3c0, index);
413 return (VGA_RD08(par->riva.PCIO, 0x3c1));
416 static inline void MISCout(struct riva_par *par, unsigned char val)
418 VGA_WR08(par->riva.PVIO, 0x3c2, val);
421 static inline unsigned char MISCin(struct riva_par *par)
423 return (VGA_RD08(par->riva.PVIO, 0x3cc));
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,
461 static inline void reverse_order(u32 *l)
464 *a = byte_rev[*a], a++;
465 *a = byte_rev[*a], a++;
466 *a = byte_rev[*a], a++;
470 /* ------------------------------------------------------------------------- *
474 * ------------------------------------------------------------------------- */
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)
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.
494 static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
495 u16 bg, u16 fg, u32 w, u32 h)
499 u32 *data = (u32 *)data8;
501 for (i = 0; i < h; i++) {
505 for (j = 0; j < w/2; j++) {
507 #if defined (__BIG_ENDIAN)
508 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
510 tmp |= (b & (1 << 31)) ? fg : bg;
513 tmp = (b & 1) ? fg : bg;
515 tmp |= (b & 1) ? fg << 16 : bg << 16;
518 writel(tmp, &par->riva.CURSOR[k++]);
520 k += (MAX_CURS - w)/2;
524 /* ------------------------------------------------------------------------- *
526 * general utility functions
528 * ------------------------------------------------------------------------- */
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
539 * Sets color register @regnum.
544 static void riva_wclut(RIVA_HW_INST *chip,
545 unsigned char regnum, unsigned char red,
546 unsigned char green, unsigned char blue)
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);
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
563 * Reads red, green, and blue from color register @regnum.
568 static void riva_rclut(RIVA_HW_INST *chip,
569 unsigned char regnum, unsigned char *red,
570 unsigned char *green, unsigned char *blue)
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);
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
585 * Saves current chip state to @regs.
591 static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
595 par->riva.LockUnlock(&par->riva, 0);
597 par->riva.UnloadStateExt(&par->riva, ®s->ext);
599 regs->misc_output = MISCin(par);
601 for (i = 0; i < NUM_CRT_REGS; i++)
602 regs->crtc[i] = CRTCin(par, i);
604 for (i = 0; i < NUM_ATC_REGS; i++)
605 regs->attr[i] = ATTRin(par, i);
607 for (i = 0; i < NUM_GRC_REGS; i++)
608 regs->gra[i] = GRAin(par, i);
610 for (i = 0; i < NUM_SEQ_REGS; i++)
611 regs->seq[i] = SEQin(par, i);
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
620 * Loads chip state from @regs.
623 * riva_load_video_mode()
628 static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
630 RIVA_HW_STATE *state = ®s->ext;
633 CRTCout(par, 0x11, 0x00);
635 par->riva.LockUnlock(&par->riva, 0);
637 par->riva.LoadStateExt(&par->riva, state);
639 MISCout(par, regs->misc_output);
641 for (i = 0; i < NUM_CRT_REGS; i++) {
647 CRTCout(par, i, regs->crtc[i]);
651 for (i = 0; i < NUM_ATC_REGS; i++)
652 ATTRout(par, i, regs->attr[i]);
654 for (i = 0; i < NUM_GRC_REGS; i++)
655 GRAout(par, i, regs->gra[i]);
657 for (i = 0; i < NUM_SEQ_REGS; i++)
658 SEQout(par, i, regs->seq[i]);
662 * riva_load_video_mode - calculate timings
663 * @info: pointer to fb_info object containing info for current riva board
666 * Calculate some timings and then send em off to riva_load_state().
671 static void riva_load_video_mode(struct fb_info *info)
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;
679 /* time to calculate */
680 rivafb_blank(1, info);
682 bpp = info->var.bits_per_pixel;
683 if (bpp == 16 && info->var.green.length == 5)
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;
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;
707 memcpy(&newmode, ®_template, sizeof(struct riva_regs));
709 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
712 if (par->FlatPanel) {
715 vBlankStart = vStart;
718 hBlankEnd = hTotal + 4;
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)
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)
739 newmode.crtc[0x10] = Set8Bits (vStart);
740 newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
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);
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);
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);
766 newmode.ext.interlace = 0xff; /* interlace off */
768 if (par->riva.Architecture >= NV_ARCH_10)
769 par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart);
771 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
772 newmode.misc_output &= ~0x40;
774 newmode.misc_output |= 0x40;
775 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
776 newmode.misc_output &= ~0x80;
778 newmode.misc_output |= 0x80;
780 par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
781 hDisplaySize, height, dotClock);
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);
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];
800 if (par->FlatPanel == 1) {
801 newmode.ext.pixel |= (1 << 7);
802 newmode.ext.scale |= (1 << 8);
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);
811 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
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;
830 * rivafb_do_maximize -
831 * @info: pointer to fb_info object containing info for current riva board
840 * -EINVAL on failure, 0 on success
846 static int rivafb_do_maximize(struct fb_info *info,
847 struct fb_var_screeninfo *var,
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 <
871 if (modes[i].xres == -1) {
873 "could not find a virtual resolution that fits into video memory!!\n");
874 DPRINTK("EXIT - EINVAL error\n");
877 var->xres_virtual = modes[i].xres;
878 var->yres_virtual = modes[i].yres;
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);
895 var->xres_virtual = (var->xres_virtual + 15) & ~15;
896 if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
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");
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;
912 if (var->xres_virtual < var->xres) {
914 "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
918 if (var->yres_virtual < var->yres) {
920 "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
923 if (var->xres_virtual > 0x7fff)
924 var->xres_virtual = 0x7fff;
925 if (var->yres_virtual > 0x7fff)
926 var->yres_virtual = 0x7fff;
931 riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
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;
940 /* acceleration routines */
941 inline void wait_for_idle(struct riva_par *par)
943 while (par->riva.Busy(&par->riva));
947 * Set ROP. Translate X rop into ROP3. Internal routine.
950 riva_set_rop_solid(struct riva_par *par, int rop)
952 riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
953 RIVA_FIFO_FREE(par->riva, Rop, 1);
954 par->riva.Rop->Rop3 = rop;
958 void riva_setup_accel(struct riva_par *par)
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);
968 * riva_get_cmap_len - query current color map length
969 * @var: standard kernel fb changeable data
972 * Get current color map length.
975 * Length of color map
980 static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
982 int rc = 256; /* reasonable default */
984 switch (var->green.length) {
986 rc = 256; /* 256 entries (2^8), 8 bpp and RGB8888 */
989 rc = 32; /* 32 entries (2^5), 16 bpp, RGB555 */
992 rc = 64; /* 64 entries (2^6), 16 bpp, RGB565 */
995 /* should not occur */
1001 /* ------------------------------------------------------------------------- *
1003 * framebuffer operations
1005 * ------------------------------------------------------------------------- */
1007 static int rivafb_open(struct fb_info *info, int user)
1009 struct riva_par *par = (struct riva_par *) info->par;
1010 int cnt = atomic_read(&par->ref_count);
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);
1020 RivaGetConfig(&par->riva, par->Chipset);
1021 /* vgaHWunlock() + riva unlock (0x7F) */
1022 CRTCout(par, 0x11, 0xFF);
1023 par->riva.LockUnlock(&par->riva, 0);
1025 riva_save_state(par, &par->initial_state);
1027 atomic_inc(&par->ref_count);
1031 static int rivafb_release(struct fb_info *info, int user)
1033 struct riva_par *par = (struct riva_par *) info->par;
1034 int cnt = atomic_read(&par->ref_count);
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);
1045 atomic_dec(&par->ref_count);
1049 static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1051 struct fb_monspecs *specs = &info->monspecs;
1052 int nom, den; /* translating from pixels->bytes */
1055 switch (var->bits_per_pixel) {
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;
1063 var->green.length = 5;
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;
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;
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;
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");
1105 if (!fb_validate_mode(var, info))
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;
1113 best_refresh = best = best_x = best_y = 0;
1114 diff_x = diff_y = -1;
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;
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;
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;
1154 riva_update_var(var, &specs->modedb[best]);
1159 /* calculate modeline if supported by monitor */
1160 if (!mode_valid && info->monspecs.gtf) {
1161 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1164 if (!mode_valid && info->monspecs.modedb_len)
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)
1174 if (var->xoffset < 0)
1176 if (var->yoffset < 0)
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;
1183 if (var->yoffset > var->yres_virtual - var->yres)
1184 var->yoffset = var->yres_virtual - var->yres - 1;
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;
1193 static int rivafb_set_par(struct fb_info *info)
1195 struct riva_par *par = (struct riva_par *) info->par;
1197 riva_load_video_mode(info);
1198 riva_setup_accel(par);
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;
1207 * rivafb_pan_display
1208 * @var: standard kernel fb changeable data
1210 * @info: pointer to fb_info object containing info for current riva board
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.
1217 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1219 static int rivafb_pan_display(struct fb_var_screeninfo *var,
1220 struct fb_info *info)
1222 struct riva_par *par = (struct riva_par *)info->par;
1225 if (var->xoffset > (var->xres_virtual - var->xres))
1227 if (var->yoffset > (var->yres_virtual - var->yres))
1230 if (var->vmode & FB_VMODE_YWRAP) {
1231 if (var->yoffset < 0
1232 || var->yoffset >= info->var.yres_virtual
1233 || var->xoffset) return -EINVAL;
1235 if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1236 var->yoffset + info->var.yres > info->var.yres_virtual)
1240 base = var->yoffset * info->fix.line_length + var->xoffset;
1242 par->riva.SetStartAddress(&par->riva, base);
1244 info->var.xoffset = var->xoffset;
1245 info->var.yoffset = var->yoffset;
1247 if (var->vmode & FB_VMODE_YWRAP)
1248 info->var.vmode |= FB_VMODE_YWRAP;
1250 info->var.vmode &= ~FB_VMODE_YWRAP;
1254 static int rivafb_blank(int blank, struct fb_info *info)
1256 struct riva_par *par= (struct riva_par *)info->par;
1257 unsigned char tmp, vesa;
1259 tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
1260 vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */
1264 switch (blank - 1) {
1265 case VESA_NO_BLANKING:
1267 case VESA_VSYNC_SUSPEND:
1270 case VESA_HSYNC_SUSPEND:
1273 case VESA_POWERDOWN:
1278 SEQout(par, 0x01, tmp);
1279 CRTCout(par, 0x1a, vesa);
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
1293 * Set a single color register. The values supplied have a 16 bit
1297 * Return != 0 for invalid regno.
1300 * fbcmap.c:fb_set_cmap()
1302 static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1303 unsigned blue, unsigned transp,
1304 struct fb_info *info)
1306 struct riva_par *par = (struct riva_par *)info->par;
1307 RIVA_HW_INST *chip = &par->riva;
1310 if (regno >= riva_get_cmap_len(&info->var))
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;
1319 switch (info->var.bits_per_pixel) {
1321 /* "transparent" stuff is completely ignored. */
1322 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1325 if (info->var.green.length == 5) {
1327 /* 0rrrrrgg gggbbbbb */
1328 ((u32 *)info->pseudo_palette)[regno] =
1329 ((red & 0xf800) >> 1) |
1330 ((green & 0xf800) >> 6) |
1331 ((blue & 0xf800) >> 11);
1333 for (i = 0; i < 8; i++)
1334 riva_wclut(chip, regno*8+i, red >> 8,
1335 green >> 8, blue >> 8);
1340 /* rrrrrggg gggbbbbb */
1341 ((u32 *)info->pseudo_palette)[regno] =
1342 ((red & 0xf800) >> 0) |
1343 ((green & 0xf800) >> 5) |
1344 ((blue & 0xf800) >> 11);
1347 for (i = 0; i < 8; i++) {
1348 riva_wclut(chip, regno*8+i, red >> 8,
1349 green >> 8, blue >> 8);
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);
1360 ((u32 *)info->pseudo_palette)[regno] =
1361 ((red & 0xff00) << 8) |
1362 ((green & 0xff00)) | ((blue & 0xff00) >> 8);
1365 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1375 * rivafb_fillrect - hardware accelerated color fill function
1376 * @info: pointer to fb_info structure
1377 * @rect: pointer to fb_fillrect structure
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.
1386 static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1388 struct riva_par *par = (struct riva_par *) info->par;
1389 u_int color, rop = 0;
1391 if (info->var.bits_per_pixel == 8)
1392 color = rect->color;
1394 color = ((u32 *)info->pseudo_palette)[rect->color];
1396 switch (rect->rop) {
1406 riva_set_rop_solid(par, rop);
1408 RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1409 par->riva.Bitmap->Color1A = color;
1411 RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1412 par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
1413 (rect->dx << 16) | rect->dy;
1415 par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
1416 (rect->width << 16) | rect->height;
1418 riva_set_rop_solid(par, 0xcc);
1423 * rivafb_copyarea - hardware accelerated blit function
1424 * @info: pointer to fb_info structure
1425 * @region: pointer to fb_copyarea structure
1428 * This copies an area of pixels from one location to another
1433 static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1435 struct riva_par *par = (struct riva_par *) info->par;
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;
1441 par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
1445 static inline void convert_bgcolor_16(u32 *col)
1447 *col = ((*col & 0x00007C00) << 9)
1448 | ((*col & 0x000003E0) << 6)
1449 | ((*col & 0x0000001F) << 3)
1455 * rivafb_imageblit: hardware accelerated color expand function
1456 * @info: pointer to fb_info structure
1457 * @image: pointer to fb_image structure
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.
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.
1470 static void rivafb_imageblit(struct fb_info *info,
1471 const struct fb_image *image)
1473 struct riva_par *par = (struct riva_par *) info->par;
1474 u32 fgx = 0, bgx = 0, width, tmp;
1475 u8 *cdat = (u8 *) image->data;
1479 if (image->depth != 1) {
1480 cfb_imageblit(info, image);
1484 switch (info->var.bits_per_pixel) {
1486 fgx = image->fg_color;
1487 bgx = image->bg_color;
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);
1496 fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1497 bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
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);
1516 d = &par->riva.Bitmap->MonochromeData01E;
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);
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);
1542 * rivafb_cursor - hardware cursor function
1543 * @info: pointer to info structure
1544 * @cursor: pointer to fbcursor structure
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.
1554 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1556 struct riva_par *par = (struct riva_par *) info->par;
1557 u8 data[MAX_CURS * MAX_CURS/8];
1561 par->riva.ShowHideCursor(&par->riva, 0);
1563 if (cursor->set & FB_CUR_SETPOS) {
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;
1573 par->riva.PRAMDAC[0x0000300/4] = temp;
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);
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;
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;
1596 info->cursor.image.data = cursor->image.data;
1597 switch (info->cursor.rop) {
1599 for (i = 0; i < s_pitch * info->cursor.image.height;
1601 src[i] = dat[i] ^ msk[i];
1605 for (i = 0; i < s_pitch * info->cursor.image.height;
1607 src[i] = dat[i] & msk[i];
1611 fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
1612 s_pitch, info->cursor.image.height);
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;
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;
1622 par->riva.LockUnlock(&par->riva, 0);
1624 rivafb_load_cursor_image(par, data, bg, fg,
1625 info->cursor.image.width,
1626 info->cursor.image.height);
1628 if (info->cursor.enable)
1629 par->riva.ShowHideCursor(&par->riva, 1);
1633 static int rivafb_sync(struct fb_info *info)
1635 struct riva_par *par = (struct riva_par *)info->par;
1641 /* ------------------------------------------------------------------------- *
1643 * initialization helper functions
1645 * ------------------------------------------------------------------------- */
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,
1664 static int __devinit riva_set_fbinfo(struct fb_info *info)
1666 unsigned int cmap_len;
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;
1679 cmap_len = riva_get_cmap_len(&info->var);
1680 fb_alloc_cmap(&info->cmap, cmap_len, 0);
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));
1690 #ifdef CONFIG_PPC_OF
1691 static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
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 };
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)
1706 if (strncmp(disptype, "LCD", 3) != 0)
1708 for (i = 0; propnames[i] != NULL; ++i) {
1709 pedid = (unsigned char *)
1710 get_property(dp, propnames[i], NULL);
1711 if (pedid != NULL) {
1719 #endif /* CONFIG_PPC_OF */
1721 static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
1723 struct fb_monspecs *specs = &info->monspecs;
1724 struct fb_videomode modedb;
1726 /* respect mode options */
1728 fb_find_mode(var, info, mode_option,
1729 specs->modedb, specs->modedb_len,
1731 } else if (specs->modedb != NULL) {
1732 /* get preferred timing */
1733 if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
1736 for (i = 0; i < specs->modedb_len; i++) {
1737 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1738 modedb = specs->modedb[i];
1743 /* otherwise, get first mode in database */
1744 modedb = specs->modedb[0];
1746 var->bits_per_pixel = 8;
1747 riva_update_var(var, &modedb);
1749 var->accel_flags |= FB_ACCELF_TEXT;
1753 static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1755 #ifdef CONFIG_PPC_OF
1756 if (!riva_get_EDID_OF(info, pdev))
1757 printk("rivafb: could not retrieve EDID from OF\n");
1759 /* XXX use other methods later */
1760 #ifdef CONFIG_FB_RIVA_I2C
1761 struct riva_par *par = (struct riva_par *) info->par;
1763 riva_create_i2c_busses(par);
1764 riva_probe_i2c_connector(par, 1, &par->EDID);
1765 riva_delete_i2c_busses(par);
1771 static void riva_get_edidinfo(struct fb_info *info)
1773 struct fb_var_screeninfo *var = &rivafb_default_var;
1774 struct riva_par *par = (struct riva_par *) info->par;
1776 fb_edid_to_monspecs(par->EDID, &info->monspecs);
1777 riva_update_default_var(var, info);
1779 /* if user specified flatpanel, we respect that */
1780 if (info->monspecs.input & FB_DISP_DDI)
1784 /* ------------------------------------------------------------------------- *
1788 * ------------------------------------------------------------------------- */
1790 static int __devinit rivafb_probe(struct pci_dev *pd,
1791 const struct pci_device_id *ent)
1793 struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1794 struct riva_par *default_par;
1795 struct fb_info *info;
1798 assert(rci != NULL);
1800 info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
1804 default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
1808 memset(info, 0, sizeof(struct fb_info));
1809 memset(default_par, 0, sizeof(struct riva_par));
1810 default_par->pdev = pd;
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);
1817 strcat(rivafb_fix.id, rci->name);
1818 default_par->riva.Architecture = rci->arch_rev;
1820 default_par->Chipset = (pd->vendor << 16) | pd->device;
1821 printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1823 default_par->FlatPanel = flatpanel;
1825 printk(KERN_INFO PFX "flatpanel support enabled\n");
1826 default_par->forceCRTC = forceCRTC;
1828 rivafb_fix.mmio_len = pci_resource_len(pd, 0);
1829 rivafb_fix.smem_len = pci_resource_len(pd, 1);
1832 /* enable IO and mem if not already done */
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);
1840 rivafb_fix.mmio_start = pci_resource_start(pd, 0);
1841 rivafb_fix.smem_start = pci_resource_start(pd, 1);
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;
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;
1856 info->par = default_par;
1858 switch (default_par->riva.Architecture) {
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.
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;
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;
1874 rivafb_fix.accel = FB_ACCEL_NV3;
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;
1885 riva_common_setup(default_par);
1887 if (default_par->riva.Architecture == NV_ARCH_03) {
1888 default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
1891 rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
1892 default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
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;
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;
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");
1915 default_par->mtrr.vram_valid = 1;
1916 /* let there be speed */
1917 printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
1920 #endif /* CONFIG_MTRR */
1922 info->fbops = &riva_fb_ops;
1923 info->fix = rivafb_fix;
1924 riva_get_EDID(info, pd);
1925 riva_get_edidinfo(info);
1927 if (riva_set_fbinfo(info) < 0) {
1928 printk(KERN_ERR PFX "error setting initial video mode\n");
1929 goto err_out_iounmap_fb;
1932 if (register_framebuffer(info) < 0) {
1934 "error registering riva framebuffer\n");
1935 goto err_out_iounmap_fb;
1938 pci_set_drvdata(pd, info);
1940 printk(KERN_INFO PFX
1941 "PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
1942 default_par->riva.Architecture,
1945 info->fix.smem_len / (1024 * 1024),
1946 info->fix.smem_start);
1950 iounmap(info->screen_base);
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);
1962 release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
1964 kfree(info->pixmap.addr);
1973 static void __exit rivafb_remove(struct pci_dev *pd)
1975 struct fb_info *info = pci_get_drvdata(pd);
1976 struct riva_par *par = (struct riva_par *) info->par;
1981 unregister_framebuffer(info);
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 */
1988 iounmap(par->ctrl_base);
1989 iounmap(info->screen_base);
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);
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);
2000 kfree(info->pixmap.addr);
2003 pci_set_drvdata(pd, NULL);
2006 /* ------------------------------------------------------------------------- *
2010 * ------------------------------------------------------------------------- */
2013 int __init rivafb_setup(char *options)
2017 if (!options || !*options)
2020 while ((this_opt = strsep(&options, ",")) != NULL) {
2021 if (!strncmp(this_opt, "forceCRTC", 9)) {
2025 if (!*p || !*(++p)) continue;
2026 forceCRTC = *p - '0';
2027 if (forceCRTC < 0 || forceCRTC > 1)
2029 } else if (!strncmp(this_opt, "flatpanel", 9)) {
2032 } else if (!strncmp(this_opt, "nomtrr", 6)) {
2035 } else if (!strncmp(this_opt, "strictmode", 10)) {
2038 mode_option = this_opt;
2042 #endif /* !MODULE */
2044 static struct pci_driver rivafb_driver = {
2046 .id_table = rivafb_pci_tbl,
2047 .probe = rivafb_probe,
2048 .remove = __exit_p(rivafb_remove),
2053 /* ------------------------------------------------------------------------- *
2057 * ------------------------------------------------------------------------- */
2059 int __init rivafb_init(void)
2061 if (pci_register_driver(&rivafb_driver) > 0)
2063 pci_unregister_driver(&rivafb_driver);
2069 static void __exit rivafb_exit(void)
2071 pci_unregister_driver(&rivafb_driver);
2074 module_init(rivafb_init);
2075 module_exit(rivafb_exit);
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)");
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");
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");