Linux 2.6.17.7
[linux/fpc-iii.git] / drivers / video / riva / fbdev.c
blob3e9308f0f165eafcb6b4d8178d6e846e2ae4c22c
1 /*
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
8 * Contributors:
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
25 * for more details.
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>
37 #include <linux/mm.h>
38 #include <linux/tty.h>
39 #include <linux/slab.h>
40 #include <linux/delay.h>
41 #include <linux/fb.h>
42 #include <linux/init.h>
43 #include <linux/pci.h>
44 #ifdef CONFIG_MTRR
45 #include <asm/mtrr.h>
46 #endif
47 #ifdef CONFIG_PPC_OF
48 #include <asm/prom.h>
49 #include <asm/pci-bridge.h>
50 #endif
51 #ifdef CONFIG_PMAC_BACKLIGHT
52 #include <asm/machdep.h>
53 #include <asm/backlight.h>
54 #endif
56 #include "rivafb.h"
57 #include "nvreg.h"
59 #ifndef CONFIG_PCI /* sanity check */
60 #error This driver requires PCI support.
61 #endif
63 /* version number of this driver */
64 #define RIVAFB_VERSION "0.9.5b"
66 /* ------------------------------------------------------------------------- *
68 * various helpful macros and constants
70 * ------------------------------------------------------------------------- */
71 #ifdef CONFIG_FB_RIVA_DEBUG
72 #define NVTRACE printk
73 #else
74 #define NVTRACE if(0) printk
75 #endif
77 #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __FUNCTION__)
78 #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __FUNCTION__)
80 #ifdef CONFIG_FB_RIVA_DEBUG
81 #define assert(expr) \
82 if(!(expr)) { \
83 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
84 #expr,__FILE__,__FUNCTION__,__LINE__); \
85 BUG(); \
87 #else
88 #define assert(expr)
89 #endif
91 #define PFX "rivafb: "
93 /* macro that allows you to set overflow bits */
94 #define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
95 #define SetBit(n) (1<<(n))
96 #define Set8Bits(value) ((value)&0xff)
98 /* HW cursor parameters */
99 #define MAX_CURS 32
101 /* ------------------------------------------------------------------------- *
103 * prototypes
105 * ------------------------------------------------------------------------- */
107 static int rivafb_blank(int blank, struct fb_info *info);
109 /* ------------------------------------------------------------------------- *
111 * card identification
113 * ------------------------------------------------------------------------- */
115 static struct pci_device_id rivafb_pci_tbl[] = {
116 { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
117 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
118 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
119 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
120 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
121 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
122 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
124 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
126 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
127 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
128 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
129 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
130 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
131 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
132 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
133 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
134 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
135 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
136 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
137 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
138 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
139 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
140 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
141 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
142 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
144 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
145 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
146 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
147 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
148 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
149 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
150 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
151 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
152 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
153 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
154 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
155 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
156 // NF2/IGP version, GeForce 4 MX, NV18
157 { PCI_VENDOR_ID_NVIDIA, 0x01f0,
158 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
159 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
160 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
161 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
162 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
163 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
164 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
165 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
166 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
167 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
168 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
169 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
170 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
171 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
172 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
173 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
175 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
177 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
179 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
181 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
182 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
183 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
184 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
185 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
186 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
187 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
188 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
189 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
190 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
191 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
192 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
193 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
194 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
195 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
196 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
197 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
198 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
199 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200,
200 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
201 { 0, } /* terminate list */
203 MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
205 /* ------------------------------------------------------------------------- *
207 * global variables
209 * ------------------------------------------------------------------------- */
211 /* command line data, set in rivafb_setup() */
212 static int flatpanel __devinitdata = -1; /* Autodetect later */
213 static int forceCRTC __devinitdata = -1;
214 static int noaccel __devinitdata = 0;
215 #ifdef CONFIG_MTRR
216 static int nomtrr __devinitdata = 0;
217 #endif
219 static char *mode_option __devinitdata = NULL;
220 static int strictmode = 0;
222 static struct fb_fix_screeninfo __devinitdata rivafb_fix = {
223 .type = FB_TYPE_PACKED_PIXELS,
224 .xpanstep = 1,
225 .ypanstep = 1,
228 static struct fb_var_screeninfo __devinitdata rivafb_default_var = {
229 .xres = 640,
230 .yres = 480,
231 .xres_virtual = 640,
232 .yres_virtual = 480,
233 .bits_per_pixel = 8,
234 .red = {0, 8, 0},
235 .green = {0, 8, 0},
236 .blue = {0, 8, 0},
237 .transp = {0, 0, 0},
238 .activate = FB_ACTIVATE_NOW,
239 .height = -1,
240 .width = -1,
241 .pixclock = 39721,
242 .left_margin = 40,
243 .right_margin = 24,
244 .upper_margin = 32,
245 .lower_margin = 11,
246 .hsync_len = 96,
247 .vsync_len = 2,
248 .vmode = FB_VMODE_NONINTERLACED
251 /* from GGI */
252 static const struct riva_regs reg_template = {
253 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */
254 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
255 0x41, 0x01, 0x0F, 0x00, 0x00},
256 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT */
257 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */
259 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
261 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, /* 0x40 */
266 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */
267 0xFF},
268 {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */
269 0xEB /* MISC */
273 * Backlight control
275 #ifdef CONFIG_PMAC_BACKLIGHT
277 static int riva_backlight_levels[] = {
278 0x158,
279 0x192,
280 0x1c6,
281 0x200,
282 0x234,
283 0x268,
284 0x2a2,
285 0x2d6,
286 0x310,
287 0x344,
288 0x378,
289 0x3b2,
290 0x3e6,
291 0x41a,
292 0x454,
293 0x534,
296 static int riva_set_backlight_enable(int on, int level, void *data);
297 static int riva_set_backlight_level(int level, void *data);
298 static struct backlight_controller riva_backlight_controller = {
299 riva_set_backlight_enable,
300 riva_set_backlight_level
302 #endif /* CONFIG_PMAC_BACKLIGHT */
304 /* ------------------------------------------------------------------------- *
306 * MMIO access macros
308 * ------------------------------------------------------------------------- */
310 static inline void CRTCout(struct riva_par *par, unsigned char index,
311 unsigned char val)
313 VGA_WR08(par->riva.PCIO, 0x3d4, index);
314 VGA_WR08(par->riva.PCIO, 0x3d5, val);
317 static inline unsigned char CRTCin(struct riva_par *par,
318 unsigned char index)
320 VGA_WR08(par->riva.PCIO, 0x3d4, index);
321 return (VGA_RD08(par->riva.PCIO, 0x3d5));
324 static inline void GRAout(struct riva_par *par, unsigned char index,
325 unsigned char val)
327 VGA_WR08(par->riva.PVIO, 0x3ce, index);
328 VGA_WR08(par->riva.PVIO, 0x3cf, val);
331 static inline unsigned char GRAin(struct riva_par *par,
332 unsigned char index)
334 VGA_WR08(par->riva.PVIO, 0x3ce, index);
335 return (VGA_RD08(par->riva.PVIO, 0x3cf));
338 static inline void SEQout(struct riva_par *par, unsigned char index,
339 unsigned char val)
341 VGA_WR08(par->riva.PVIO, 0x3c4, index);
342 VGA_WR08(par->riva.PVIO, 0x3c5, val);
345 static inline unsigned char SEQin(struct riva_par *par,
346 unsigned char index)
348 VGA_WR08(par->riva.PVIO, 0x3c4, index);
349 return (VGA_RD08(par->riva.PVIO, 0x3c5));
352 static inline void ATTRout(struct riva_par *par, unsigned char index,
353 unsigned char val)
355 VGA_WR08(par->riva.PCIO, 0x3c0, index);
356 VGA_WR08(par->riva.PCIO, 0x3c0, val);
359 static inline unsigned char ATTRin(struct riva_par *par,
360 unsigned char index)
362 VGA_WR08(par->riva.PCIO, 0x3c0, index);
363 return (VGA_RD08(par->riva.PCIO, 0x3c1));
366 static inline void MISCout(struct riva_par *par, unsigned char val)
368 VGA_WR08(par->riva.PVIO, 0x3c2, val);
371 static inline unsigned char MISCin(struct riva_par *par)
373 return (VGA_RD08(par->riva.PVIO, 0x3cc));
376 static u8 byte_rev[256] = {
377 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
378 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
379 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
380 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
381 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
382 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
383 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
384 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
385 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
386 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
387 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
388 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
389 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
390 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
391 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
392 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
393 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
394 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
395 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
396 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
397 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
398 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
399 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
400 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
401 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
402 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
403 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
404 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
405 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
406 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
407 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
408 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
411 static inline void reverse_order(u32 *l)
413 u8 *a = (u8 *)l;
414 *a = byte_rev[*a], a++;
415 *a = byte_rev[*a], a++;
416 *a = byte_rev[*a], a++;
417 *a = byte_rev[*a];
420 /* ------------------------------------------------------------------------- *
422 * cursor stuff
424 * ------------------------------------------------------------------------- */
427 * rivafb_load_cursor_image - load cursor image to hardware
428 * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
429 * @par: pointer to private data
430 * @w: width of cursor image in pixels
431 * @h: height of cursor image in scanlines
432 * @bg: background color (ARGB1555) - alpha bit determines opacity
433 * @fg: foreground color (ARGB1555)
435 * DESCRIPTiON:
436 * Loads cursor image based on a monochrome source and mask bitmap. The
437 * image bits determines the color of the pixel, 0 for background, 1 for
438 * foreground. Only the affected region (as determined by @w and @h
439 * parameters) will be updated.
441 * CALLED FROM:
442 * rivafb_cursor()
444 static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
445 u16 bg, u16 fg, u32 w, u32 h)
447 int i, j, k = 0;
448 u32 b, tmp;
449 u32 *data = (u32 *)data8;
450 bg = le16_to_cpu(bg);
451 fg = le16_to_cpu(fg);
453 w = (w + 1) & ~1;
455 for (i = 0; i < h; i++) {
456 b = *data++;
457 reverse_order(&b);
459 for (j = 0; j < w/2; j++) {
460 tmp = 0;
461 #if defined (__BIG_ENDIAN)
462 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
463 b <<= 1;
464 tmp |= (b & (1 << 31)) ? fg : bg;
465 b <<= 1;
466 #else
467 tmp = (b & 1) ? fg : bg;
468 b >>= 1;
469 tmp |= (b & 1) ? fg << 16 : bg << 16;
470 b >>= 1;
471 #endif
472 writel(tmp, &par->riva.CURSOR[k++]);
474 k += (MAX_CURS - w)/2;
478 /* ------------------------------------------------------------------------- *
480 * general utility functions
482 * ------------------------------------------------------------------------- */
485 * riva_wclut - set CLUT entry
486 * @chip: pointer to RIVA_HW_INST object
487 * @regnum: register number
488 * @red: red component
489 * @green: green component
490 * @blue: blue component
492 * DESCRIPTION:
493 * Sets color register @regnum.
495 * CALLED FROM:
496 * rivafb_setcolreg()
498 static void riva_wclut(RIVA_HW_INST *chip,
499 unsigned char regnum, unsigned char red,
500 unsigned char green, unsigned char blue)
502 VGA_WR08(chip->PDIO, 0x3c8, regnum);
503 VGA_WR08(chip->PDIO, 0x3c9, red);
504 VGA_WR08(chip->PDIO, 0x3c9, green);
505 VGA_WR08(chip->PDIO, 0x3c9, blue);
509 * riva_rclut - read fromCLUT register
510 * @chip: pointer to RIVA_HW_INST object
511 * @regnum: register number
512 * @red: red component
513 * @green: green component
514 * @blue: blue component
516 * DESCRIPTION:
517 * Reads red, green, and blue from color register @regnum.
519 * CALLED FROM:
520 * rivafb_setcolreg()
522 static void riva_rclut(RIVA_HW_INST *chip,
523 unsigned char regnum, unsigned char *red,
524 unsigned char *green, unsigned char *blue)
527 VGA_WR08(chip->PDIO, 0x3c7, regnum);
528 *red = VGA_RD08(chip->PDIO, 0x3c9);
529 *green = VGA_RD08(chip->PDIO, 0x3c9);
530 *blue = VGA_RD08(chip->PDIO, 0x3c9);
534 * riva_save_state - saves current chip state
535 * @par: pointer to riva_par object containing info for current riva board
536 * @regs: pointer to riva_regs object
538 * DESCRIPTION:
539 * Saves current chip state to @regs.
541 * CALLED FROM:
542 * rivafb_probe()
544 /* from GGI */
545 static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
547 int i;
549 NVTRACE_ENTER();
550 par->riva.LockUnlock(&par->riva, 0);
552 par->riva.UnloadStateExt(&par->riva, &regs->ext);
554 regs->misc_output = MISCin(par);
556 for (i = 0; i < NUM_CRT_REGS; i++)
557 regs->crtc[i] = CRTCin(par, i);
559 for (i = 0; i < NUM_ATC_REGS; i++)
560 regs->attr[i] = ATTRin(par, i);
562 for (i = 0; i < NUM_GRC_REGS; i++)
563 regs->gra[i] = GRAin(par, i);
565 for (i = 0; i < NUM_SEQ_REGS; i++)
566 regs->seq[i] = SEQin(par, i);
567 NVTRACE_LEAVE();
571 * riva_load_state - loads current chip state
572 * @par: pointer to riva_par object containing info for current riva board
573 * @regs: pointer to riva_regs object
575 * DESCRIPTION:
576 * Loads chip state from @regs.
578 * CALLED FROM:
579 * riva_load_video_mode()
580 * rivafb_probe()
581 * rivafb_remove()
583 /* from GGI */
584 static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
586 RIVA_HW_STATE *state = &regs->ext;
587 int i;
589 NVTRACE_ENTER();
590 CRTCout(par, 0x11, 0x00);
592 par->riva.LockUnlock(&par->riva, 0);
594 par->riva.LoadStateExt(&par->riva, state);
596 MISCout(par, regs->misc_output);
598 for (i = 0; i < NUM_CRT_REGS; i++) {
599 switch (i) {
600 case 0x19:
601 case 0x20 ... 0x40:
602 break;
603 default:
604 CRTCout(par, i, regs->crtc[i]);
608 for (i = 0; i < NUM_ATC_REGS; i++)
609 ATTRout(par, i, regs->attr[i]);
611 for (i = 0; i < NUM_GRC_REGS; i++)
612 GRAout(par, i, regs->gra[i]);
614 for (i = 0; i < NUM_SEQ_REGS; i++)
615 SEQout(par, i, regs->seq[i]);
616 NVTRACE_LEAVE();
620 * riva_load_video_mode - calculate timings
621 * @info: pointer to fb_info object containing info for current riva board
623 * DESCRIPTION:
624 * Calculate some timings and then send em off to riva_load_state().
626 * CALLED FROM:
627 * rivafb_set_par()
629 static void riva_load_video_mode(struct fb_info *info)
631 int bpp, width, hDisplaySize, hDisplay, hStart,
632 hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
633 int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
634 struct riva_par *par = info->par;
635 struct riva_regs newmode;
637 NVTRACE_ENTER();
638 /* time to calculate */
639 rivafb_blank(1, info);
641 bpp = info->var.bits_per_pixel;
642 if (bpp == 16 && info->var.green.length == 5)
643 bpp = 15;
644 width = info->var.xres_virtual;
645 hDisplaySize = info->var.xres;
646 hDisplay = (hDisplaySize / 8) - 1;
647 hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
648 hEnd = (hDisplaySize + info->var.right_margin +
649 info->var.hsync_len) / 8 - 1;
650 hTotal = (hDisplaySize + info->var.right_margin +
651 info->var.hsync_len + info->var.left_margin) / 8 - 5;
652 hBlankStart = hDisplay;
653 hBlankEnd = hTotal + 4;
655 height = info->var.yres_virtual;
656 vDisplay = info->var.yres - 1;
657 vStart = info->var.yres + info->var.lower_margin - 1;
658 vEnd = info->var.yres + info->var.lower_margin +
659 info->var.vsync_len - 1;
660 vTotal = info->var.yres + info->var.lower_margin +
661 info->var.vsync_len + info->var.upper_margin + 2;
662 vBlankStart = vDisplay;
663 vBlankEnd = vTotal + 1;
664 dotClock = 1000000000 / info->var.pixclock;
666 memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
668 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
669 vTotal |= 1;
671 if (par->FlatPanel) {
672 vStart = vTotal - 3;
673 vEnd = vTotal - 2;
674 vBlankStart = vStart;
675 hStart = hTotal - 3;
676 hEnd = hTotal - 2;
677 hBlankEnd = hTotal + 4;
680 newmode.crtc[0x0] = Set8Bits (hTotal);
681 newmode.crtc[0x1] = Set8Bits (hDisplay);
682 newmode.crtc[0x2] = Set8Bits (hBlankStart);
683 newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
684 newmode.crtc[0x4] = Set8Bits (hStart);
685 newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)
686 | SetBitField (hEnd, 4: 0, 4:0);
687 newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
688 newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
689 | SetBitField (vDisplay, 8: 8, 1:1)
690 | SetBitField (vStart, 8: 8, 2:2)
691 | SetBitField (vBlankStart, 8: 8, 3:3)
692 | SetBit (4)
693 | SetBitField (vTotal, 9: 9, 5:5)
694 | SetBitField (vDisplay, 9: 9, 6:6)
695 | SetBitField (vStart, 9: 9, 7:7);
696 newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)
697 | SetBit (6);
698 newmode.crtc[0x10] = Set8Bits (vStart);
699 newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
700 | SetBit (5);
701 newmode.crtc[0x12] = Set8Bits (vDisplay);
702 newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
703 newmode.crtc[0x15] = Set8Bits (vBlankStart);
704 newmode.crtc[0x16] = Set8Bits (vBlankEnd);
706 newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)
707 | SetBitField(vBlankStart,10:10,3:3)
708 | SetBitField(vStart,10:10,2:2)
709 | SetBitField(vDisplay,10:10,1:1)
710 | SetBitField(vTotal,10:10,0:0);
711 newmode.ext.horiz = SetBitField(hTotal,8:8,0:0)
712 | SetBitField(hDisplay,8:8,1:1)
713 | SetBitField(hBlankStart,8:8,2:2)
714 | SetBitField(hStart,8:8,3:3);
715 newmode.ext.extra = SetBitField(vTotal,11:11,0:0)
716 | SetBitField(vDisplay,11:11,2:2)
717 | SetBitField(vStart,11:11,4:4)
718 | SetBitField(vBlankStart,11:11,6:6);
720 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
721 int tmp = (hTotal >> 1) & ~1;
722 newmode.ext.interlace = Set8Bits(tmp);
723 newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
724 } else
725 newmode.ext.interlace = 0xff; /* interlace off */
727 if (par->riva.Architecture >= NV_ARCH_10)
728 par->riva.CURSOR = (U032 __iomem *)(info->screen_base + par->riva.CursorStart);
730 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
731 newmode.misc_output &= ~0x40;
732 else
733 newmode.misc_output |= 0x40;
734 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
735 newmode.misc_output &= ~0x80;
736 else
737 newmode.misc_output |= 0x80;
739 par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
740 hDisplaySize, height, dotClock);
742 newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
743 0xfff000ff;
744 if (par->FlatPanel == 1) {
745 newmode.ext.pixel |= (1 << 7);
746 newmode.ext.scale |= (1 << 8);
748 if (par->SecondCRTC) {
749 newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) &
750 ~0x00001000;
751 newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) |
752 0x00001000;
753 newmode.ext.crtcOwner = 3;
754 newmode.ext.pllsel |= 0x20000800;
755 newmode.ext.vpll2 = newmode.ext.vpll;
756 } else if (par->riva.twoHeads) {
757 newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) |
758 0x00001000;
759 newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) &
760 ~0x00001000;
761 newmode.ext.crtcOwner = 0;
762 newmode.ext.vpll2 = NV_RD32(par->riva.PRAMDAC0, 0x00000520);
764 if (par->FlatPanel == 1) {
765 newmode.ext.pixel |= (1 << 7);
766 newmode.ext.scale |= (1 << 8);
768 newmode.ext.cursorConfig = 0x02000100;
769 par->current_state = newmode;
770 riva_load_state(par, &par->current_state);
771 par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
772 rivafb_blank(0, info);
773 NVTRACE_LEAVE();
776 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
778 NVTRACE_ENTER();
779 var->xres = var->xres_virtual = modedb->xres;
780 var->yres = modedb->yres;
781 if (var->yres_virtual < var->yres)
782 var->yres_virtual = var->yres;
783 var->xoffset = var->yoffset = 0;
784 var->pixclock = modedb->pixclock;
785 var->left_margin = modedb->left_margin;
786 var->right_margin = modedb->right_margin;
787 var->upper_margin = modedb->upper_margin;
788 var->lower_margin = modedb->lower_margin;
789 var->hsync_len = modedb->hsync_len;
790 var->vsync_len = modedb->vsync_len;
791 var->sync = modedb->sync;
792 var->vmode = modedb->vmode;
793 NVTRACE_LEAVE();
797 * rivafb_do_maximize -
798 * @info: pointer to fb_info object containing info for current riva board
799 * @var:
800 * @nom:
801 * @den:
803 * DESCRIPTION:
806 * RETURNS:
807 * -EINVAL on failure, 0 on success
810 * CALLED FROM:
811 * rivafb_check_var()
813 static int rivafb_do_maximize(struct fb_info *info,
814 struct fb_var_screeninfo *var,
815 int nom, int den)
817 static struct {
818 int xres, yres;
819 } modes[] = {
820 {1600, 1280},
821 {1280, 1024},
822 {1024, 768},
823 {800, 600},
824 {640, 480},
825 {-1, -1}
827 int i;
829 NVTRACE_ENTER();
830 /* use highest possible virtual resolution */
831 if (var->xres_virtual == -1 && var->yres_virtual == -1) {
832 printk(KERN_WARNING PFX
833 "using maximum available virtual resolution\n");
834 for (i = 0; modes[i].xres != -1; i++) {
835 if (modes[i].xres * nom / den * modes[i].yres <
836 info->fix.smem_len)
837 break;
839 if (modes[i].xres == -1) {
840 printk(KERN_ERR PFX
841 "could not find a virtual resolution that fits into video memory!!\n");
842 NVTRACE("EXIT - EINVAL error\n");
843 return -EINVAL;
845 var->xres_virtual = modes[i].xres;
846 var->yres_virtual = modes[i].yres;
848 printk(KERN_INFO PFX
849 "virtual resolution set to maximum of %dx%d\n",
850 var->xres_virtual, var->yres_virtual);
851 } else if (var->xres_virtual == -1) {
852 var->xres_virtual = (info->fix.smem_len * den /
853 (nom * var->yres_virtual)) & ~15;
854 printk(KERN_WARNING PFX
855 "setting virtual X resolution to %d\n", var->xres_virtual);
856 } else if (var->yres_virtual == -1) {
857 var->xres_virtual = (var->xres_virtual + 15) & ~15;
858 var->yres_virtual = info->fix.smem_len * den /
859 (nom * var->xres_virtual);
860 printk(KERN_WARNING PFX
861 "setting virtual Y resolution to %d\n", var->yres_virtual);
862 } else {
863 var->xres_virtual = (var->xres_virtual + 15) & ~15;
864 if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
865 printk(KERN_ERR PFX
866 "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
867 var->xres, var->yres, var->bits_per_pixel);
868 NVTRACE("EXIT - EINVAL error\n");
869 return -EINVAL;
873 if (var->xres_virtual * nom / den >= 8192) {
874 printk(KERN_WARNING PFX
875 "virtual X resolution (%d) is too high, lowering to %d\n",
876 var->xres_virtual, 8192 * den / nom - 16);
877 var->xres_virtual = 8192 * den / nom - 16;
880 if (var->xres_virtual < var->xres) {
881 printk(KERN_ERR PFX
882 "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
883 return -EINVAL;
886 if (var->yres_virtual < var->yres) {
887 printk(KERN_ERR PFX
888 "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
889 return -EINVAL;
891 if (var->yres_virtual > 0x7fff/nom)
892 var->yres_virtual = 0x7fff/nom;
893 if (var->xres_virtual > 0x7fff/nom)
894 var->xres_virtual = 0x7fff/nom;
895 NVTRACE_LEAVE();
896 return 0;
899 static void
900 riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
902 RIVA_FIFO_FREE(par->riva, Patt, 4);
903 NV_WR32(&par->riva.Patt->Color0, 0, clr0);
904 NV_WR32(&par->riva.Patt->Color1, 0, clr1);
905 NV_WR32(par->riva.Patt->Monochrome, 0, pat0);
906 NV_WR32(par->riva.Patt->Monochrome, 4, pat1);
909 /* acceleration routines */
910 static inline void wait_for_idle(struct riva_par *par)
912 while (par->riva.Busy(&par->riva));
916 * Set ROP. Translate X rop into ROP3. Internal routine.
918 static void
919 riva_set_rop_solid(struct riva_par *par, int rop)
921 riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
922 RIVA_FIFO_FREE(par->riva, Rop, 1);
923 NV_WR32(&par->riva.Rop->Rop3, 0, rop);
927 static void riva_setup_accel(struct fb_info *info)
929 struct riva_par *par = info->par;
931 RIVA_FIFO_FREE(par->riva, Clip, 2);
932 NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0);
933 NV_WR32(&par->riva.Clip->WidthHeight, 0,
934 (info->var.xres_virtual & 0xffff) |
935 (info->var.yres_virtual << 16));
936 riva_set_rop_solid(par, 0xcc);
937 wait_for_idle(par);
941 * riva_get_cmap_len - query current color map length
942 * @var: standard kernel fb changeable data
944 * DESCRIPTION:
945 * Get current color map length.
947 * RETURNS:
948 * Length of color map
950 * CALLED FROM:
951 * rivafb_setcolreg()
953 static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
955 int rc = 256; /* reasonable default */
957 switch (var->green.length) {
958 case 8:
959 rc = 256; /* 256 entries (2^8), 8 bpp and RGB8888 */
960 break;
961 case 5:
962 rc = 32; /* 32 entries (2^5), 16 bpp, RGB555 */
963 break;
964 case 6:
965 rc = 64; /* 64 entries (2^6), 16 bpp, RGB565 */
966 break;
967 default:
968 /* should not occur */
969 break;
971 return rc;
974 /* ------------------------------------------------------------------------- *
976 * Backlight operations
978 * ------------------------------------------------------------------------- */
980 #ifdef CONFIG_PMAC_BACKLIGHT
981 static int riva_set_backlight_enable(int on, int level, void *data)
983 struct riva_par *par = data;
984 U032 tmp_pcrt, tmp_pmc;
986 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
987 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
988 if(on && (level > BACKLIGHT_OFF)) {
989 tmp_pcrt |= 0x1;
990 tmp_pmc |= (1 << 31); // backlight bit
991 tmp_pmc |= riva_backlight_levels[level-1] << 16; // level
993 par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
994 par->riva.PMC[0x10F0/4] = tmp_pmc;
995 return 0;
998 static int riva_set_backlight_level(int level, void *data)
1000 return riva_set_backlight_enable(1, level, data);
1002 #endif /* CONFIG_PMAC_BACKLIGHT */
1004 /* ------------------------------------------------------------------------- *
1006 * framebuffer operations
1008 * ------------------------------------------------------------------------- */
1010 static int rivafb_open(struct fb_info *info, int user)
1012 struct riva_par *par = info->par;
1013 int cnt = atomic_read(&par->ref_count);
1015 NVTRACE_ENTER();
1016 if (!cnt) {
1017 #ifdef CONFIG_X86
1018 memset(&par->state, 0, sizeof(struct vgastate));
1019 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
1020 /* save the DAC for Riva128 */
1021 if (par->riva.Architecture == NV_ARCH_03)
1022 par->state.flags |= VGA_SAVE_CMAP;
1023 save_vga(&par->state);
1024 #endif
1025 /* vgaHWunlock() + riva unlock (0x7F) */
1026 CRTCout(par, 0x11, 0xFF);
1027 par->riva.LockUnlock(&par->riva, 0);
1029 riva_save_state(par, &par->initial_state);
1031 atomic_inc(&par->ref_count);
1032 NVTRACE_LEAVE();
1033 return 0;
1036 static int rivafb_release(struct fb_info *info, int user)
1038 struct riva_par *par = info->par;
1039 int cnt = atomic_read(&par->ref_count);
1041 NVTRACE_ENTER();
1042 if (!cnt)
1043 return -EINVAL;
1044 if (cnt == 1) {
1045 par->riva.LockUnlock(&par->riva, 0);
1046 par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1047 riva_load_state(par, &par->initial_state);
1048 #ifdef CONFIG_X86
1049 restore_vga(&par->state);
1050 #endif
1051 par->riva.LockUnlock(&par->riva, 1);
1053 atomic_dec(&par->ref_count);
1054 NVTRACE_LEAVE();
1055 return 0;
1058 static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1060 struct fb_videomode *mode;
1061 struct riva_par *par = info->par;
1062 int nom, den; /* translating from pixels->bytes */
1063 int mode_valid = 0;
1065 NVTRACE_ENTER();
1066 switch (var->bits_per_pixel) {
1067 case 1 ... 8:
1068 var->red.offset = var->green.offset = var->blue.offset = 0;
1069 var->red.length = var->green.length = var->blue.length = 8;
1070 var->bits_per_pixel = 8;
1071 nom = den = 1;
1072 break;
1073 case 9 ... 15:
1074 var->green.length = 5;
1075 /* fall through */
1076 case 16:
1077 var->bits_per_pixel = 16;
1078 /* The Riva128 supports RGB555 only */
1079 if (par->riva.Architecture == NV_ARCH_03)
1080 var->green.length = 5;
1081 if (var->green.length == 5) {
1082 /* 0rrrrrgg gggbbbbb */
1083 var->red.offset = 10;
1084 var->green.offset = 5;
1085 var->blue.offset = 0;
1086 var->red.length = 5;
1087 var->green.length = 5;
1088 var->blue.length = 5;
1089 } else {
1090 /* rrrrrggg gggbbbbb */
1091 var->red.offset = 11;
1092 var->green.offset = 5;
1093 var->blue.offset = 0;
1094 var->red.length = 5;
1095 var->green.length = 6;
1096 var->blue.length = 5;
1098 nom = 2;
1099 den = 1;
1100 break;
1101 case 17 ... 32:
1102 var->red.length = var->green.length = var->blue.length = 8;
1103 var->bits_per_pixel = 32;
1104 var->red.offset = 16;
1105 var->green.offset = 8;
1106 var->blue.offset = 0;
1107 nom = 4;
1108 den = 1;
1109 break;
1110 default:
1111 printk(KERN_ERR PFX
1112 "mode %dx%dx%d rejected...color depth not supported.\n",
1113 var->xres, var->yres, var->bits_per_pixel);
1114 NVTRACE("EXIT, returning -EINVAL\n");
1115 return -EINVAL;
1118 if (!strictmode) {
1119 if (!info->monspecs.vfmax || !info->monspecs.hfmax ||
1120 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
1121 mode_valid = 1;
1124 /* calculate modeline if supported by monitor */
1125 if (!mode_valid && info->monspecs.gtf) {
1126 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1127 mode_valid = 1;
1130 if (!mode_valid) {
1131 mode = fb_find_best_mode(var, &info->modelist);
1132 if (mode) {
1133 riva_update_var(var, mode);
1134 mode_valid = 1;
1138 if (!mode_valid && info->monspecs.modedb_len)
1139 return -EINVAL;
1141 if (var->xres_virtual < var->xres)
1142 var->xres_virtual = var->xres;
1143 if (var->yres_virtual <= var->yres)
1144 var->yres_virtual = -1;
1145 if (rivafb_do_maximize(info, var, nom, den) < 0)
1146 return -EINVAL;
1148 if (var->xoffset < 0)
1149 var->xoffset = 0;
1150 if (var->yoffset < 0)
1151 var->yoffset = 0;
1153 /* truncate xoffset and yoffset to maximum if too high */
1154 if (var->xoffset > var->xres_virtual - var->xres)
1155 var->xoffset = var->xres_virtual - var->xres - 1;
1157 if (var->yoffset > var->yres_virtual - var->yres)
1158 var->yoffset = var->yres_virtual - var->yres - 1;
1160 var->red.msb_right =
1161 var->green.msb_right =
1162 var->blue.msb_right =
1163 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1164 NVTRACE_LEAVE();
1165 return 0;
1168 static int rivafb_set_par(struct fb_info *info)
1170 struct riva_par *par = info->par;
1172 NVTRACE_ENTER();
1173 /* vgaHWunlock() + riva unlock (0x7F) */
1174 CRTCout(par, 0x11, 0xFF);
1175 par->riva.LockUnlock(&par->riva, 0);
1176 riva_load_video_mode(info);
1177 if(!(info->flags & FBINFO_HWACCEL_DISABLED))
1178 riva_setup_accel(info);
1180 par->cursor_reset = 1;
1181 info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1182 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1183 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1185 if (info->flags & FBINFO_HWACCEL_DISABLED)
1186 info->pixmap.scan_align = 1;
1187 else
1188 info->pixmap.scan_align = 4;
1189 NVTRACE_LEAVE();
1190 return 0;
1194 * rivafb_pan_display
1195 * @var: standard kernel fb changeable data
1196 * @con: TODO
1197 * @info: pointer to fb_info object containing info for current riva board
1199 * DESCRIPTION:
1200 * Pan (or wrap, depending on the `vmode' field) the display using the
1201 * `xoffset' and `yoffset' fields of the `var' structure.
1202 * If the values don't fit, return -EINVAL.
1204 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1206 static int rivafb_pan_display(struct fb_var_screeninfo *var,
1207 struct fb_info *info)
1209 struct riva_par *par = info->par;
1210 unsigned int base;
1212 NVTRACE_ENTER();
1213 base = var->yoffset * info->fix.line_length + var->xoffset;
1214 par->riva.SetStartAddress(&par->riva, base);
1215 NVTRACE_LEAVE();
1216 return 0;
1219 static int rivafb_blank(int blank, struct fb_info *info)
1221 struct riva_par *par= info->par;
1222 unsigned char tmp, vesa;
1224 tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
1225 vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */
1227 NVTRACE_ENTER();
1229 if (blank)
1230 tmp |= 0x20;
1232 switch (blank) {
1233 case FB_BLANK_UNBLANK:
1234 case FB_BLANK_NORMAL:
1235 break;
1236 case FB_BLANK_VSYNC_SUSPEND:
1237 vesa |= 0x80;
1238 break;
1239 case FB_BLANK_HSYNC_SUSPEND:
1240 vesa |= 0x40;
1241 break;
1242 case FB_BLANK_POWERDOWN:
1243 vesa |= 0xc0;
1244 break;
1247 SEQout(par, 0x01, tmp);
1248 CRTCout(par, 0x1a, vesa);
1250 #ifdef CONFIG_PMAC_BACKLIGHT
1251 if ( par->FlatPanel && machine_is(powermac)) {
1252 set_backlight_enable(!blank);
1254 #endif
1256 NVTRACE_LEAVE();
1258 return 0;
1262 * rivafb_setcolreg
1263 * @regno: register index
1264 * @red: red component
1265 * @green: green component
1266 * @blue: blue component
1267 * @transp: transparency
1268 * @info: pointer to fb_info object containing info for current riva board
1270 * DESCRIPTION:
1271 * Set a single color register. The values supplied have a 16 bit
1272 * magnitude.
1274 * RETURNS:
1275 * Return != 0 for invalid regno.
1277 * CALLED FROM:
1278 * fbcmap.c:fb_set_cmap()
1280 static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1281 unsigned blue, unsigned transp,
1282 struct fb_info *info)
1284 struct riva_par *par = info->par;
1285 RIVA_HW_INST *chip = &par->riva;
1286 int i;
1288 if (regno >= riva_get_cmap_len(&info->var))
1289 return -EINVAL;
1291 if (info->var.grayscale) {
1292 /* gray = 0.30*R + 0.59*G + 0.11*B */
1293 red = green = blue =
1294 (red * 77 + green * 151 + blue * 28) >> 8;
1297 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1298 ((u32 *) info->pseudo_palette)[regno] =
1299 (regno << info->var.red.offset) |
1300 (regno << info->var.green.offset) |
1301 (regno << info->var.blue.offset);
1303 * The Riva128 2D engine requires color information in
1304 * TrueColor format even if framebuffer is in DirectColor
1306 if (par->riva.Architecture == NV_ARCH_03) {
1307 switch (info->var.bits_per_pixel) {
1308 case 16:
1309 par->palette[regno] = ((red & 0xf800) >> 1) |
1310 ((green & 0xf800) >> 6) |
1311 ((blue & 0xf800) >> 11);
1312 break;
1313 case 32:
1314 par->palette[regno] = ((red & 0xff00) << 8) |
1315 ((green & 0xff00)) |
1316 ((blue & 0xff00) >> 8);
1317 break;
1322 switch (info->var.bits_per_pixel) {
1323 case 8:
1324 /* "transparent" stuff is completely ignored. */
1325 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1326 break;
1327 case 16:
1328 if (info->var.green.length == 5) {
1329 for (i = 0; i < 8; i++) {
1330 riva_wclut(chip, regno*8+i, red >> 8,
1331 green >> 8, blue >> 8);
1333 } else {
1334 u8 r, g, b;
1336 if (regno < 32) {
1337 for (i = 0; i < 8; i++) {
1338 riva_wclut(chip, regno*8+i,
1339 red >> 8, green >> 8,
1340 blue >> 8);
1343 riva_rclut(chip, regno*4, &r, &g, &b);
1344 for (i = 0; i < 4; i++)
1345 riva_wclut(chip, regno*4+i, r,
1346 green >> 8, b);
1348 break;
1349 case 32:
1350 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1351 break;
1352 default:
1353 /* do nothing */
1354 break;
1356 return 0;
1360 * rivafb_fillrect - hardware accelerated color fill function
1361 * @info: pointer to fb_info structure
1362 * @rect: pointer to fb_fillrect structure
1364 * DESCRIPTION:
1365 * This function fills up a region of framebuffer memory with a solid
1366 * color with a choice of two different ROP's, copy or invert.
1368 * CALLED FROM:
1369 * framebuffer hook
1371 static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1373 struct riva_par *par = info->par;
1374 u_int color, rop = 0;
1376 if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
1377 cfb_fillrect(info, rect);
1378 return;
1381 if (info->var.bits_per_pixel == 8)
1382 color = rect->color;
1383 else {
1384 if (par->riva.Architecture != NV_ARCH_03)
1385 color = ((u32 *)info->pseudo_palette)[rect->color];
1386 else
1387 color = par->palette[rect->color];
1390 switch (rect->rop) {
1391 case ROP_XOR:
1392 rop = 0x66;
1393 break;
1394 case ROP_COPY:
1395 default:
1396 rop = 0xCC;
1397 break;
1400 riva_set_rop_solid(par, rop);
1402 RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1403 NV_WR32(&par->riva.Bitmap->Color1A, 0, color);
1405 RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1406 NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].TopLeft, 0,
1407 (rect->dx << 16) | rect->dy);
1408 mb();
1409 NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].WidthHeight, 0,
1410 (rect->width << 16) | rect->height);
1411 mb();
1412 riva_set_rop_solid(par, 0xcc);
1417 * rivafb_copyarea - hardware accelerated blit function
1418 * @info: pointer to fb_info structure
1419 * @region: pointer to fb_copyarea structure
1421 * DESCRIPTION:
1422 * This copies an area of pixels from one location to another
1424 * CALLED FROM:
1425 * framebuffer hook
1427 static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1429 struct riva_par *par = info->par;
1431 if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
1432 cfb_copyarea(info, region);
1433 return;
1436 RIVA_FIFO_FREE(par->riva, Blt, 3);
1437 NV_WR32(&par->riva.Blt->TopLeftSrc, 0,
1438 (region->sy << 16) | region->sx);
1439 NV_WR32(&par->riva.Blt->TopLeftDst, 0,
1440 (region->dy << 16) | region->dx);
1441 mb();
1442 NV_WR32(&par->riva.Blt->WidthHeight, 0,
1443 (region->height << 16) | region->width);
1444 mb();
1447 static inline void convert_bgcolor_16(u32 *col)
1449 *col = ((*col & 0x0000F800) << 8)
1450 | ((*col & 0x00007E0) << 5)
1451 | ((*col & 0x0000001F) << 3)
1452 | 0xFF000000;
1453 mb();
1457 * rivafb_imageblit: hardware accelerated color expand function
1458 * @info: pointer to fb_info structure
1459 * @image: pointer to fb_image structure
1461 * DESCRIPTION:
1462 * If the source is a monochrome bitmap, the function fills up a a region
1463 * of framebuffer memory with pixels whose color is determined by the bit
1464 * setting of the bitmap, 1 - foreground, 0 - background.
1466 * If the source is not a monochrome bitmap, color expansion is not done.
1467 * In this case, it is channeled to a software function.
1469 * CALLED FROM:
1470 * framebuffer hook
1472 static void rivafb_imageblit(struct fb_info *info,
1473 const struct fb_image *image)
1475 struct riva_par *par = info->par;
1476 u32 fgx = 0, bgx = 0, width, tmp;
1477 u8 *cdat = (u8 *) image->data;
1478 volatile u32 __iomem *d;
1479 int i, size;
1481 if ((info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) {
1482 cfb_imageblit(info, image);
1483 return;
1486 switch (info->var.bits_per_pixel) {
1487 case 8:
1488 fgx = image->fg_color;
1489 bgx = image->bg_color;
1490 break;
1491 case 16:
1492 case 32:
1493 if (par->riva.Architecture != NV_ARCH_03) {
1494 fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1495 bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1496 } else {
1497 fgx = par->palette[image->fg_color];
1498 bgx = par->palette[image->bg_color];
1500 if (info->var.green.length == 6)
1501 convert_bgcolor_16(&bgx);
1502 break;
1505 RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1506 NV_WR32(&par->riva.Bitmap->ClipE.TopLeft, 0,
1507 (image->dy << 16) | (image->dx & 0xFFFF));
1508 NV_WR32(&par->riva.Bitmap->ClipE.BottomRight, 0,
1509 (((image->dy + image->height) << 16) |
1510 ((image->dx + image->width) & 0xffff)));
1511 NV_WR32(&par->riva.Bitmap->Color0E, 0, bgx);
1512 NV_WR32(&par->riva.Bitmap->Color1E, 0, fgx);
1513 NV_WR32(&par->riva.Bitmap->WidthHeightInE, 0,
1514 (image->height << 16) | ((image->width + 31) & ~31));
1515 NV_WR32(&par->riva.Bitmap->WidthHeightOutE, 0,
1516 (image->height << 16) | ((image->width + 31) & ~31));
1517 NV_WR32(&par->riva.Bitmap->PointE, 0,
1518 (image->dy << 16) | (image->dx & 0xFFFF));
1520 d = &par->riva.Bitmap->MonochromeData01E;
1522 width = (image->width + 31)/32;
1523 size = width * image->height;
1524 while (size >= 16) {
1525 RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1526 for (i = 0; i < 16; i++) {
1527 tmp = *((u32 *)cdat);
1528 cdat = (u8 *)((u32 *)cdat + 1);
1529 reverse_order(&tmp);
1530 NV_WR32(d, i*4, tmp);
1532 size -= 16;
1534 if (size) {
1535 RIVA_FIFO_FREE(par->riva, Bitmap, size);
1536 for (i = 0; i < size; i++) {
1537 tmp = *((u32 *) cdat);
1538 cdat = (u8 *)((u32 *)cdat + 1);
1539 reverse_order(&tmp);
1540 NV_WR32(d, i*4, tmp);
1546 * rivafb_cursor - hardware cursor function
1547 * @info: pointer to info structure
1548 * @cursor: pointer to fbcursor structure
1550 * DESCRIPTION:
1551 * A cursor function that supports displaying a cursor image via hardware.
1552 * Within the kernel, copy and invert rops are supported. If exported
1553 * to user space, only the copy rop will be supported.
1555 * CALLED FROM
1556 * framebuffer hook
1558 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1560 struct riva_par *par = info->par;
1561 u8 data[MAX_CURS * MAX_CURS/8];
1562 int i, set = cursor->set;
1563 u16 fg, bg;
1565 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
1566 return -ENXIO;
1568 par->riva.ShowHideCursor(&par->riva, 0);
1570 if (par->cursor_reset) {
1571 set = FB_CUR_SETALL;
1572 par->cursor_reset = 0;
1575 if (set & FB_CUR_SETSIZE)
1576 memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1578 if (set & FB_CUR_SETPOS) {
1579 u32 xx, yy, temp;
1581 yy = cursor->image.dy - info->var.yoffset;
1582 xx = cursor->image.dx - info->var.xoffset;
1583 temp = xx & 0xFFFF;
1584 temp |= yy << 16;
1586 NV_WR32(par->riva.PRAMDAC, 0x0000300, temp);
1590 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
1591 u32 bg_idx = cursor->image.bg_color;
1592 u32 fg_idx = cursor->image.fg_color;
1593 u32 s_pitch = (cursor->image.width+7) >> 3;
1594 u32 d_pitch = MAX_CURS/8;
1595 u8 *dat = (u8 *) cursor->image.data;
1596 u8 *msk = (u8 *) cursor->mask;
1597 u8 *src;
1599 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
1601 if (src) {
1602 switch (cursor->rop) {
1603 case ROP_XOR:
1604 for (i = 0; i < s_pitch * cursor->image.height; i++)
1605 src[i] = dat[i] ^ msk[i];
1606 break;
1607 case ROP_COPY:
1608 default:
1609 for (i = 0; i < s_pitch * cursor->image.height; i++)
1610 src[i] = dat[i] & msk[i];
1611 break;
1614 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
1615 cursor->image.height);
1617 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1618 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1619 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
1620 1 << 15;
1622 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1623 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1624 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
1625 1 << 15;
1627 par->riva.LockUnlock(&par->riva, 0);
1629 rivafb_load_cursor_image(par, data, bg, fg,
1630 cursor->image.width,
1631 cursor->image.height);
1632 kfree(src);
1636 if (cursor->enable)
1637 par->riva.ShowHideCursor(&par->riva, 1);
1639 return 0;
1642 static int rivafb_sync(struct fb_info *info)
1644 struct riva_par *par = info->par;
1646 wait_for_idle(par);
1647 return 0;
1650 /* ------------------------------------------------------------------------- *
1652 * initialization helper functions
1654 * ------------------------------------------------------------------------- */
1656 /* kernel interface */
1657 static struct fb_ops riva_fb_ops = {
1658 .owner = THIS_MODULE,
1659 .fb_open = rivafb_open,
1660 .fb_release = rivafb_release,
1661 .fb_check_var = rivafb_check_var,
1662 .fb_set_par = rivafb_set_par,
1663 .fb_setcolreg = rivafb_setcolreg,
1664 .fb_pan_display = rivafb_pan_display,
1665 .fb_blank = rivafb_blank,
1666 .fb_fillrect = rivafb_fillrect,
1667 .fb_copyarea = rivafb_copyarea,
1668 .fb_imageblit = rivafb_imageblit,
1669 .fb_cursor = rivafb_cursor,
1670 .fb_sync = rivafb_sync,
1673 static int __devinit riva_set_fbinfo(struct fb_info *info)
1675 unsigned int cmap_len;
1676 struct riva_par *par = info->par;
1678 NVTRACE_ENTER();
1679 info->flags = FBINFO_DEFAULT
1680 | FBINFO_HWACCEL_XPAN
1681 | FBINFO_HWACCEL_YPAN
1682 | FBINFO_HWACCEL_COPYAREA
1683 | FBINFO_HWACCEL_FILLRECT
1684 | FBINFO_HWACCEL_IMAGEBLIT;
1686 /* Accel seems to not work properly on NV30 yet...*/
1687 if ((par->riva.Architecture == NV_ARCH_30) || noaccel) {
1688 printk(KERN_DEBUG PFX "disabling acceleration\n");
1689 info->flags |= FBINFO_HWACCEL_DISABLED;
1692 info->var = rivafb_default_var;
1693 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1694 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1696 info->pseudo_palette = par->pseudo_palette;
1698 cmap_len = riva_get_cmap_len(&info->var);
1699 fb_alloc_cmap(&info->cmap, cmap_len, 0);
1701 info->pixmap.size = 8 * 1024;
1702 info->pixmap.buf_align = 4;
1703 info->pixmap.access_align = 32;
1704 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1705 info->var.yres_virtual = -1;
1706 NVTRACE_LEAVE();
1707 return (rivafb_check_var(&info->var, info));
1710 #ifdef CONFIG_PPC_OF
1711 static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1713 struct riva_par *par = info->par;
1714 struct device_node *dp;
1715 unsigned char *pedid = NULL;
1716 unsigned char *disptype = NULL;
1717 static char *propnames[] = {
1718 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
1719 int i;
1721 NVTRACE_ENTER();
1722 dp = pci_device_to_OF_node(pd);
1723 for (; dp != NULL; dp = dp->child) {
1724 disptype = (unsigned char *)get_property(dp, "display-type", NULL);
1725 if (disptype == NULL)
1726 continue;
1727 if (strncmp(disptype, "LCD", 3) != 0)
1728 continue;
1729 for (i = 0; propnames[i] != NULL; ++i) {
1730 pedid = (unsigned char *)
1731 get_property(dp, propnames[i], NULL);
1732 if (pedid != NULL) {
1733 par->EDID = pedid;
1734 NVTRACE("LCD found.\n");
1735 return 1;
1739 NVTRACE_LEAVE();
1740 return 0;
1742 #endif /* CONFIG_PPC_OF */
1744 #if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF)
1745 static int __devinit riva_get_EDID_i2c(struct fb_info *info)
1747 struct riva_par *par = info->par;
1748 struct fb_var_screeninfo var;
1749 int i;
1751 NVTRACE_ENTER();
1752 riva_create_i2c_busses(par);
1753 for (i = 0; i < par->bus; i++) {
1754 riva_probe_i2c_connector(par, i+1, &par->EDID);
1755 if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
1756 printk(PFX "Found EDID Block from BUS %i\n", i);
1757 break;
1761 NVTRACE_LEAVE();
1762 return (par->EDID) ? 1 : 0;
1764 #endif /* CONFIG_FB_RIVA_I2C */
1766 static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
1767 struct fb_info *info)
1769 struct fb_monspecs *specs = &info->monspecs;
1770 struct fb_videomode modedb;
1772 NVTRACE_ENTER();
1773 /* respect mode options */
1774 if (mode_option) {
1775 fb_find_mode(var, info, mode_option,
1776 specs->modedb, specs->modedb_len,
1777 NULL, 8);
1778 } else if (specs->modedb != NULL) {
1779 /* get preferred timing */
1780 if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
1781 int i;
1783 for (i = 0; i < specs->modedb_len; i++) {
1784 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1785 modedb = specs->modedb[i];
1786 break;
1789 } else {
1790 /* otherwise, get first mode in database */
1791 modedb = specs->modedb[0];
1793 var->bits_per_pixel = 8;
1794 riva_update_var(var, &modedb);
1796 NVTRACE_LEAVE();
1800 static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1802 NVTRACE_ENTER();
1803 #ifdef CONFIG_PPC_OF
1804 if (!riva_get_EDID_OF(info, pdev))
1805 printk(PFX "could not retrieve EDID from OF\n");
1806 #elif defined(CONFIG_FB_RIVA_I2C)
1807 if (!riva_get_EDID_i2c(info))
1808 printk(PFX "could not retrieve EDID from DDC/I2C\n");
1809 #endif
1810 NVTRACE_LEAVE();
1814 static void __devinit riva_get_edidinfo(struct fb_info *info)
1816 struct fb_var_screeninfo *var = &rivafb_default_var;
1817 struct riva_par *par = info->par;
1819 fb_edid_to_monspecs(par->EDID, &info->monspecs);
1820 fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len,
1821 &info->modelist);
1822 riva_update_default_var(var, info);
1824 /* if user specified flatpanel, we respect that */
1825 if (info->monspecs.input & FB_DISP_DDI)
1826 par->FlatPanel = 1;
1829 /* ------------------------------------------------------------------------- *
1831 * PCI bus
1833 * ------------------------------------------------------------------------- */
1835 static u32 __devinit riva_get_arch(struct pci_dev *pd)
1837 u32 arch = 0;
1839 switch (pd->device & 0x0ff0) {
1840 case 0x0100: /* GeForce 256 */
1841 case 0x0110: /* GeForce2 MX */
1842 case 0x0150: /* GeForce2 */
1843 case 0x0170: /* GeForce4 MX */
1844 case 0x0180: /* GeForce4 MX (8x AGP) */
1845 case 0x01A0: /* nForce */
1846 case 0x01F0: /* nForce2 */
1847 arch = NV_ARCH_10;
1848 break;
1849 case 0x0200: /* GeForce3 */
1850 case 0x0250: /* GeForce4 Ti */
1851 case 0x0280: /* GeForce4 Ti (8x AGP) */
1852 arch = NV_ARCH_20;
1853 break;
1854 case 0x0300: /* GeForceFX 5800 */
1855 case 0x0310: /* GeForceFX 5600 */
1856 case 0x0320: /* GeForceFX 5200 */
1857 case 0x0330: /* GeForceFX 5900 */
1858 case 0x0340: /* GeForceFX 5700 */
1859 arch = NV_ARCH_30;
1860 break;
1861 case 0x0020: /* TNT, TNT2 */
1862 arch = NV_ARCH_04;
1863 break;
1864 case 0x0010: /* Riva128 */
1865 arch = NV_ARCH_03;
1866 break;
1867 default: /* unknown architecture */
1868 break;
1870 return arch;
1873 static int __devinit rivafb_probe(struct pci_dev *pd,
1874 const struct pci_device_id *ent)
1876 struct riva_par *default_par;
1877 struct fb_info *info;
1878 int ret;
1880 NVTRACE_ENTER();
1881 assert(pd != NULL);
1883 info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
1884 if (!info) {
1885 printk (KERN_ERR PFX "could not allocate memory\n");
1886 ret = -ENOMEM;
1887 goto err_ret;
1889 default_par = info->par;
1890 default_par->pdev = pd;
1892 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1893 if (info->pixmap.addr == NULL) {
1894 ret = -ENOMEM;
1895 goto err_framebuffer_release;
1897 memset(info->pixmap.addr, 0, 8 * 1024);
1899 ret = pci_enable_device(pd);
1900 if (ret < 0) {
1901 printk(KERN_ERR PFX "cannot enable PCI device\n");
1902 goto err_free_pixmap;
1905 ret = pci_request_regions(pd, "rivafb");
1906 if (ret < 0) {
1907 printk(KERN_ERR PFX "cannot request PCI regions\n");
1908 goto err_disable_device;
1911 default_par->riva.Architecture = riva_get_arch(pd);
1913 default_par->Chipset = (pd->vendor << 16) | pd->device;
1914 printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1916 if(default_par->riva.Architecture == 0) {
1917 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1918 ret=-ENODEV;
1919 goto err_release_region;
1921 if(default_par->riva.Architecture == NV_ARCH_10 ||
1922 default_par->riva.Architecture == NV_ARCH_20 ||
1923 default_par->riva.Architecture == NV_ARCH_30) {
1924 sprintf(rivafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1925 } else {
1926 sprintf(rivafb_fix.id, "NV%x", default_par->riva.Architecture);
1929 default_par->FlatPanel = flatpanel;
1930 if (flatpanel == 1)
1931 printk(KERN_INFO PFX "flatpanel support enabled\n");
1932 default_par->forceCRTC = forceCRTC;
1934 rivafb_fix.mmio_len = pci_resource_len(pd, 0);
1935 rivafb_fix.smem_len = pci_resource_len(pd, 1);
1938 /* enable IO and mem if not already done */
1939 unsigned short cmd;
1941 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1942 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1943 pci_write_config_word(pd, PCI_COMMAND, cmd);
1946 rivafb_fix.mmio_start = pci_resource_start(pd, 0);
1947 rivafb_fix.smem_start = pci_resource_start(pd, 1);
1949 default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
1950 rivafb_fix.mmio_len);
1951 if (!default_par->ctrl_base) {
1952 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1953 ret = -EIO;
1954 goto err_release_region;
1957 switch (default_par->riva.Architecture) {
1958 case NV_ARCH_03:
1959 /* Riva128's PRAMIN is in the "framebuffer" space
1960 * Since these cards were never made with more than 8 megabytes
1961 * we can safely allocate this separately.
1963 default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
1964 if (!default_par->riva.PRAMIN) {
1965 printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
1966 ret = -EIO;
1967 goto err_iounmap_ctrl_base;
1969 break;
1970 case NV_ARCH_04:
1971 case NV_ARCH_10:
1972 case NV_ARCH_20:
1973 case NV_ARCH_30:
1974 default_par->riva.PCRTC0 =
1975 (u32 __iomem *)(default_par->ctrl_base + 0x00600000);
1976 default_par->riva.PRAMIN =
1977 (u32 __iomem *)(default_par->ctrl_base + 0x00710000);
1978 break;
1980 riva_common_setup(default_par);
1982 if (default_par->riva.Architecture == NV_ARCH_03) {
1983 default_par->riva.PCRTC = default_par->riva.PCRTC0
1984 = default_par->riva.PGRAPH;
1987 rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
1988 default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
1989 info->screen_base = ioremap(rivafb_fix.smem_start,
1990 rivafb_fix.smem_len);
1991 if (!info->screen_base) {
1992 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1993 ret = -EIO;
1994 goto err_iounmap_pramin;
1997 #ifdef CONFIG_MTRR
1998 if (!nomtrr) {
1999 default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
2000 rivafb_fix.smem_len,
2001 MTRR_TYPE_WRCOMB, 1);
2002 if (default_par->mtrr.vram < 0) {
2003 printk(KERN_ERR PFX "unable to setup MTRR\n");
2004 } else {
2005 default_par->mtrr.vram_valid = 1;
2006 /* let there be speed */
2007 printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
2010 #endif /* CONFIG_MTRR */
2012 info->fbops = &riva_fb_ops;
2013 info->fix = rivafb_fix;
2014 riva_get_EDID(info, pd);
2015 riva_get_edidinfo(info);
2017 ret=riva_set_fbinfo(info);
2018 if (ret < 0) {
2019 printk(KERN_ERR PFX "error setting initial video mode\n");
2020 goto err_iounmap_screen_base;
2023 fb_destroy_modedb(info->monspecs.modedb);
2024 info->monspecs.modedb = NULL;
2025 ret = register_framebuffer(info);
2026 if (ret < 0) {
2027 printk(KERN_ERR PFX
2028 "error registering riva framebuffer\n");
2029 goto err_iounmap_screen_base;
2032 pci_set_drvdata(pd, info);
2034 printk(KERN_INFO PFX
2035 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
2036 info->fix.id,
2037 RIVAFB_VERSION,
2038 info->fix.smem_len / (1024 * 1024),
2039 info->fix.smem_start);
2040 #ifdef CONFIG_PMAC_BACKLIGHT
2041 if (default_par->FlatPanel && machine_is(powermac))
2042 register_backlight_controller(&riva_backlight_controller,
2043 default_par, "mnca");
2044 #endif
2045 NVTRACE_LEAVE();
2046 return 0;
2048 err_iounmap_screen_base:
2049 #ifdef CONFIG_FB_RIVA_I2C
2050 riva_delete_i2c_busses(info->par);
2051 #endif
2052 iounmap(info->screen_base);
2053 err_iounmap_pramin:
2054 if (default_par->riva.Architecture == NV_ARCH_03)
2055 iounmap(default_par->riva.PRAMIN);
2056 err_iounmap_ctrl_base:
2057 iounmap(default_par->ctrl_base);
2058 err_release_region:
2059 pci_release_regions(pd);
2060 err_disable_device:
2061 pci_disable_device(pd);
2062 err_free_pixmap:
2063 kfree(info->pixmap.addr);
2064 err_framebuffer_release:
2065 framebuffer_release(info);
2066 err_ret:
2067 return ret;
2070 static void __exit rivafb_remove(struct pci_dev *pd)
2072 struct fb_info *info = pci_get_drvdata(pd);
2073 struct riva_par *par = info->par;
2075 NVTRACE_ENTER();
2077 #ifdef CONFIG_FB_RIVA_I2C
2078 riva_delete_i2c_busses(par);
2079 kfree(par->EDID);
2080 #endif
2082 unregister_framebuffer(info);
2083 #ifdef CONFIG_MTRR
2084 if (par->mtrr.vram_valid)
2085 mtrr_del(par->mtrr.vram, info->fix.smem_start,
2086 info->fix.smem_len);
2087 #endif /* CONFIG_MTRR */
2089 iounmap(par->ctrl_base);
2090 iounmap(info->screen_base);
2091 if (par->riva.Architecture == NV_ARCH_03)
2092 iounmap(par->riva.PRAMIN);
2093 pci_release_regions(pd);
2094 pci_disable_device(pd);
2095 kfree(info->pixmap.addr);
2096 framebuffer_release(info);
2097 pci_set_drvdata(pd, NULL);
2098 NVTRACE_LEAVE();
2101 /* ------------------------------------------------------------------------- *
2103 * initialization
2105 * ------------------------------------------------------------------------- */
2107 #ifndef MODULE
2108 static int __init rivafb_setup(char *options)
2110 char *this_opt;
2112 NVTRACE_ENTER();
2113 if (!options || !*options)
2114 return 0;
2116 while ((this_opt = strsep(&options, ",")) != NULL) {
2117 if (!strncmp(this_opt, "forceCRTC", 9)) {
2118 char *p;
2120 p = this_opt + 9;
2121 if (!*p || !*(++p)) continue;
2122 forceCRTC = *p - '0';
2123 if (forceCRTC < 0 || forceCRTC > 1)
2124 forceCRTC = -1;
2125 } else if (!strncmp(this_opt, "flatpanel", 9)) {
2126 flatpanel = 1;
2127 #ifdef CONFIG_MTRR
2128 } else if (!strncmp(this_opt, "nomtrr", 6)) {
2129 nomtrr = 1;
2130 #endif
2131 } else if (!strncmp(this_opt, "strictmode", 10)) {
2132 strictmode = 1;
2133 } else if (!strncmp(this_opt, "noaccel", 7)) {
2134 noaccel = 1;
2135 } else
2136 mode_option = this_opt;
2138 NVTRACE_LEAVE();
2139 return 0;
2141 #endif /* !MODULE */
2143 static struct pci_driver rivafb_driver = {
2144 .name = "rivafb",
2145 .id_table = rivafb_pci_tbl,
2146 .probe = rivafb_probe,
2147 .remove = __exit_p(rivafb_remove),
2152 /* ------------------------------------------------------------------------- *
2154 * modularization
2156 * ------------------------------------------------------------------------- */
2158 static int __devinit rivafb_init(void)
2160 #ifndef MODULE
2161 char *option = NULL;
2163 if (fb_get_options("rivafb", &option))
2164 return -ENODEV;
2165 rivafb_setup(option);
2166 #endif
2167 return pci_register_driver(&rivafb_driver);
2171 module_init(rivafb_init);
2173 #ifdef MODULE
2174 static void __exit rivafb_exit(void)
2176 pci_unregister_driver(&rivafb_driver);
2179 module_exit(rivafb_exit);
2180 #endif /* MODULE */
2182 module_param(noaccel, bool, 0);
2183 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
2184 module_param(flatpanel, int, 0);
2185 MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2186 module_param(forceCRTC, int, 0);
2187 MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2188 #ifdef CONFIG_MTRR
2189 module_param(nomtrr, bool, 0);
2190 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2191 #endif
2192 module_param(strictmode, bool, 0);
2193 MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
2195 MODULE_AUTHOR("Ani Joshi, maintainer");
2196 MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
2197 MODULE_LICENSE("GPL");