File: /usr/src/linux/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      * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
18      * Includes riva_hw.c from nVidia, see copyright below.
19      * KGI code provided the basis for state storage, init, and mode switching.
20      *
21      * This file is subject to the terms and conditions of the GNU General Public
22      * License.  See the file COPYING in the main directory of this archive
23      * for more details.
24      *
25      * Known bugs and issues:
26      *	restoring text mode fails
27      *	doublescan modes are broken
28      *	option 'noaccel' has no effect
29      */
30     
31     #include <linux/config.h>
32     #include <linux/module.h>
33     #include <linux/kernel.h>
34     #include <linux/errno.h>
35     #include <linux/string.h>
36     #include <linux/mm.h>
37     #include <linux/selection.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     #include <linux/console.h>
45     #ifdef CONFIG_MTRR
46     #include <asm/mtrr.h>
47     #endif
48     #include "rivafb.h"
49     #include "nvreg.h"
50     
51     #ifndef CONFIG_PCI		/* sanity check */
52     #error This driver requires PCI support.
53     #endif
54     
55     
56     
57     /* version number of this driver */
58     #define RIVAFB_VERSION "0.9.2a"
59     
60     
61     
62     /* ------------------------------------------------------------------------- *
63      *
64      * various helpful macros and constants
65      *
66      * ------------------------------------------------------------------------- */
67     
68     #undef RIVAFBDEBUG
69     #ifdef RIVAFBDEBUG
70     #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
71     #else
72     #define DPRINTK(fmt, args...)
73     #endif
74     
75     #ifndef RIVA_NDEBUG
76     #define assert(expr) \
77     	if(!(expr)) { \
78     	printk( "Assertion failed! %s,%s,%s,line=%d\n",\
79     	#expr,__FILE__,__FUNCTION__,__LINE__); \
80     	BUG(); \
81     	}
82     #else
83     #define assert(expr)
84     #endif
85     
86     #define PFX "rivafb: "
87     
88     /* macro that allows you to set overflow bits */
89     #define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
90     #define SetBit(n)		(1<<(n))
91     #define Set8Bits(value)		((value)&0xff)
92     
93     /* HW cursor parameters */
94     #define DEFAULT_CURSOR_BLINK_RATE	(40)
95     #define CURSOR_HIDE_DELAY		(20)
96     #define CURSOR_SHOW_DELAY		(3)
97     
98     #define CURSOR_COLOR		0x7fff
99     #define TRANSPARENT_COLOR	0x0000
100     #define MAX_CURS		32
101     
102     
103     
104     /* ------------------------------------------------------------------------- *
105      *
106      * prototypes
107      *
108      * ------------------------------------------------------------------------- */
109     
110     static void rivafb_blank(int blank, struct fb_info *info);
111     
112     extern void riva_setup_accel(struct rivafb_info *rinfo);
113     extern inline void wait_for_idle(struct rivafb_info *rinfo);
114     
115     
116     
117     /* ------------------------------------------------------------------------- *
118      *
119      * card identification
120      *
121      * ------------------------------------------------------------------------- */
122     
123     enum riva_chips {
124     	CH_RIVA_128 = 0,
125     	CH_RIVA_TNT,
126     	CH_RIVA_TNT2,
127     	CH_RIVA_UTNT2,	/* UTNT2 */
128     	CH_RIVA_VTNT2,	/* VTNT2 */
129     	CH_RIVA_UVTNT2,	/* VTNT2 */
130     	CH_RIVA_ITNT2,	/* ITNT2 */
131     	CH_GEFORCE_SDR,
132     	CH_GEFORCE_DDR,
133     	CH_QUADRO,
134     	CH_GEFORCE2_MX,
135     	CH_QUADRO2_MXR,
136     	CH_GEFORCE2_GTS,
137     	CH_GEFORCE2_ULTRA,
138     	CH_QUADRO2_PRO,
139     };
140     
141     /* directly indexed by riva_chips enum, above */
142     static struct riva_chip_info {
143     	const char *name;
144     	unsigned arch_rev;
145     } riva_chip_info[] __devinitdata = {
146     	{ "RIVA-128", NV_ARCH_03 },
147     	{ "RIVA-TNT", NV_ARCH_04 },
148     	{ "RIVA-TNT2", NV_ARCH_04 },
149     	{ "RIVA-UTNT2", NV_ARCH_04 },
150     	{ "RIVA-VTNT2", NV_ARCH_04 },
151     	{ "RIVA-UVTNT2", NV_ARCH_04 },
152     	{ "RIVA-ITNT2", NV_ARCH_04 },
153     	{ "GeForce-SDR", NV_ARCH_10},
154     	{ "GeForce-DDR", NV_ARCH_10},
155     	{ "Quadro", NV_ARCH_10},
156     	{ "GeForce2-MX", NV_ARCH_10},
157     	{ "Quadro2-MXR", NV_ARCH_10},
158     	{ "GeForce2-GTS", NV_ARCH_10},
159     	{ "GeForce2-ULTRA", NV_ARCH_10},
160     	{ "Quadro2-PRO", NV_ARCH_10},
161     };
162     
163     static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
164     	{ PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
165     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_128 },
166     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
167     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT },
168     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
169     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT2 },
170     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
171     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_UTNT2 },
172     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
173     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
174     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
175     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
176     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
177     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_ITNT2 },
178     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
179     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_SDR },
180     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
181     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_DDR },
182     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
183     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO },
184     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
185     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX },
186     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
187     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX },
188     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
189     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_MXR },
190     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
191     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS },
192     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
193     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS },
194     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
195     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_ULTRA },
196     	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
197     	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_PRO },
198     	{ 0, } /* terminate list */
199     };
200     MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
201     
202     
203     
204     /* ------------------------------------------------------------------------- *
205      *
206      * framebuffer related structures
207      *
208      * ------------------------------------------------------------------------- */
209     
210     #ifdef FBCON_HAS_CFB8
211     extern struct display_switch fbcon_riva8;
212     #endif
213     #ifdef FBCON_HAS_CFB16
214     extern struct display_switch fbcon_riva16;
215     #endif
216     #ifdef FBCON_HAS_CFB32
217     extern struct display_switch fbcon_riva32;
218     #endif
219     
220     #if 0
221     /* describes the state of a Riva board */
222     struct rivafb_par {
223     	struct riva_regs state;	/* state of hw board */
224     	__u32 visual;		/* FB_VISUAL_xxx */
225     	unsigned depth;		/* bpp of current mode */
226     };
227     #endif
228     
229     struct riva_cursor {
230     	int enable;
231     	int on;
232     	int vbl_cnt;
233     	int last_move_delay;
234     	int blink_rate;
235     	struct {
236     		u16 x, y;
237     	} pos, size;
238     	unsigned short image[MAX_CURS*MAX_CURS];
239     	struct timer_list *timer;
240     };
241     
242     
243     
244     /* ------------------------------------------------------------------------- *
245      *
246      * global variables
247      *
248      * ------------------------------------------------------------------------- */
249     
250     struct rivafb_info *riva_boards = NULL;
251     
252     /* command line data, set in rivafb_setup() */
253     static char fontname[40] __initdata = { 0 };
254     static char noaccel __initdata = 0;
255     static char nomove = 0;
256     static char nohwcursor __initdata = 0;
257     static char noblink = 0;
258     #ifdef CONFIG_MTRR
259     static char nomtrr __initdata = 0;
260     #endif
261     
262     #ifndef MODULE
263     static char *mode_option __initdata = NULL;
264     #else
265     static char *font = NULL;
266     #endif
267     
268     static struct fb_var_screeninfo rivafb_default_var = {
269     	xres:		640,
270     	yres:		480,
271     	xres_virtual:	640,
272     	yres_virtual:	480,
273     	xoffset:	0,
274     	yoffset:	0,
275     	bits_per_pixel:	8,
276     	grayscale:	0,
277     	red:		{0, 6, 0},
278     	green:		{0, 6, 0},
279     	blue:		{0, 6, 0},
280     	transp:		{0, 0, 0},
281     	nonstd:		0,
282     	activate:	0,
283     	height:		-1,
284     	width:		-1,
285     	accel_flags:	0,
286     	pixclock:	39721,
287     	left_margin:	40,
288     	right_margin:	24,
289     	upper_margin:	32,
290     	lower_margin:	11,
291     	hsync_len:	96,
292     	vsync_len:	2,
293     	sync:		0,
294     	vmode:		FB_VMODE_NONINTERLACED
295     };
296     
297     /* from GGI */
298     static const struct riva_regs reg_template = {
299     	{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* ATTR */
300     	 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
301     	 0x41, 0x01, 0x0F, 0x00, 0x00},
302     	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* CRT  */
303     	 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
304     	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3,	/* 0x10 */
305     	 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306     	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x20 */
307     	 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308     	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x30 */
309     	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310     	 0x00,							/* 0x40 */
311     	 },
312     	{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,	/* GRA  */
313     	 0xFF},
314     	{0x03, 0x01, 0x0F, 0x00, 0x0E},				/* SEQ  */
315     	0xEB							/* MISC */
316     };
317     
318     
319     
320     /* ------------------------------------------------------------------------- *
321      *
322      * MMIO access macros
323      *
324      * ------------------------------------------------------------------------- */
325     
326     static inline void CRTCout(struct rivafb_info *rinfo, unsigned char index,
327     			   unsigned char val)
328     {
329     	VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
330     	VGA_WR08(rinfo->riva.PCIO, 0x3d5, val);
331     }
332     
333     static inline unsigned char CRTCin(struct rivafb_info *rinfo,
334     				   unsigned char index)
335     {
336     	VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
337     	return (VGA_RD08(rinfo->riva.PCIO, 0x3d5));
338     }
339     
340     static inline void GRAout(struct rivafb_info *rinfo, unsigned char index,
341     			  unsigned char val)
342     {
343     	VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
344     	VGA_WR08(rinfo->riva.PVIO, 0x3cf, val);
345     }
346     
347     static inline unsigned char GRAin(struct rivafb_info *rinfo,
348     				  unsigned char index)
349     {
350     	VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
351     	return (VGA_RD08(rinfo->riva.PVIO, 0x3cf));
352     }
353     
354     static inline void SEQout(struct rivafb_info *rinfo, unsigned char index,
355     			  unsigned char val)
356     {
357     	VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
358     	VGA_WR08(rinfo->riva.PVIO, 0x3c5, val);
359     }
360     
361     static inline unsigned char SEQin(struct rivafb_info *rinfo,
362     				  unsigned char index)
363     {
364     	VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
365     	return (VGA_RD08(rinfo->riva.PVIO, 0x3c5));
366     }
367     
368     static inline void ATTRout(struct rivafb_info *rinfo, unsigned char index,
369     			   unsigned char val)
370     {
371     	VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
372     	VGA_WR08(rinfo->riva.PCIO, 0x3c0, val);
373     }
374     
375     static inline unsigned char ATTRin(struct rivafb_info *rinfo,
376     				   unsigned char index)
377     {
378     	VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
379     	return (VGA_RD08(rinfo->riva.PCIO, 0x3c1));
380     }
381     
382     static inline void MISCout(struct rivafb_info *rinfo, unsigned char val)
383     {
384     	VGA_WR08(rinfo->riva.PVIO, 0x3c2, val);
385     }
386     
387     static inline unsigned char MISCin(struct rivafb_info *rinfo)
388     {
389     	return (VGA_RD08(rinfo->riva.PVIO, 0x3cc));
390     }
391     
392     
393     
394     /* ------------------------------------------------------------------------- *
395      *
396      * cursor stuff
397      *
398      * ------------------------------------------------------------------------- */
399     
400     /**
401      * riva_cursor_timer_handler - blink timer
402      * @dev_addr: pointer to rivafb_info object containing info for current riva board
403      *
404      * DESCRIPTION:
405      * Cursor blink timer.
406      */
407     static void riva_cursor_timer_handler(unsigned long dev_addr)
408     {
409     	struct rivafb_info *rinfo = (struct rivafb_info *)dev_addr;
410     
411     	if (!rinfo->cursor) return;
412     
413     	if (!rinfo->cursor->enable) goto out;
414     
415     	if (rinfo->cursor->last_move_delay < 1000)
416     		rinfo->cursor->last_move_delay++;
417     
418     	if (rinfo->cursor->vbl_cnt && --rinfo->cursor->vbl_cnt == 0) {
419     		rinfo->cursor->on ^= 1;
420     		if (rinfo->cursor->on)
421     			*(rinfo->riva.CURSORPOS) = (rinfo->cursor->pos.x & 0xFFFF)
422     						   | (rinfo->cursor->pos.y << 16);
423     		rinfo->riva.ShowHideCursor(&rinfo->riva, rinfo->cursor->on);
424     		if (!noblink)
425     			rinfo->cursor->vbl_cnt = rinfo->cursor->blink_rate;
426     	}
427     out:
428     	rinfo->cursor->timer->expires = jiffies + (HZ / 100);
429     	add_timer(rinfo->cursor->timer);
430     }
431     
432     /**
433      * rivafb_init_cursor - allocates cursor structure and starts blink timer
434      * @rinfo: pointer to rivafb_info object containing info for current riva board
435      *
436      * DESCRIPTION:
437      * Allocates cursor structure and starts blink timer.
438      *
439      * RETURNS:
440      * Pointer to allocated cursor structure.
441      *
442      * CALLED FROM:
443      * rivafb_init_one()
444      */
445     static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
446     {
447     	struct riva_cursor *cursor;
448     
449     	cursor = kmalloc(sizeof(struct riva_cursor), GFP_KERNEL);
450     	if (!cursor) return 0;
451     	memset(cursor, 0, sizeof(*cursor));
452     
453     	cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
454     	if (!cursor->timer) {
455     		kfree(cursor);
456     		return 0;
457     	}
458     	memset(cursor->timer, 0, sizeof(*cursor->timer));
459     
460     	cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
461     
462     	init_timer(cursor->timer);
463     	cursor->timer->expires = jiffies + (HZ / 100);
464     	cursor->timer->data = (unsigned long)rinfo;
465     	cursor->timer->function = riva_cursor_timer_handler;
466     	add_timer(cursor->timer);
467     
468     	return cursor;
469     }
470     
471     /**
472      * rivafb_exit_cursor - stops blink timer and releases cursor structure
473      * @rinfo: pointer to rivafb_info object containing info for current riva board
474      *
475      * DESCRIPTION:
476      * Stops blink timer and releases cursor structure.
477      *
478      * CALLED FROM:
479      * rivafb_init_one()
480      * rivafb_remove_one()
481      */
482     static void rivafb_exit_cursor(struct rivafb_info *rinfo)
483     {
484     	struct riva_cursor *cursor = rinfo->cursor;
485     
486     	if (cursor) {
487     		if (cursor->timer) {
488     			del_timer_sync(cursor->timer);
489     			kfree(cursor->timer);
490     		}
491     		kfree(cursor);
492     		rinfo->cursor = 0;
493     	}
494     }
495     
496     /**
497      * rivafb_download_cursor - writes cursor shape into card registers
498      * @rinfo: pointer to rivafb_info object containing info for current riva board
499      *
500      * DESCRIPTION:
501      * Writes cursor shape into card registers.
502      *
503      * CALLED FROM:
504      * riva_load_video_mode()
505      */
506     static void rivafb_download_cursor(struct rivafb_info *rinfo)
507     {
508     	int i, save;
509     	int *image;
510     	
511     	if (!rinfo->cursor) return;
512     
513     	image = (int *)rinfo->cursor->image;
514     	save = rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
515     	for (i = 0; i < (MAX_CURS*MAX_CURS*2)/sizeof(int); i++)
516     		writel(image[i], rinfo->riva.CURSOR + i);
517     
518     	rinfo->riva.ShowHideCursor(&rinfo->riva, save);
519     }
520     
521     /**
522      * rivafb_create_cursor - sets rectangular cursor
523      * @rinfo: pointer to rivafb_info object containing info for current riva board
524      * @width: cursor width in pixels
525      * @height: cursor height in pixels
526      *
527      * DESCRIPTION:
528      * Sets rectangular cursor.
529      *
530      * CALLED FROM:
531      * rivafb_set_font()
532      * rivafb_set_var()
533      */
534     static void rivafb_create_cursor(struct rivafb_info *rinfo, int width, int height)
535     {
536     	struct riva_cursor *c = rinfo->cursor;
537     	int i, j, idx;
538     
539     	if (c) {
540     		if (width <= 0 || height <= 0) {
541     			width = 8;
542     			height = 16;
543     		}
544     		if (width > MAX_CURS) width = MAX_CURS;
545     		if (height > MAX_CURS) height = MAX_CURS;
546     
547     		c->size.x = width;
548     		c->size.y = height;
549     		
550     		idx = 0;
551     
552     		for (i = 0; i < height; i++) {
553     			for (j = 0; j < width; j++,idx++)
554     				c->image[idx] = CURSOR_COLOR;
555     			for (j = width; j < MAX_CURS; j++,idx++)
556     				c->image[idx] = TRANSPARENT_COLOR;
557     		}
558     		for (i = height; i < MAX_CURS; i++)
559     			for (j = 0; j < MAX_CURS; j++,idx++)
560     				c->image[idx] = TRANSPARENT_COLOR;
561     	}
562     }
563     
564     /**
565      * rivafb_set_font - change font size
566      * @p: pointer to display object
567      * @width: font width in pixels
568      * @height: font height in pixels
569      *
570      * DESCRIPTION:
571      * Callback function called if font settings changed.
572      *
573      * RETURNS:
574      * 1 (Always succeeds.)
575      */
576     static int rivafb_set_font(struct display *p, int width, int height)
577     {
578     	struct rivafb_info *fb = (struct rivafb_info *)(p->fb_info);
579     
580     	rivafb_create_cursor(fb, width, height);
581     	return 1;
582     }
583     
584     /**
585      * rivafb_cursor - cursor handler
586      * @p: pointer to display object
587      * @mode: cursor mode (see CM_*)
588      * @x: cursor x coordinate in characters
589      * @y: cursor y coordinate in characters
590      *
591      * DESCRIPTION:
592      * Cursor handler.
593      */
594     static void rivafb_cursor(struct display *p, int mode, int x, int y)
595     {
596     	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
597     	struct riva_cursor *c = rinfo->cursor;
598     
599     	if (!c)	return;
600     
601     	x = x * fontwidth(p) - p->var.xoffset;
602     	y = y * fontheight(p) - p->var.yoffset;
603     
604     	if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
605     		return;
606     
607     	c->enable = 0;
608     	if (c->on) rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
609     		
610     	c->pos.x = x;
611     	c->pos.y = y;
612     
613     	switch (mode) {
614     	case CM_ERASE:
615     		c->on = 0;
616     		break;
617     	case CM_DRAW:
618     	case CM_MOVE:
619     		if (c->last_move_delay <= 1) { /* rapid cursor movement */
620     			c->vbl_cnt = CURSOR_SHOW_DELAY;
621     		} else {
622     			*(rinfo->riva.CURSORPOS) = (x & 0xFFFF) | (y << 16);
623     			rinfo->riva.ShowHideCursor(&rinfo->riva, 1);
624     			if (!noblink) c->vbl_cnt = CURSOR_HIDE_DELAY;
625     			c->on = 1;
626     		}
627     		c->last_move_delay = 0;
628     		c->enable = 1;
629     		break;
630     	}
631     }
632     
633     
634     
635     /* ------------------------------------------------------------------------- *
636      *
637      * general utility functions
638      *
639      * ------------------------------------------------------------------------- */
640     
641     /**
642      * riva_set_dispsw - sets dispsw
643      * @rinfo: pointer to internal driver struct for a given Riva card
644      * @disp: pointer to display object
645      *
646      * DESCRIPTION:
647      * Sets up console low level operations depending on the current? color depth
648      * of the display.
649      *
650      * CALLED FROM:
651      * rivafb_set_var()
652      * rivafb_switch()
653      * riva_init_disp()
654      */
655     static void riva_set_dispsw(struct rivafb_info *rinfo, struct display *disp)
656     {
657     	int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
658     
659     	DPRINTK("ENTER\n");
660     
661     	assert(rinfo != NULL);
662     
663     	disp->dispsw_data = NULL;
664     
665     	disp->screen_base = rinfo->fb_base;
666     	disp->type = FB_TYPE_PACKED_PIXELS;
667     	disp->type_aux = 0;
668     	disp->ypanstep = 1;
669     	disp->ywrapstep = 0;
670     	disp->can_soft_blank = 1;
671     	disp->inverse = 0;
672     
673     	switch (disp->var.bits_per_pixel) {
674     #ifdef FBCON_HAS_CFB8
675     	case 8:
676     		rinfo->dispsw = accel ? fbcon_riva8 : fbcon_cfb8;
677     		disp->dispsw = &rinfo->dispsw;
678     		disp->line_length = disp->var.xres_virtual;
679     		disp->visual = FB_VISUAL_PSEUDOCOLOR;
680     		break;
681     #endif
682     #ifdef FBCON_HAS_CFB16
683     	case 16:
684     		rinfo->dispsw = accel ? fbcon_riva16 : fbcon_cfb16;
685     		disp->dispsw_data = &rinfo->con_cmap.cfb16;
686     		disp->dispsw = &rinfo->dispsw;
687     		disp->line_length = disp->var.xres_virtual * 2;
688     		disp->visual = FB_VISUAL_DIRECTCOLOR;
689     		break;
690     #endif
691     #ifdef FBCON_HAS_CFB32
692     	case 32:
693     		rinfo->dispsw = accel ? fbcon_riva32 : fbcon_cfb32;
694     		disp->dispsw_data = rinfo->con_cmap.cfb32;
695     		disp->dispsw = &rinfo->dispsw;
696     		disp->line_length = disp->var.xres_virtual * 4;
697     		disp->visual = FB_VISUAL_DIRECTCOLOR;
698     		break;
699     #endif
700     	default:
701     		DPRINTK("Setting fbcon_dummy renderer\n");
702     		rinfo->dispsw = fbcon_dummy;
703     		disp->dispsw = &rinfo->dispsw;
704     	}
705     
706     	/* FIXME: verify that the above code sets dsp->* fields correctly */
707     
708     	if (rinfo->cursor) {
709     		rinfo->dispsw.cursor = rivafb_cursor;
710     		rinfo->dispsw.set_font = rivafb_set_font;
711     	}
712     
713     	DPRINTK("EXIT\n");
714     }
715     
716     /**
717      * riva_wclut - set CLUT entry
718      * @chip: pointer to RIVA_HW_INST object
719      * @regnum: register number
720      * @red: red component
721      * @green: green component
722      * @blue: blue component
723      *
724      * DESCRIPTION:
725      * Sets color register @regnum.
726      *
727      * CALLED FROM:
728      * riva_setcolreg()
729      */
730     static void riva_wclut(RIVA_HW_INST *chip,
731     		       unsigned char regnum, unsigned char red,
732     		       unsigned char green, unsigned char blue)
733     {
734     	VGA_WR08(chip->PDIO, 0x3c8, regnum);
735     	VGA_WR08(chip->PDIO, 0x3c9, red);
736     	VGA_WR08(chip->PDIO, 0x3c9, green);
737     	VGA_WR08(chip->PDIO, 0x3c9, blue);
738     }
739     
740     /**
741      * riva_save_state - saves current chip state
742      * @rinfo: pointer to rivafb_info object containing info for current riva board
743      * @regs: pointer to riva_regs object
744      *
745      * DESCRIPTION:
746      * Saves current chip state to @regs.
747      *
748      * CALLED FROM:
749      * rivafb_init_one()
750      */
751     /* from GGI */
752     static void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
753     {
754     	int i;
755     
756     	rinfo->riva.LockUnlock(&rinfo->riva, 0);
757     
758     	rinfo->riva.UnloadStateExt(&rinfo->riva, &regs->ext);
759     
760     	regs->misc_output = MISCin(rinfo);
761     
762     	for (i = 0; i < NUM_CRT_REGS; i++) {
763     		regs->crtc[i] = CRTCin(rinfo, i);
764     	}
765     
766     	for (i = 0; i < NUM_ATC_REGS; i++) {
767     		regs->attr[i] = ATTRin(rinfo, i);
768     	}
769     
770     	for (i = 0; i < NUM_GRC_REGS; i++) {
771     		regs->gra[i] = GRAin(rinfo, i);
772     	}
773     
774     	for (i = 0; i < NUM_SEQ_REGS; i++) {
775     		regs->seq[i] = SEQin(rinfo, i);
776     	}
777     }
778     
779     /**
780      * riva_load_state - loads current chip state
781      * @rinfo: pointer to rivafb_info object containing info for current riva board
782      * @regs: pointer to riva_regs object
783      *
784      * DESCRIPTION:
785      * Loads chip state from @regs.
786      *
787      * CALLED FROM:
788      * riva_load_video_mode()
789      * rivafb_init_one()
790      * rivafb_remove_one()
791      */
792     /* from GGI */
793     static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
794     {
795     	int i;
796     	RIVA_HW_STATE *state = &regs->ext;
797     
798     	CRTCout(rinfo, 0x11, 0x00);
799     
800     	rinfo->riva.LockUnlock(&rinfo->riva, 0);
801     
802     	rinfo->riva.LoadStateExt(&rinfo->riva, state);
803     
804     	MISCout(rinfo, regs->misc_output);
805     
806     	for (i = 0; i < NUM_CRT_REGS; i++) {
807     		switch (i) {
808     		case 0x19:
809     		case 0x20 ... 0x40:
810     			break;
811     		default:
812     			CRTCout(rinfo, i, regs->crtc[i]);
813     		}
814     	}
815     
816     	for (i = 0; i < NUM_ATC_REGS; i++) {
817     		ATTRout(rinfo, i, regs->attr[i]);
818     	}
819     
820     	for (i = 0; i < NUM_GRC_REGS; i++) {
821     		GRAout(rinfo, i, regs->gra[i]);
822     	}
823     
824     	for (i = 0; i < NUM_SEQ_REGS; i++) {
825     		SEQout(rinfo, i, regs->seq[i]);
826     	}
827     }
828     
829     /**
830      * riva_load_video_mode - calculate timings
831      * @rinfo: pointer to rivafb_info object containing info for current riva board
832      * @video_mode: video mode to set
833      *
834      * DESCRIPTION:
835      * Calculate some timings and then send em off to riva_load_state().
836      *
837      * CALLED FROM:
838      * rivafb_set_var()
839      */
840     static void riva_load_video_mode(struct rivafb_info *rinfo,
841     				 struct fb_var_screeninfo *video_mode)
842     {
843     	struct riva_regs newmode;
844     	int bpp, width, hDisplaySize, hDisplay, hStart,
845     	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
846     
847     	/* time to calculate */
848     
849     	rivafb_blank(1, (struct fb_info *)rinfo);
850     
851     	bpp = video_mode->bits_per_pixel;
852     	if (bpp == 16 && video_mode->green.length == 5)
853     		bpp = 15;
854     	width = video_mode->xres_virtual;
855     	hDisplaySize = video_mode->xres;
856     	hDisplay = (hDisplaySize / 8) - 1;
857     	hStart = (hDisplaySize + video_mode->right_margin) / 8 + 2;
858     	hEnd = (hDisplaySize + video_mode->right_margin +
859     		video_mode->hsync_len) / 8 - 1;
860     	hTotal = (hDisplaySize + video_mode->right_margin +
861     		  video_mode->hsync_len + video_mode->left_margin) / 8 - 1;
862     	height = video_mode->yres_virtual;
863     	vDisplay = video_mode->yres - 1;
864     	vStart = video_mode->yres + video_mode->lower_margin - 1;
865     	vEnd = video_mode->yres + video_mode->lower_margin +
866     	       video_mode->vsync_len - 1;
867     	vTotal = video_mode->yres + video_mode->lower_margin +
868     		 video_mode->vsync_len + video_mode->upper_margin + 2;
869     	dotClock = 1000000000 / video_mode->pixclock;
870     
871     	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
872     
873     	newmode.crtc[0x0] = Set8Bits (hTotal - 4);
874     	newmode.crtc[0x1] = Set8Bits (hDisplay);
875     	newmode.crtc[0x2] = Set8Bits (hDisplay);
876     	newmode.crtc[0x3] = SetBitField (hTotal, 4: 0, 4:0) | SetBit (7);
877     	newmode.crtc[0x4] = Set8Bits (hStart);
878     	newmode.crtc[0x5] = SetBitField (hTotal, 5: 5, 7:7)
879     		| SetBitField (hEnd, 4: 0, 4:0);
880     	newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
881     	newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
882     		| SetBitField (vDisplay, 8: 8, 1:1)
883     		| SetBitField (vStart, 8: 8, 2:2)
884     		| SetBitField (vDisplay, 8: 8, 3:3)
885     		| SetBit (4)
886     		| SetBitField (vTotal, 9: 9, 5:5)
887     		| SetBitField (vDisplay, 9: 9, 6:6)
888     		| SetBitField (vStart, 9: 9, 7:7);
889     	newmode.crtc[0x9] = SetBitField (vDisplay, 9: 9, 5:5)
890     		| SetBit (6);
891     	newmode.crtc[0x10] = Set8Bits (vStart);
892     	newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
893     		| SetBit (5);
894     	newmode.crtc[0x12] = Set8Bits (vDisplay);
895     	newmode.crtc[0x13] = ((width / 8) * ((bpp + 1) / 8)) & 0xFF;
896     	newmode.crtc[0x15] = Set8Bits (vDisplay);
897     	newmode.crtc[0x16] = Set8Bits (vTotal + 1);
898     
899     	newmode.ext.bpp = bpp;
900     	newmode.ext.width = width;
901     	newmode.ext.height = height;
902     
903     	rinfo->riva.CalcStateExt(&rinfo->riva, &newmode.ext, bpp, width,
904     				  hDisplaySize, hDisplay, hStart, hEnd,
905     				  hTotal, height, vDisplay, vStart, vEnd,
906     				  vTotal, dotClock);
907     
908     	rinfo->current_state = newmode;
909     	riva_load_state(rinfo, &rinfo->current_state);
910     
911     	rinfo->riva.LockUnlock(&rinfo->riva, 0); /* important for HW cursor */
912     	rivafb_download_cursor(rinfo);
913     }
914     
915     /**
916      * riva_board_list_add - maintains board list
917      * @board_list: root node of list of boards
918      * @new_node: new node to be added
919      *
920      * DESCRIPTION:
921      * Adds @new_node to the list referenced by @board_list.
922      *
923      * RETURNS:
924      * New root node
925      *
926      * CALLED FROM:
927      * rivafb_init_one()
928      */
929     static struct rivafb_info *riva_board_list_add(struct rivafb_info *board_list,
930     					       struct rivafb_info *new_node)
931     {
932     	struct rivafb_info *i_p = board_list;
933     
934     	new_node->next = NULL;
935     
936     	if (board_list == NULL)
937     		return new_node;
938     
939     	while (i_p->next != NULL)
940     		i_p = i_p->next;
941     	i_p->next = new_node;
942     
943     	return board_list;
944     }
945     
946     /**
947      * riva_board_list_del - maintains board list
948      * @board_list: root node of list of boards
949      * @del_node: node to be removed
950      *
951      * DESCRIPTION:
952      * Removes @del_node from the list referenced by @board_list.
953      *
954      * RETURNS:
955      * New root node
956      *
957      * CALLED FROM:
958      * rivafb_remove_one()
959      */
960     static struct rivafb_info *riva_board_list_del(struct rivafb_info *board_list,
961     					       struct rivafb_info *del_node)
962     {
963     	struct rivafb_info *i_p = board_list;
964     
965     	if (board_list == del_node)
966     		return del_node->next;
967     
968     	while (i_p->next != del_node)
969     		i_p = i_p->next;
970     	i_p->next = del_node->next;
971     
972     	return board_list;
973     }
974     
975     /**
976      * rivafb_do_maximize - 
977      * @rinfo: pointer to rivafb_info object containing info for current riva board
978      * @var:
979      * @v:
980      * @nom:
981      * @den:
982      *
983      * DESCRIPTION:
984      * .
985      *
986      * RETURNS:
987      * -EINVAL on failure, 0 on success
988      * 
989      *
990      * CALLED FROM:
991      * rivafb_set_var()
992      */
993     static int rivafb_do_maximize(struct rivafb_info *rinfo,
994     			      struct fb_var_screeninfo *var,
995     			      struct fb_var_screeninfo *v,
996     			      int nom, int den)
997     {
998     	static struct {
999     		int xres, yres;
1000     	} modes[] = {
1001     		{1600, 1280},
1002     		{1280, 1024},
1003     		{1024, 768},
1004     		{800, 600},
1005     		{640, 480},
1006     		{-1, -1}
1007     	};
1008     	int i;
1009     
1010     	/* use highest possible virtual resolution */
1011     	if (v->xres_virtual == -1 && v->yres_virtual == -1) {
1012     		printk(KERN_WARNING PFX
1013     		       "using maximum available virtual resolution\n");
1014     		for (i = 0; modes[i].xres != -1; i++) {
1015     			if (modes[i].xres * nom / den * modes[i].yres <
1016     			    rinfo->ram_amount / 2)
1017     				break;
1018     		}
1019     		if (modes[i].xres == -1) {
1020     			printk(KERN_ERR PFX
1021     			       "could not find a virtual resolution that fits into video memory!!\n");
1022     			DPRINTK("EXIT - EINVAL error\n");
1023     			return -EINVAL;
1024     		}
1025     		v->xres_virtual = modes[i].xres;
1026     		v->yres_virtual = modes[i].yres;
1027     
1028     		printk(KERN_INFO PFX
1029     		       "virtual resolution set to maximum of %dx%d\n",
1030     		       v->xres_virtual, v->yres_virtual);
1031     	} else if (v->xres_virtual == -1) {
1032     		v->xres_virtual = (rinfo->ram_amount * den /
1033     			(nom * v->yres_virtual * 2)) & ~15;
1034     		printk(KERN_WARNING PFX
1035     		       "setting virtual X resolution to %d\n", v->xres_virtual);
1036     	} else if (v->yres_virtual == -1) {
1037     		v->xres_virtual = (v->xres_virtual + 15) & ~15;
1038     		v->yres_virtual = rinfo->ram_amount * den /
1039     			(nom * v->xres_virtual * 2);
1040     		printk(KERN_WARNING PFX
1041     		       "setting virtual Y resolution to %d\n", v->yres_virtual);
1042     	} else {
1043     		v->xres_virtual = (v->xres_virtual + 15) & ~15;
1044     		if (v->xres_virtual * nom / den * v->yres_virtual > rinfo->ram_amount) {
1045     			printk(KERN_ERR PFX
1046     			       "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
1047     			       var->xres, var->yres, var->bits_per_pixel);
1048     			DPRINTK("EXIT - EINVAL error\n");
1049     			return -EINVAL;
1050     		}
1051     	}
1052     	
1053     	if (v->xres_virtual * nom / den >= 8192) {
1054     		printk(KERN_WARNING PFX
1055     		       "virtual X resolution (%d) is too high, lowering to %d\n",
1056     		       v->xres_virtual, 8192 * den / nom - 16);
1057     		v->xres_virtual = 8192 * den / nom - 16;
1058     	}
1059     	
1060     	if (v->xres_virtual < v->xres) {
1061     		printk(KERN_ERR PFX
1062     		       "virtual X resolution (%d) is smaller than real\n", v->xres_virtual);
1063     		return -EINVAL;
1064     	}
1065     
1066     	if (v->yres_virtual < v->yres) {
1067     		printk(KERN_ERR PFX
1068     		       "virtual Y resolution (%d) is smaller than real\n", v->yres_virtual);
1069     		return -EINVAL;
1070     	}
1071     	
1072     	return 0;
1073     }
1074     
1075     
1076     
1077     /* ------------------------------------------------------------------------- *
1078      *
1079      * internal fb_ops helper functions
1080      *
1081      * ------------------------------------------------------------------------- */
1082     
1083     /**
1084      * riva_get_cmap_len - query current color map length
1085      * @var: standard kernel fb changeable data
1086      *
1087      * DESCRIPTION:
1088      * Get current color map length.
1089      *
1090      * RETURNS:
1091      * Length of color map
1092      *
1093      * CALLED FROM:
1094      * riva_getcolreg()
1095      * riva_setcolreg()
1096      * rivafb_get_cmap()
1097      * rivafb_set_cmap()
1098      */
1099     static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
1100     {
1101     	int rc = 16;		/* reasonable default */
1102     
1103     	assert(var != NULL);
1104     
1105     	switch (var->bits_per_pixel) {
1106     #ifdef FBCON_HAS_CFB8
1107     	case 8:
1108     		rc = 256;	/* pseudocolor... 256 entries HW palette */
1109     		break;
1110     #endif
1111     #ifdef FBCON_HAS_CFB16
1112     	case 15:
1113     		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */
1114     	case 16:
1115     		rc = 16;	/* directcolor... 16 entries SW palette */
1116     		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
1117     #endif
1118     #ifdef FBCON_HAS_CFB32
1119     	case 32:
1120     		rc = 16;	/* directcolor... 16 entries SW palette */
1121     		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
1122     #endif
1123     	default:
1124     		/* should not occur */
1125     		break;
1126     	}
1127     
1128     	return rc;
1129     }
1130     
1131     /**
1132      * riva_getcolreg
1133      * @regno: register index
1134      * @red: red component
1135      * @green: green component
1136      * @blue: blue component
1137      * @transp: transparency
1138      * @info: pointer to rivafb_info object containing info for current riva board
1139      *
1140      * DESCRIPTION:
1141      * Read a single color register and split it into colors/transparent.
1142      * The return values must have a 16 bit magnitude.
1143      *
1144      * RETURNS:
1145      * Return != 0 for invalid regno.
1146      *
1147      * CALLED FROM:
1148      * rivafb_get_cmap()
1149      * rivafb_switch()
1150      * fbcmap.c:fb_get_cmap()
1151      *	fbgen.c:fbgen_get_cmap()
1152      *	fbgen.c:fbgen_switch()
1153      */
1154     static int riva_getcolreg(unsigned regno, unsigned *red, unsigned *green,
1155     			  unsigned *blue, unsigned *transp,
1156     			  struct fb_info *info)
1157     {
1158     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1159     
1160     	if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var))
1161     		return 1;
1162     
1163     	*red = rivainfo->palette[regno].red;
1164     	*green = rivainfo->palette[regno].green;
1165     	*blue = rivainfo->palette[regno].blue;
1166     	*transp = 0;
1167     
1168     	return 0;
1169     }
1170     
1171     /**
1172      * riva_setcolreg
1173      * @regno: register index
1174      * @red: red component
1175      * @green: green component
1176      * @blue: blue component
1177      * @transp: transparency
1178      * @info: pointer to rivafb_info object containing info for current riva board
1179      *
1180      * DESCRIPTION:
1181      * Set a single color register. The values supplied have a 16 bit
1182      * magnitude.
1183      *
1184      * RETURNS:
1185      * Return != 0 for invalid regno.
1186      *
1187      * CALLED FROM:
1188      * rivafb_set_cmap()
1189      * fbcmap.c:fb_set_cmap()
1190      *	fbgen.c:fbgen_get_cmap()
1191      *	fbgen.c:fbgen_install_cmap()
1192      *		fbgen.c:fbgen_set_var()
1193      *		fbgen.c:fbgen_switch()
1194      *		fbgen.c:fbgen_blank()
1195      *	fbgen.c:fbgen_blank()
1196      */
1197     static int riva_setcolreg(unsigned regno, unsigned red, unsigned green,
1198     			  unsigned blue, unsigned transp,
1199     			  struct fb_info *info)
1200     {
1201     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1202     	RIVA_HW_INST *chip = &rivainfo->riva;
1203     	struct display *p;
1204     
1205     	DPRINTK("ENTER\n");
1206     
1207     	assert(rivainfo != NULL);
1208     	assert(rivainfo->currcon_display != NULL);
1209     
1210     	p = rivainfo->currcon_display;
1211     
1212     	if (regno >= riva_get_cmap_len(&p->var))
1213     		return -EINVAL;
1214     
1215     	rivainfo->palette[regno].red = red;
1216     	rivainfo->palette[regno].green = green;
1217     	rivainfo->palette[regno].blue = blue;
1218     
1219     	if (p->var.grayscale) {
1220     		/* gray = 0.30*R + 0.59*G + 0.11*B */
1221     		red = green = blue =
1222     		    (red * 77 + green * 151 + blue * 28) >> 8;
1223     	}
1224     
1225     	switch (p->var.bits_per_pixel) {
1226     #ifdef FBCON_HAS_CFB8
1227     	case 8:
1228     		/* "transparent" stuff is completely ignored. */
1229     		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1230     		break;
1231     #endif /* FBCON_HAS_CFB8 */
1232     #ifdef FBCON_HAS_CFB16
1233     	case 16:
1234     		assert(regno < 16);
1235     		if (p->var.green.length == 5) {
1236     			/* 0rrrrrgg gggbbbbb */
1237     			rivainfo->con_cmap.cfb16[regno] =
1238     			    ((red & 0xf800) >> 1) |
1239     			    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
1240     		} else {
1241     			/* rrrrrggg gggbbbbb */
1242     			rivainfo->con_cmap.cfb16[regno] =
1243     			    ((red & 0xf800) >> 0) |
1244     			    ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
1245     		}
1246     		break;
1247     #endif /* FBCON_HAS_CFB16 */
1248     #ifdef FBCON_HAS_CFB32
1249     	case 32:
1250     		assert(regno < 16);
1251     		rivainfo->con_cmap.cfb32[regno] =
1252     		    ((red & 0xff00) << 8) |
1253     		    ((green & 0xff00)) | ((blue & 0xff00) >> 8);
1254     		break;
1255     #endif /* FBCON_HAS_CFB32 */
1256     	default:
1257     		/* do nothing */
1258     		break;
1259     	}
1260     
1261     	return 0;
1262     }
1263     
1264     
1265     
1266     /* ------------------------------------------------------------------------- *
1267      *
1268      * framebuffer operations
1269      *
1270      * ------------------------------------------------------------------------- */
1271     
1272     static int rivafb_get_fix(struct fb_fix_screeninfo *fix, int con,
1273     			  struct fb_info *info)
1274     {
1275     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1276     	struct display *p;
1277     
1278     	DPRINTK("ENTER\n");
1279     
1280     	assert(fix != NULL);
1281     	assert(info != NULL);
1282     	assert(rivainfo->drvr_name && rivainfo->drvr_name[0]);
1283     	assert(rivainfo->fb_base_phys > 0);
1284     	assert(rivainfo->ram_amount > 0);
1285     
1286     	p = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1287     
1288     	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1289     	sprintf(fix->id, "nVidia %s", rivainfo->drvr_name);
1290     
1291     	fix->smem_start = rivainfo->fb_base_phys;
1292     	fix->smem_len = rivainfo->ram_amount;
1293     
1294     	fix->type = p->type;
1295     	fix->type_aux = p->type_aux;
1296     	fix->visual = p->visual;
1297     
1298     	fix->xpanstep = 1;
1299     	fix->ypanstep = 1;
1300     	fix->ywrapstep = 0;	/* FIXME: no ywrap for now */
1301     
1302     	fix->line_length = p->line_length;
1303     
1304     	fix->mmio_start = rivainfo->ctrl_base_phys;
1305     	fix->mmio_len = rivainfo->base0_region_size;
1306     	fix->smem_start = rivainfo->fb_base_phys;
1307     	fix->smem_len = rivainfo->base1_region_size;
1308     
1309     	switch (rivainfo->riva.Architecture) {
1310     	case NV_ARCH_03:
1311     		fix->accel = FB_ACCEL_NV3;
1312     		break;
1313     	case NV_ARCH_04:	/* riva_hw.c now doesn't distinguish between TNT & TNT2 */
1314     		fix->accel = FB_ACCEL_NV4;
1315     		break;
1316     	case NV_ARCH_10:	/* FIXME: ID for GeForce */
1317     		fix->accel = FB_ACCEL_NV4;
1318     		break;
1319     
1320     	}
1321     
1322     	DPRINTK("EXIT, returning 0\n");
1323     
1324     	return 0;
1325     }
1326     
1327     static int rivafb_get_var(struct fb_var_screeninfo *var, int con,
1328     			  struct fb_info *info)
1329     {
1330     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1331     
1332     	DPRINTK("ENTER\n");
1333     
1334     	assert(info != NULL);
1335     	assert(var != NULL);
1336     
1337     	*var = (con < 0) ? rivainfo->disp.var : fb_display[con].var;
1338     
1339     	DPRINTK("EXIT, returning 0\n");
1340     
1341     	return 0;
1342     }
1343     
1344     static int rivafb_set_var(struct fb_var_screeninfo *var, int con,
1345     			  struct fb_info *info)
1346     {
1347     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1348     	struct display *dsp;
1349     	struct fb_var_screeninfo v;
1350     	int nom, den;		/* translating from pixels->bytes */
1351     	int accel;
1352     	unsigned chgvar = 0;
1353     
1354     	DPRINTK("ENTER\n");
1355     
1356     	assert(info != NULL);
1357     	assert(var != NULL);
1358     
1359     	DPRINTK("Requested: %dx%dx%d\n", var->xres, var->yres,
1360     		var->bits_per_pixel);
1361     	DPRINTK("  virtual: %dx%d\n", var->xres_virtual,
1362     		var->yres_virtual);
1363     	DPRINTK("   offset: (%d,%d)\n", var->xoffset, var->yoffset);
1364     	DPRINTK("grayscale: %d\n", var->grayscale);
1365     
1366     	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1367     	assert(dsp != NULL);
1368     
1369     	/* if var has changed, we should call changevar() later */
1370     	if (con >= 0) {
1371     		chgvar = ((dsp->var.xres != var->xres) ||
1372     			  (dsp->var.yres != var->yres) ||
1373     			  (dsp->var.xres_virtual != var->xres_virtual) ||
1374     			  (dsp->var.yres_virtual != var->yres_virtual) ||
1375     			  (dsp->var.accel_flags != var->accel_flags) ||
1376     			  (dsp->var.bits_per_pixel != var->bits_per_pixel)
1377     			  || memcmp(&dsp->var.red, &var->red,
1378     				    sizeof(var->red))
1379     			  || memcmp(&dsp->var.green, &var->green,
1380     				    sizeof(var->green))
1381     			  || memcmp(&dsp->var.blue, &var->blue,
1382     				    sizeof(var->blue)));
1383     	}
1384     
1385     	memcpy(&v, var, sizeof(v));
1386     
1387     	accel = v.accel_flags & FB_ACCELF_TEXT;
1388     
1389     	switch (v.bits_per_pixel) {
1390     #ifdef FBCON_HAS_CFB8
1391     	case 1 ... 8:
1392     		v.bits_per_pixel = 8;
1393     		nom = 1;
1394     		den = 1;
1395     		v.red.offset = 0;
1396     		v.red.length = 8;
1397     		v.green.offset = 0;
1398     		v.green.length = 8;
1399     		v.blue.offset = 0;
1400     		v.blue.length = 8;
1401     		break;
1402     #endif
1403     #ifdef FBCON_HAS_CFB16
1404     	case 9 ... 15:
1405     		v.green.length = 5;
1406     		/* fall through */
1407     	case 16:
1408     		v.bits_per_pixel = 16;
1409     		nom = 2;
1410     		den = 1;
1411     		if (v.green.length == 5) {
1412     			/* 0rrrrrgg gggbbbbb */
1413     			v.red.offset = 10;
1414     			v.green.offset = 5;
1415     			v.blue.offset = 0;
1416     			v.red.length = 5;
1417     			v.green.length = 5;
1418     			v.blue.length = 5;
1419     		} else {
1420     			/* rrrrrggg gggbbbbb */
1421     			v.red.offset = 11;
1422     			v.green.offset = 5;
1423     			v.blue.offset = 0;
1424     			v.red.length = 5;
1425     			v.green.length = 6;
1426     			v.blue.length = 5;
1427     		}
1428     		break;
1429     #endif
1430     #ifdef FBCON_HAS_CFB32
1431     	case 17 ... 32:
1432     		v.bits_per_pixel = 32;
1433     		nom = 4;
1434     		den = 1;
1435     		v.red.offset = 16;
1436     		v.green.offset = 8;
1437     		v.blue.offset = 0;
1438     		v.red.length = 8;
1439     		v.green.length = 8;
1440     		v.blue.length = 8;
1441     		break;
1442     #endif
1443     	default:
1444     		printk(KERN_ERR PFX
1445     		       "mode %dx%dx%d rejected...color depth not supported.\n",
1446     		       var->xres, var->yres, var->bits_per_pixel);
1447     		DPRINTK("EXIT, returning -EINVAL\n");
1448     		return -EINVAL;
1449     	}
1450     
1451     	if (rivafb_do_maximize(rivainfo, var, &v, nom, den) < 0)
1452     		return -EINVAL;
1453     
1454     	if (v.xoffset < 0)
1455     		v.xoffset = 0;
1456     	if (v.yoffset < 0)
1457     		v.yoffset = 0;
1458     
1459     	/* truncate xoffset and yoffset to maximum if too high */
1460     	if (v.xoffset > v.xres_virtual - v.xres)
1461     		v.xoffset = v.xres_virtual - v.xres - 1;
1462     
1463     	if (v.yoffset > v.yres_virtual - v.yres)
1464     		v.yoffset = v.yres_virtual - v.yres - 1;
1465     
1466     	v.red.msb_right =
1467     	    v.green.msb_right =
1468     	    v.blue.msb_right =
1469     	    v.transp.offset = v.transp.length = v.transp.msb_right = 0;
1470     
1471     	switch (v.activate & FB_ACTIVATE_MASK) {
1472     	case FB_ACTIVATE_TEST:
1473     		DPRINTK("EXIT - FB_ACTIVATE_TEST\n");
1474     		return 0;
1475     	case FB_ACTIVATE_NXTOPEN:	/* ?? */
1476     	case FB_ACTIVATE_NOW:
1477     		break;		/* continue */
1478     	default:
1479     		DPRINTK("EXIT - unknown activation type\n");
1480     		return -EINVAL;	/* unknown */
1481     	}
1482     
1483     	memcpy(&dsp->var, &v, sizeof(v));
1484     	if (chgvar) {
1485     		riva_set_dispsw(rivainfo, dsp);
1486     
1487     		if (accel) {
1488     			if (nomove)
1489     				dsp->scrollmode = SCROLL_YNOMOVE;
1490     			else
1491     				dsp->scrollmode = 0;
1492     		} else
1493     			dsp->scrollmode = SCROLL_YREDRAW;
1494     
1495     		if (info && info->changevar)
1496     			info->changevar(con);
1497     	}
1498     
1499     	rivafb_create_cursor(rivainfo, fontwidth(dsp), fontheight(dsp));
1500     	riva_load_video_mode(rivainfo, &v);
1501     	if (accel) riva_setup_accel(rivainfo);
1502     
1503     	DPRINTK("EXIT, returning 0\n");
1504     	return 0;
1505     }
1506     
1507     static int rivafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
1508     			   struct fb_info *info)
1509     {
1510     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1511     	struct display *dsp;
1512     
1513     	DPRINTK("ENTER\n");
1514     
1515     	assert(rivainfo != NULL);
1516     	assert(cmap != NULL);
1517     
1518     	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1519     
1520     	if (con == rivainfo->currcon) {	/* current console? */
1521     		int rc = fb_get_cmap(cmap, kspc, riva_getcolreg, info);
1522     		DPRINTK("EXIT - returning %d\n", rc);
1523     		return rc;
1524     	} else if (dsp->cmap.len)	/* non default colormap? */
1525     		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
1526     	else
1527     		fb_copy_cmap(fb_default_cmap
1528     			     (riva_get_cmap_len(&dsp->var)), cmap,
1529     			     kspc ? 0 : 2);
1530     
1531     	DPRINTK("EXIT, returning 0\n");
1532     
1533     	return 0;
1534     }
1535     
1536     static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
1537     			   struct fb_info *info)
1538     {
1539     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1540     	struct display *dsp;
1541     	unsigned int cmap_len;
1542     
1543     	DPRINTK("ENTER\n");
1544     	
1545     	assert(rivainfo != NULL);
1546     	assert(cmap != NULL);
1547     
1548     	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1549     
1550     	cmap_len = riva_get_cmap_len(&dsp->var);
1551     	if (dsp->cmap.len != cmap_len) {
1552     		int err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);
1553     		if (err) {
1554     			DPRINTK("EXIT - returning %d\n", err);
1555     			return err;
1556     		}
1557     	}
1558     	if (con == rivainfo->currcon) {	/* current console? */
1559     		int rc = fb_set_cmap(cmap, kspc, riva_setcolreg, info);
1560     		DPRINTK("EXIT - returning %d\n", rc);
1561     		return rc;
1562     	} else
1563     		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
1564     
1565     	DPRINTK("EXIT, returning 0\n");
1566     
1567     	return 0;
1568     }
1569     
1570     /**
1571      * rivafb_pan_display
1572      * @var: standard kernel fb changeable data
1573      * @con: TODO
1574      * @info: pointer to rivafb_info object containing info for current riva board
1575      *
1576      * DESCRIPTION:
1577      * Pan (or wrap, depending on the `vmode' field) the display using the
1578      * `xoffset' and `yoffset' fields of the `var' structure.
1579      * If the values don't fit, return -EINVAL.
1580      *
1581      * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1582      */
1583     static int rivafb_pan_display(struct fb_var_screeninfo *var, int con,
1584     			      struct fb_info *info)
1585     {
1586     	unsigned int base;
1587     	struct display *dsp;
1588     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1589     
1590     	DPRINTK("ENTER\n");
1591     
1592     	assert(rivainfo != NULL);
1593     
1594     	if (var->xoffset > (var->xres_virtual - var->xres))
1595     		return -EINVAL;
1596     	if (var->yoffset > (var->yres_virtual - var->yres))
1597     		return -EINVAL;
1598     
1599     	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1600     
1601     	if (var->vmode & FB_VMODE_YWRAP) {
1602     		if (var->yoffset < 0
1603     		    || var->yoffset >= dsp->var.yres_virtual
1604     		    || var->xoffset) return -EINVAL;
1605     	} else {
1606     		if (var->xoffset + dsp->var.xres > dsp->var.xres_virtual ||
1607     		    var->yoffset + dsp->var.yres > dsp->var.yres_virtual)
1608     			return -EINVAL;
1609     	}
1610     
1611     	base = var->yoffset * dsp->line_length + var->xoffset;
1612     
1613     	if (con == rivainfo->currcon) {
1614     		rivainfo->riva.SetStartAddress(&rivainfo->riva, base);
1615     	}
1616     
1617     	dsp->var.xoffset = var->xoffset;
1618     	dsp->var.yoffset = var->yoffset;
1619     
1620     	if (var->vmode & FB_VMODE_YWRAP)
1621     		dsp->var.vmode |= FB_VMODE_YWRAP;
1622     	else
1623     		dsp->var.vmode &= ~FB_VMODE_YWRAP;
1624     
1625     	DPRINTK("EXIT, returning 0\n");
1626     
1627     	return 0;
1628     }
1629     
1630     static int rivafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1631     			unsigned long arg, int con, struct fb_info *info)
1632     {
1633     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1634     
1635     	DPRINTK("ENTER\n");
1636     
1637     	assert(rivainfo != NULL);
1638     
1639     	/* no rivafb-specific ioctls */
1640     
1641     	DPRINTK("EXIT, returning -EINVAL\n");
1642     
1643     	return -EINVAL;
1644     }
1645     
1646     static int rivafb_rasterimg(struct fb_info *info, int start)
1647     {
1648     	struct rivafb_info *rinfo = (struct rivafb_info *)info;
1649     
1650     	wait_for_idle(rinfo);
1651     
1652     	return 0;
1653     }
1654     
1655     static int rivafb_switch(int con, struct fb_info *info)
1656     {
1657     	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
1658     	struct fb_cmap *cmap;
1659     	struct display *dsp;
1660     	
1661     	DPRINTK("ENTER\n");
1662     	
1663     	assert(rivainfo != NULL);
1664     
1665     	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
1666     
1667     	if (rivainfo->currcon >= 0) {
1668     		/* Do we have to save the colormap? */
1669     		cmap = &(rivainfo->currcon_display->cmap);
1670     		DPRINTK("switch1: con = %d, cmap.len = %d\n",
1671     			 rivainfo->currcon, cmap->len);
1672     
1673     		if (cmap->len) {
1674     			DPRINTK("switch1a: %p %p %p %p\n", cmap->red,
1675     				 cmap->green, cmap->blue, cmap->transp);
1676     			fb_get_cmap(cmap, 1, riva_getcolreg, info);
1677     		}
1678     	}
1679     	rivainfo->currcon = con;
1680     	rivainfo->currcon_display = dsp;
1681     
1682     	rivafb_set_var(&dsp->var, con, info);
1683     	riva_set_dispsw(rivainfo, dsp);
1684     
1685     	DPRINTK("EXIT, returning 0\n");
1686     	return 0;
1687     }
1688     
1689     static int rivafb_updatevar(int con, struct fb_info *info)
1690     {
1691     	int rc;
1692     
1693     	DPRINTK("ENTER\n");
1694     
1695     	rc = (con < 0) ? -EINVAL : rivafb_pan_display(&fb_display[con].var,
1696     						      con, info);
1697     	DPRINTK("EXIT, returning %d\n", rc);
1698     	return rc;
1699     }
1700     
1701     static void rivafb_blank(int blank, struct fb_info *info)
1702     {
1703     	unsigned char tmp, vesa;
1704     	struct rivafb_info *rinfo = (struct rivafb_info *)info;
1705     
1706     	DPRINTK("ENTER\n");
1707     
1708     	assert(rinfo != NULL);
1709     
1710     	tmp = SEQin(rinfo, 0x01) & ~0x20;	/* screen on/off */
1711     	vesa = CRTCin(rinfo, 0x1a) & ~0xc0;	/* sync on/off */
1712     
1713     	if (blank) {
1714     		tmp |= 0x20;
1715     		switch (blank - 1) {
1716     		case VESA_NO_BLANKING:
1717     			break;
1718     		case VESA_VSYNC_SUSPEND:
1719     			vesa |= 0x80;
1720     			break;
1721     		case VESA_HSYNC_SUSPEND:
1722     			vesa |= 0x40;
1723     			break;
1724     		case VESA_POWERDOWN:
1725     			vesa |= 0xc0;
1726     			break;
1727     		}
1728     	}
1729     
1730     	SEQout(rinfo, 0x01, tmp);
1731     	CRTCout(rinfo, 0x1a, vesa);
1732     
1733     	DPRINTK("EXIT\n");
1734     }
1735     
1736     
1737     
1738     /* ------------------------------------------------------------------------- *
1739      *
1740      * initialization helper functions
1741      *
1742      * ------------------------------------------------------------------------- */
1743     
1744     /* kernel interface */
1745     static struct fb_ops riva_fb_ops = {
1746     	owner:		THIS_MODULE,
1747     	fb_get_fix:	rivafb_get_fix,
1748     	fb_get_var:	rivafb_get_var,
1749     	fb_set_var:	rivafb_set_var,
1750     	fb_get_cmap:	rivafb_get_cmap,
1751     	fb_set_cmap:	rivafb_set_cmap,
1752     	fb_pan_display:	rivafb_pan_display,
1753     	fb_ioctl:	rivafb_ioctl,
1754     	fb_rasterimg:	rivafb_rasterimg,
1755     };
1756     
1757     static int __devinit riva_init_disp_var(struct rivafb_info *rinfo)
1758     {
1759     #ifndef MODULE
1760     	if (mode_option)
1761     		fb_find_mode(&rinfo->disp.var, &rinfo->info, mode_option,
1762     			     NULL, 0, NULL, 8);
1763     #endif
1764     	return 0;
1765     }
1766     
1767     static int __devinit riva_init_disp(struct rivafb_info *rinfo)
1768     {
1769     	struct fb_info *info;
1770     	struct display *disp;
1771     
1772     	DPRINTK("ENTER\n");
1773     
1774     	assert(rinfo != NULL);
1775     
1776     	info = &rinfo->info;
1777     	disp = &rinfo->disp;
1778     
1779     	disp->var = rivafb_default_var;
1780     	
1781     	if (noaccel)
1782     		disp->var.accel_flags &= ~FB_ACCELF_TEXT;
1783     	else
1784     		disp->var.accel_flags |= FB_ACCELF_TEXT;
1785     	
1786     	info->disp = disp;
1787     
1788     	/* FIXME: assure that disp->cmap is completely filled out */
1789     
1790     	rinfo->currcon_display = disp;
1791     
1792     	if ((riva_init_disp_var(rinfo)) < 0) {
1793     		DPRINTK("EXIT, returning -1\n");
1794     		return -1;
1795     	}
1796     
1797     	riva_set_dispsw(rinfo, disp);
1798     
1799     	DPRINTK("EXIT, returning 0\n");
1800     	return 0;
1801     
1802     }
1803     
1804     static int __devinit riva_set_fbinfo(struct rivafb_info *rinfo)
1805     {
1806     	struct fb_info *info;
1807     
1808     	assert(rinfo != NULL);
1809     
1810     	info = &rinfo->info;
1811     
1812     	strcpy(info->modename, rinfo->drvr_name);
1813     	info->node = -1;
1814     	info->flags = FBINFO_FLAG_DEFAULT;
1815     	info->fbops = &riva_fb_ops;
1816     
1817     	/* FIXME: set monspecs to what??? */
1818     
1819     	info->display_fg = NULL;
1820     	strncpy(info->fontname, fontname, sizeof(info->fontname));
1821     	info->fontname[sizeof(info->fontname) - 1] = 0;
1822     
1823     	info->changevar = NULL;
1824     	info->switch_con = rivafb_switch;
1825     	info->updatevar = rivafb_updatevar;
1826     	info->blank = rivafb_blank;
1827     
1828     	if (riva_init_disp(rinfo) < 0)	/* must be done last */
1829     		return -1;
1830     
1831     	return 0;
1832     }
1833     
1834     
1835     
1836     /* ------------------------------------------------------------------------- *
1837      *
1838      * PCI bus
1839      *
1840      * ------------------------------------------------------------------------- */
1841     
1842     static int __devinit rivafb_init_one(struct pci_dev *pd,
1843     				     const struct pci_device_id *ent)
1844     {
1845     	struct rivafb_info *rinfo;
1846     	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1847     
1848     	assert(pd != NULL);
1849     	assert(rci != NULL);
1850     
1851     	rinfo = kmalloc(sizeof(struct rivafb_info), GFP_KERNEL);
1852     	if (!rinfo)
1853     		goto err_out;
1854     
1855     	memset(rinfo, 0, sizeof(struct rivafb_info));
1856     
1857     	rinfo->drvr_name = rci->name;
1858     	rinfo->riva.Architecture = rci->arch_rev;
1859     
1860     	rinfo->pd = pd;
1861     	rinfo->base0_region_size = pci_resource_len(pd, 0);
1862     	rinfo->base1_region_size = pci_resource_len(pd, 1);
1863     
1864     	assert(rinfo->base0_region_size >= 0x00800000);	/* from GGI */
1865     	assert(rinfo->base1_region_size >= 0x01000000);	/* from GGI */
1866     
1867     	rinfo->ctrl_base_phys = pci_resource_start(rinfo->pd, 0);
1868     	rinfo->fb_base_phys = pci_resource_start(rinfo->pd, 1);
1869     
1870     	if (!request_mem_region(rinfo->ctrl_base_phys,
1871     				rinfo->base0_region_size, "rivafb")) {
1872     		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
1873     		goto err_out_kfree;
1874     	}
1875     
1876     	if (!request_mem_region(rinfo->fb_base_phys,
1877     				rinfo->base1_region_size, "rivafb")) {
1878     		printk(KERN_ERR PFX "cannot reserve FB region\n");
1879     		goto err_out_free_base0;
1880     	}
1881     	
1882     	rinfo->ctrl_base = ioremap(rinfo->ctrl_base_phys,
1883     				   rinfo->base0_region_size);
1884     	if (!rinfo->ctrl_base) {
1885     		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1886     		goto err_out_free_base1;
1887     	}
1888     	
1889     	rinfo->fb_base = ioremap(rinfo->fb_base_phys,
1890     				 rinfo->base1_region_size);
1891     	if (!rinfo->fb_base) {
1892     		printk(KERN_ERR PFX "cannot ioremap FB base\n");
1893     		goto err_out_iounmap_ctrl;
1894     	}
1895     	
1896     #ifdef CONFIG_MTRR
1897     	if (!nomtrr) {
1898     		rinfo->mtrr.vram = mtrr_add(rinfo->fb_base_phys,
1899     					    rinfo->base1_region_size, MTRR_TYPE_WRCOMB, 1);
1900     		if (rinfo->mtrr.vram < 0) {
1901     			printk(KERN_ERR PFX "unable to setup MTRR\n");
1902     		} else {
1903     			rinfo->mtrr.vram_valid = 1;
1904     			/* let there be speed */
1905     			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
1906     		}
1907     	}
1908     #endif /* CONFIG_MTRR */
1909     
1910     	rinfo->riva.EnableIRQ = 0;
1911     	rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base + 0x00680000);
1912     	rinfo->riva.PFB = (unsigned *)(rinfo->ctrl_base + 0x00100000);
1913     	rinfo->riva.PFIFO = (unsigned *)(rinfo->ctrl_base + 0x00002000);
1914     	rinfo->riva.PGRAPH = (unsigned *)(rinfo->ctrl_base + 0x00400000);
1915     	rinfo->riva.PEXTDEV = (unsigned *)(rinfo->ctrl_base + 0x00101000);
1916     	rinfo->riva.PTIMER = (unsigned *)(rinfo->ctrl_base + 0x00009000);
1917     	rinfo->riva.PMC = (unsigned *)(rinfo->ctrl_base + 0x00000000);
1918     	rinfo->riva.FIFO = (unsigned *)(rinfo->ctrl_base + 0x00800000);
1919     
1920     	rinfo->riva.PCIO = (U008 *)(rinfo->ctrl_base + 0x00601000);
1921     	rinfo->riva.PDIO = (U008 *)(rinfo->ctrl_base + 0x00681000);
1922     	rinfo->riva.PVIO = (U008 *)(rinfo->ctrl_base + 0x000C0000);
1923     
1924     	rinfo->riva.IO = (MISCin(rinfo) & 0x01) ? 0x3D0 : 0x3B0;
1925     
1926     	switch (rinfo->riva.Architecture) {
1927     	case NV_ARCH_03:
1928     		rinfo->riva.PRAMIN = (unsigned *)(rinfo->fb_base + 0x00C00000);
1929     		break;
1930     	case NV_ARCH_04:
1931     	case NV_ARCH_10:
1932     		rinfo->riva.PCRTC = (unsigned *)(rinfo->ctrl_base + 0x00600000);
1933     		rinfo->riva.PRAMIN = (unsigned *)(rinfo->ctrl_base + 0x00710000);
1934     		break;
1935     	}
1936     
1937     	RivaGetConfig(&rinfo->riva);
1938     
1939     	/* back to normal */
1940     
1941     	assert(rinfo->pd != NULL);
1942     
1943     	/* unlock io */
1944     	CRTCout(rinfo, 0x11, 0xFF);	/* vgaHWunlock() + riva unlock (0x7F) */
1945     	rinfo->riva.LockUnlock(&rinfo->riva, 0);
1946     
1947     	riva_save_state(rinfo, &rinfo->initial_state);
1948     
1949     	rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
1950     	rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
1951     
1952     	if (!nohwcursor) rinfo->cursor = rivafb_init_cursor(rinfo);
1953     
1954     	if (riva_set_fbinfo(rinfo) < 0) {
1955     		printk(KERN_ERR PFX "error setting initial video mode\n");
1956     		goto err_out_cursor;
1957     	}
1958     
1959     	if (register_framebuffer((struct fb_info *)rinfo) < 0) {
1960     		printk(KERN_ERR PFX
1961     			"error registering riva framebuffer\n");
1962     		goto err_out_load_state;
1963     	}
1964     
1965     	riva_boards = riva_board_list_add(riva_boards, rinfo);
1966     
1967     	pci_set_drvdata(pd, rinfo);
1968     
1969     	printk(KERN_INFO PFX
1970     		"PCI nVidia NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
1971     		rinfo->riva.Architecture,
1972     		RIVAFB_VERSION,
1973     		rinfo->drvr_name,
1974     		rinfo->ram_amount / (1024 * 1024),
1975     		rinfo->fb_base_phys);
1976     
1977     	return 0;
1978     
1979     err_out_load_state:
1980     	riva_load_state(rinfo, &rinfo->initial_state);
1981     err_out_cursor:
1982     	rivafb_exit_cursor(rinfo);
1983     /* err_out_iounmap_fb: */
1984     	iounmap(rinfo->fb_base);
1985     err_out_iounmap_ctrl:
1986     	iounmap(rinfo->ctrl_base);
1987     err_out_free_base1:
1988     	release_mem_region(rinfo->fb_base_phys, rinfo->base1_region_size);
1989     err_out_free_base0:
1990     	release_mem_region(rinfo->ctrl_base_phys, rinfo->base0_region_size);
1991     err_out_kfree:
1992     	kfree(rinfo);
1993     err_out:
1994     	return -ENODEV;
1995     }
1996     
1997     static void __devexit rivafb_remove_one(struct pci_dev *pd)
1998     {
1999     	struct rivafb_info *board = pci_get_drvdata(pd);
2000     	
2001     	if (!board)
2002     		return;
2003     
2004     	riva_boards = riva_board_list_del(riva_boards, board);
2005     
2006     	riva_load_state(board, &board->initial_state);
2007     
2008     	unregister_framebuffer((struct fb_info *)board);
2009     
2010     	rivafb_exit_cursor(board);
2011     
2012     #ifdef CONFIG_MTRR
2013     	if (board->mtrr.vram_valid)
2014     		mtrr_del(board->mtrr.vram, board->fb_base_phys,
2015     			 board->base1_region_size);
2016     #endif /* CONFIG_MTRR */
2017     
2018     	iounmap(board->ctrl_base);
2019     	iounmap(board->fb_base);
2020     
2021     	release_mem_region(board->ctrl_base_phys,
2022     			   board->base0_region_size);
2023     	release_mem_region(board->fb_base_phys,
2024     			   board->base1_region_size);
2025     
2026     	kfree(board);
2027     
2028     	pci_set_drvdata(pd, NULL);
2029     }
2030     
2031     
2032     
2033     /* ------------------------------------------------------------------------- *
2034      *
2035      * initialization
2036      *
2037      * ------------------------------------------------------------------------- */
2038     
2039     #ifndef MODULE
2040     int __init rivafb_setup(char *options)
2041     {
2042     	char *this_opt;
2043     
2044     	if (!options || !*options)
2045     		return 0;
2046     
2047     	for (this_opt = strtok(options, ","); this_opt;
2048     	     this_opt = strtok(NULL, ",")) {
2049     		if (!strncmp(this_opt, "font:", 5)) {
2050     			char *p;
2051     			int i;
2052     
2053     			p = this_opt + 5;
2054     			for (i = 0; i < sizeof(fontname) - 1; i++)
2055     				if (!*p || *p == ' ' || *p == ',')
2056     					break;
2057     			memcpy(fontname, this_opt + 5, i);
2058     			fontname[i] = 0;
2059     
2060     		} else if (!strncmp(this_opt, "noblink", 7)) {
2061     			noblink = 1;
2062     		} else if (!strncmp(this_opt, "noaccel", 7)) {
2063     			noaccel = 1;
2064     		} else if (!strncmp(this_opt, "nomove", 6)) {
2065     			nomove = 1;
2066     #ifdef CONFIG_MTRR
2067     		} else if (!strncmp(this_opt, "nomtrr", 6)) {
2068     			nomtrr = 1;
2069     #endif
2070     		} else if (!strncmp(this_opt, "nohwcursor", 10)) {
2071     			nohwcursor = 1;
2072     		} else
2073     			mode_option = this_opt;
2074     	}
2075     	return 0;
2076     }
2077     #endif /* !MODULE */
2078     
2079     static struct pci_driver rivafb_driver = {
2080     	name:		"rivafb",
2081     	id_table:	rivafb_pci_tbl,
2082     	probe:		rivafb_init_one,
2083     	remove:		rivafb_remove_one,
2084     };
2085     
2086     
2087     
2088     /* ------------------------------------------------------------------------- *
2089      *
2090      * modularization
2091      *
2092      * ------------------------------------------------------------------------- */
2093     
2094     int __init rivafb_init(void)
2095     {
2096     	int err;
2097     #ifdef MODULE
2098     	if (font) strncpy(fontname, font, sizeof(fontname)-1);
2099     #endif
2100     	err = pci_module_init(&rivafb_driver);
2101     	if (err)
2102     		return err;
2103     	return 0;
2104     }
2105     
2106     
2107     #ifdef MODULE
2108     static void __exit rivafb_exit(void)
2109     {
2110     	pci_unregister_driver(&rivafb_driver);
2111     }
2112     
2113     module_init(rivafb_init);
2114     module_exit(rivafb_exit);
2115     
2116     MODULE_PARM(font, "s");
2117     MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (default=none)");
2118     MODULE_PARM(noaccel, "i");
2119     MODULE_PARM_DESC(noaccel, "Disables hardware acceleration (0 or 1=disabled) (default=0)");
2120     MODULE_PARM(nomove, "i");
2121     MODULE_PARM_DESC(nomove, "Enables YSCROLL_NOMOVE (0 or 1=enabled) (default=0)");
2122     MODULE_PARM(nohwcursor, "i");
2123     MODULE_PARM_DESC(nohwcursor, "Disables hardware cursor (0 or 1=disabled) (default=0)");
2124     MODULE_PARM(noblink, "i");
2125     MODULE_PARM_DESC(noblink, "Disables hardware cursor blinking (0 or 1=disabled) (default=0)");
2126     #ifdef CONFIG_MTRR
2127     MODULE_PARM(nomtrr, "i");
2128     MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2129     #endif
2130     #endif /* MODULE */
2131     
2132     MODULE_AUTHOR("Ani Joshi, maintainer");
2133     MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2");
2134