blob: 6a30c0ca1de0a670e3117ec1a46acba1e63d5521 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver
3 *
4 * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
5 *
6 * Copyright 1999-2000 Jeff Garzik
7 *
8 * Contributors:
9 *
10 * Ani Joshi: Lots of debugging and cleanup work, really helped
11 * get the driver going
12 *
13 * Ferenc Bakonyi: Bug fixes, cleanup, modularization
14 *
15 * Jindrich Makovicka: Accel code help, hw cursor, mtrr
16 *
17 * Paul Richards: Bug fixes, updates
18 *
19 * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
20 * Includes riva_hw.c from nVidia, see copyright below.
21 * KGI code provided the basis for state storage, init, and mode switching.
22 *
23 * This file is subject to the terms and conditions of the GNU General Public
24 * License. See the file COPYING in the main directory of this archive
25 * for more details.
26 *
27 * Known bugs and issues:
28 * restoring text mode fails
29 * doublescan modes are broken
30 */
31
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#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/tty.h>
38#include <linux/slab.h>
39#include <linux/delay.h>
40#include <linux/fb.h>
41#include <linux/init.h>
42#include <linux/pci.h>
Michael Hanselmann5474c122006-06-25 05:47:08 -070043#include <linux/backlight.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#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
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +110052#include <asm/machdep.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <asm/backlight.h>
54#endif
55
56#include "rivafb.h"
57#include "nvreg.h"
58
59#ifndef CONFIG_PCI /* sanity check */
60#error This driver requires PCI support.
61#endif
62
63/* version number of this driver */
64#define RIVAFB_VERSION "0.9.5b"
65
66/* ------------------------------------------------------------------------- *
67 *
68 * various helpful macros and constants
69 *
70 * ------------------------------------------------------------------------- */
71#ifdef CONFIG_FB_RIVA_DEBUG
72#define NVTRACE printk
73#else
74#define NVTRACE if(0) printk
75#endif
76
77#define NVTRACE_ENTER(...) NVTRACE("%s START\n", __FUNCTION__)
78#define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __FUNCTION__)
79
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(); \
86 }
87#else
88#define assert(expr)
89#endif
90
91#define PFX "rivafb: "
92
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)
97
98/* HW cursor parameters */
99#define MAX_CURS 32
100
101/* ------------------------------------------------------------------------- *
102 *
103 * prototypes
104 *
105 * ------------------------------------------------------------------------- */
106
107static int rivafb_blank(int blank, struct fb_info *info);
108
109/* ------------------------------------------------------------------------- *
110 *
111 * card identification
112 *
113 * ------------------------------------------------------------------------- */
114
115static 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 */
202};
203MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
204
205/* ------------------------------------------------------------------------- *
206 *
207 * global variables
208 *
209 * ------------------------------------------------------------------------- */
210
211/* command line data, set in rivafb_setup() */
212static int flatpanel __devinitdata = -1; /* Autodetect later */
213static int forceCRTC __devinitdata = -1;
214static int noaccel __devinitdata = 0;
215#ifdef CONFIG_MTRR
216static int nomtrr __devinitdata = 0;
217#endif
218
219static char *mode_option __devinitdata = NULL;
220static int strictmode = 0;
221
222static struct fb_fix_screeninfo __devinitdata rivafb_fix = {
223 .type = FB_TYPE_PACKED_PIXELS,
224 .xpanstep = 1,
225 .ypanstep = 1,
226};
227
228static 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
249};
250
251/* from GGI */
252static 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 */
265 },
266 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */
267 0xFF},
268 {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */
269 0xEB /* MISC */
270};
271
272/*
273 * Backlight control
274 */
Michael Hanselmann5474c122006-06-25 05:47:08 -0700275#ifdef CONFIG_FB_RIVA_BACKLIGHT
276/* We do not have any information about which values are allowed, thus
277 * we used safe values.
278 */
279#define MIN_LEVEL 0x158
280#define MAX_LEVEL 0x534
281
282static struct backlight_properties riva_bl_data;
283
284static int riva_bl_get_level_brightness(struct riva_par *par,
285 int level)
286{
287 struct fb_info *info = pci_get_drvdata(par->pdev);
288 int nlevel;
289
290 /* Get and convert the value */
291 mutex_lock(&info->bl_mutex);
292 nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
293 mutex_unlock(&info->bl_mutex);
294
295 if (nlevel < 0)
296 nlevel = 0;
297 else if (nlevel < MIN_LEVEL)
298 nlevel = MIN_LEVEL;
299 else if (nlevel > MAX_LEVEL)
300 nlevel = MAX_LEVEL;
301
302 return nlevel;
303}
304
305static int riva_bl_update_status(struct backlight_device *bd)
306{
307 struct riva_par *par = class_get_devdata(&bd->class_dev);
308 U032 tmp_pcrt, tmp_pmc;
309 int level;
310
311 if (bd->props->power != FB_BLANK_UNBLANK ||
312 bd->props->fb_blank != FB_BLANK_UNBLANK)
313 level = 0;
314 else
315 level = bd->props->brightness;
316
317 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
318 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
319 if(level > 0) {
320 tmp_pcrt |= 0x1;
321 tmp_pmc |= (1 << 31); /* backlight bit */
322 tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
323 }
324 par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
325 par->riva.PMC[0x10F0/4] = tmp_pmc;
326
327 return 0;
328}
329
330static int riva_bl_get_brightness(struct backlight_device *bd)
331{
332 return bd->props->brightness;
333}
334
335static struct backlight_properties riva_bl_data = {
336 .owner = THIS_MODULE,
337 .get_brightness = riva_bl_get_brightness,
338 .update_status = riva_bl_update_status,
339 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
340};
341
342static void riva_bl_init(struct riva_par *par)
343{
344 struct fb_info *info = pci_get_drvdata(par->pdev);
345 struct backlight_device *bd;
346 char name[12];
347
348 if (!par->FlatPanel)
349 return;
350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351#ifdef CONFIG_PMAC_BACKLIGHT
Michael Hanselmann5474c122006-06-25 05:47:08 -0700352 if (!machine_is(powermac) ||
353 !pmac_has_backlight_type("mnca"))
354 return;
355#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Michael Hanselmann5474c122006-06-25 05:47:08 -0700357 snprintf(name, sizeof(name), "rivabl%d", info->node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
Michael Hanselmann5474c122006-06-25 05:47:08 -0700359 bd = backlight_device_register(name, par, &riva_bl_data);
360 if (IS_ERR(bd)) {
361 info->bl_dev = NULL;
362 printk("riva: Backlight registration failed\n");
363 goto error;
364 }
365
366 mutex_lock(&info->bl_mutex);
367 info->bl_dev = bd;
368 fb_bl_default_curve(info, 0,
369 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
370 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
371 mutex_unlock(&info->bl_mutex);
372
373 up(&bd->sem);
374 bd->props->brightness = riva_bl_data.max_brightness;
375 bd->props->power = FB_BLANK_UNBLANK;
376 bd->props->update_status(bd);
377 down(&bd->sem);
378
379#ifdef CONFIG_PMAC_BACKLIGHT
380 mutex_lock(&pmac_backlight_mutex);
381 if (!pmac_backlight)
382 pmac_backlight = bd;
383 mutex_unlock(&pmac_backlight_mutex);
384#endif
385
386 printk("riva: Backlight initialized (%s)\n", name);
387
388 return;
389
390error:
391 return;
392}
393
394static void riva_bl_exit(struct riva_par *par)
395{
396 struct fb_info *info = pci_get_drvdata(par->pdev);
397
398#ifdef CONFIG_PMAC_BACKLIGHT
399 mutex_lock(&pmac_backlight_mutex);
400#endif
401
402 mutex_lock(&info->bl_mutex);
403 if (info->bl_dev) {
404#ifdef CONFIG_PMAC_BACKLIGHT
405 if (pmac_backlight == info->bl_dev)
406 pmac_backlight = NULL;
407#endif
408
409 backlight_device_unregister(info->bl_dev);
410
411 printk("riva: Backlight unloaded\n");
412 }
413 mutex_unlock(&info->bl_mutex);
414
415#ifdef CONFIG_PMAC_BACKLIGHT
416 mutex_unlock(&pmac_backlight_mutex);
417#endif
418}
419#else
420static inline void riva_bl_init(struct riva_par *par) {}
421static inline void riva_bl_exit(struct riva_par *par) {}
422#endif /* CONFIG_FB_RIVA_BACKLIGHT */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
424/* ------------------------------------------------------------------------- *
425 *
426 * MMIO access macros
427 *
428 * ------------------------------------------------------------------------- */
429
430static inline void CRTCout(struct riva_par *par, unsigned char index,
431 unsigned char val)
432{
433 VGA_WR08(par->riva.PCIO, 0x3d4, index);
434 VGA_WR08(par->riva.PCIO, 0x3d5, val);
435}
436
437static inline unsigned char CRTCin(struct riva_par *par,
438 unsigned char index)
439{
440 VGA_WR08(par->riva.PCIO, 0x3d4, index);
441 return (VGA_RD08(par->riva.PCIO, 0x3d5));
442}
443
444static inline void GRAout(struct riva_par *par, unsigned char index,
445 unsigned char val)
446{
447 VGA_WR08(par->riva.PVIO, 0x3ce, index);
448 VGA_WR08(par->riva.PVIO, 0x3cf, val);
449}
450
451static inline unsigned char GRAin(struct riva_par *par,
452 unsigned char index)
453{
454 VGA_WR08(par->riva.PVIO, 0x3ce, index);
455 return (VGA_RD08(par->riva.PVIO, 0x3cf));
456}
457
458static inline void SEQout(struct riva_par *par, unsigned char index,
459 unsigned char val)
460{
461 VGA_WR08(par->riva.PVIO, 0x3c4, index);
462 VGA_WR08(par->riva.PVIO, 0x3c5, val);
463}
464
465static inline unsigned char SEQin(struct riva_par *par,
466 unsigned char index)
467{
468 VGA_WR08(par->riva.PVIO, 0x3c4, index);
469 return (VGA_RD08(par->riva.PVIO, 0x3c5));
470}
471
472static inline void ATTRout(struct riva_par *par, unsigned char index,
473 unsigned char val)
474{
475 VGA_WR08(par->riva.PCIO, 0x3c0, index);
476 VGA_WR08(par->riva.PCIO, 0x3c0, val);
477}
478
479static inline unsigned char ATTRin(struct riva_par *par,
480 unsigned char index)
481{
482 VGA_WR08(par->riva.PCIO, 0x3c0, index);
483 return (VGA_RD08(par->riva.PCIO, 0x3c1));
484}
485
486static inline void MISCout(struct riva_par *par, unsigned char val)
487{
488 VGA_WR08(par->riva.PVIO, 0x3c2, val);
489}
490
491static inline unsigned char MISCin(struct riva_par *par)
492{
493 return (VGA_RD08(par->riva.PVIO, 0x3cc));
494}
495
496static u8 byte_rev[256] = {
497 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
498 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
499 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
500 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
501 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
502 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
503 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
504 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
505 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
506 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
507 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
508 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
509 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
510 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
511 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
512 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
513 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
514 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
515 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
516 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
517 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
518 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
519 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
520 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
521 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
522 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
523 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
524 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
525 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
526 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
527 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
528 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
529};
530
531static inline void reverse_order(u32 *l)
532{
533 u8 *a = (u8 *)l;
534 *a = byte_rev[*a], a++;
535 *a = byte_rev[*a], a++;
536 *a = byte_rev[*a], a++;
537 *a = byte_rev[*a];
538}
539
540/* ------------------------------------------------------------------------- *
541 *
542 * cursor stuff
543 *
544 * ------------------------------------------------------------------------- */
545
546/**
547 * rivafb_load_cursor_image - load cursor image to hardware
548 * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
549 * @par: pointer to private data
550 * @w: width of cursor image in pixels
551 * @h: height of cursor image in scanlines
552 * @bg: background color (ARGB1555) - alpha bit determines opacity
553 * @fg: foreground color (ARGB1555)
554 *
555 * DESCRIPTiON:
556 * Loads cursor image based on a monochrome source and mask bitmap. The
557 * image bits determines the color of the pixel, 0 for background, 1 for
558 * foreground. Only the affected region (as determined by @w and @h
559 * parameters) will be updated.
560 *
561 * CALLED FROM:
562 * rivafb_cursor()
563 */
564static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
565 u16 bg, u16 fg, u32 w, u32 h)
566{
567 int i, j, k = 0;
568 u32 b, tmp;
569 u32 *data = (u32 *)data8;
570 bg = le16_to_cpu(bg);
571 fg = le16_to_cpu(fg);
572
573 w = (w + 1) & ~1;
574
575 for (i = 0; i < h; i++) {
576 b = *data++;
577 reverse_order(&b);
578
579 for (j = 0; j < w/2; j++) {
580 tmp = 0;
581#if defined (__BIG_ENDIAN)
582 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
583 b <<= 1;
584 tmp |= (b & (1 << 31)) ? fg : bg;
585 b <<= 1;
586#else
587 tmp = (b & 1) ? fg : bg;
588 b >>= 1;
589 tmp |= (b & 1) ? fg << 16 : bg << 16;
590 b >>= 1;
591#endif
592 writel(tmp, &par->riva.CURSOR[k++]);
593 }
594 k += (MAX_CURS - w)/2;
595 }
596}
597
598/* ------------------------------------------------------------------------- *
599 *
600 * general utility functions
601 *
602 * ------------------------------------------------------------------------- */
603
604/**
605 * riva_wclut - set CLUT entry
606 * @chip: pointer to RIVA_HW_INST object
607 * @regnum: register number
608 * @red: red component
609 * @green: green component
610 * @blue: blue component
611 *
612 * DESCRIPTION:
613 * Sets color register @regnum.
614 *
615 * CALLED FROM:
616 * rivafb_setcolreg()
617 */
618static void riva_wclut(RIVA_HW_INST *chip,
619 unsigned char regnum, unsigned char red,
620 unsigned char green, unsigned char blue)
621{
622 VGA_WR08(chip->PDIO, 0x3c8, regnum);
623 VGA_WR08(chip->PDIO, 0x3c9, red);
624 VGA_WR08(chip->PDIO, 0x3c9, green);
625 VGA_WR08(chip->PDIO, 0x3c9, blue);
626}
627
628/**
629 * riva_rclut - read fromCLUT register
630 * @chip: pointer to RIVA_HW_INST object
631 * @regnum: register number
632 * @red: red component
633 * @green: green component
634 * @blue: blue component
635 *
636 * DESCRIPTION:
637 * Reads red, green, and blue from color register @regnum.
638 *
639 * CALLED FROM:
640 * rivafb_setcolreg()
641 */
642static void riva_rclut(RIVA_HW_INST *chip,
643 unsigned char regnum, unsigned char *red,
644 unsigned char *green, unsigned char *blue)
645{
646
647 VGA_WR08(chip->PDIO, 0x3c7, regnum);
648 *red = VGA_RD08(chip->PDIO, 0x3c9);
649 *green = VGA_RD08(chip->PDIO, 0x3c9);
650 *blue = VGA_RD08(chip->PDIO, 0x3c9);
651}
652
653/**
654 * riva_save_state - saves current chip state
655 * @par: pointer to riva_par object containing info for current riva board
656 * @regs: pointer to riva_regs object
657 *
658 * DESCRIPTION:
659 * Saves current chip state to @regs.
660 *
661 * CALLED FROM:
662 * rivafb_probe()
663 */
664/* from GGI */
665static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
666{
667 int i;
668
669 NVTRACE_ENTER();
670 par->riva.LockUnlock(&par->riva, 0);
671
672 par->riva.UnloadStateExt(&par->riva, &regs->ext);
673
674 regs->misc_output = MISCin(par);
675
676 for (i = 0; i < NUM_CRT_REGS; i++)
677 regs->crtc[i] = CRTCin(par, i);
678
679 for (i = 0; i < NUM_ATC_REGS; i++)
680 regs->attr[i] = ATTRin(par, i);
681
682 for (i = 0; i < NUM_GRC_REGS; i++)
683 regs->gra[i] = GRAin(par, i);
684
685 for (i = 0; i < NUM_SEQ_REGS; i++)
686 regs->seq[i] = SEQin(par, i);
687 NVTRACE_LEAVE();
688}
689
690/**
691 * riva_load_state - loads current chip state
692 * @par: pointer to riva_par object containing info for current riva board
693 * @regs: pointer to riva_regs object
694 *
695 * DESCRIPTION:
696 * Loads chip state from @regs.
697 *
698 * CALLED FROM:
699 * riva_load_video_mode()
700 * rivafb_probe()
701 * rivafb_remove()
702 */
703/* from GGI */
704static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
705{
706 RIVA_HW_STATE *state = &regs->ext;
707 int i;
708
709 NVTRACE_ENTER();
710 CRTCout(par, 0x11, 0x00);
711
712 par->riva.LockUnlock(&par->riva, 0);
713
714 par->riva.LoadStateExt(&par->riva, state);
715
716 MISCout(par, regs->misc_output);
717
718 for (i = 0; i < NUM_CRT_REGS; i++) {
719 switch (i) {
720 case 0x19:
721 case 0x20 ... 0x40:
722 break;
723 default:
724 CRTCout(par, i, regs->crtc[i]);
725 }
726 }
727
728 for (i = 0; i < NUM_ATC_REGS; i++)
729 ATTRout(par, i, regs->attr[i]);
730
731 for (i = 0; i < NUM_GRC_REGS; i++)
732 GRAout(par, i, regs->gra[i]);
733
734 for (i = 0; i < NUM_SEQ_REGS; i++)
735 SEQout(par, i, regs->seq[i]);
736 NVTRACE_LEAVE();
737}
738
739/**
740 * riva_load_video_mode - calculate timings
741 * @info: pointer to fb_info object containing info for current riva board
742 *
743 * DESCRIPTION:
744 * Calculate some timings and then send em off to riva_load_state().
745 *
746 * CALLED FROM:
747 * rivafb_set_par()
748 */
749static void riva_load_video_mode(struct fb_info *info)
750{
751 int bpp, width, hDisplaySize, hDisplay, hStart,
752 hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
753 int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
Antonino A. Daplasf4a41832006-01-09 20:53:04 -0800754 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 struct riva_regs newmode;
756
757 NVTRACE_ENTER();
758 /* time to calculate */
759 rivafb_blank(1, info);
760
761 bpp = info->var.bits_per_pixel;
762 if (bpp == 16 && info->var.green.length == 5)
763 bpp = 15;
764 width = info->var.xres_virtual;
765 hDisplaySize = info->var.xres;
766 hDisplay = (hDisplaySize / 8) - 1;
767 hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
768 hEnd = (hDisplaySize + info->var.right_margin +
769 info->var.hsync_len) / 8 - 1;
770 hTotal = (hDisplaySize + info->var.right_margin +
771 info->var.hsync_len + info->var.left_margin) / 8 - 5;
772 hBlankStart = hDisplay;
773 hBlankEnd = hTotal + 4;
774
775 height = info->var.yres_virtual;
776 vDisplay = info->var.yres - 1;
777 vStart = info->var.yres + info->var.lower_margin - 1;
778 vEnd = info->var.yres + info->var.lower_margin +
779 info->var.vsync_len - 1;
780 vTotal = info->var.yres + info->var.lower_margin +
781 info->var.vsync_len + info->var.upper_margin + 2;
782 vBlankStart = vDisplay;
783 vBlankEnd = vTotal + 1;
784 dotClock = 1000000000 / info->var.pixclock;
785
786 memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
787
788 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
789 vTotal |= 1;
790
791 if (par->FlatPanel) {
792 vStart = vTotal - 3;
793 vEnd = vTotal - 2;
794 vBlankStart = vStart;
795 hStart = hTotal - 3;
796 hEnd = hTotal - 2;
797 hBlankEnd = hTotal + 4;
798 }
799
800 newmode.crtc[0x0] = Set8Bits (hTotal);
801 newmode.crtc[0x1] = Set8Bits (hDisplay);
802 newmode.crtc[0x2] = Set8Bits (hBlankStart);
803 newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
804 newmode.crtc[0x4] = Set8Bits (hStart);
805 newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)
806 | SetBitField (hEnd, 4: 0, 4:0);
807 newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
808 newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
809 | SetBitField (vDisplay, 8: 8, 1:1)
810 | SetBitField (vStart, 8: 8, 2:2)
811 | SetBitField (vBlankStart, 8: 8, 3:3)
812 | SetBit (4)
813 | SetBitField (vTotal, 9: 9, 5:5)
814 | SetBitField (vDisplay, 9: 9, 6:6)
815 | SetBitField (vStart, 9: 9, 7:7);
816 newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)
817 | SetBit (6);
818 newmode.crtc[0x10] = Set8Bits (vStart);
819 newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
820 | SetBit (5);
821 newmode.crtc[0x12] = Set8Bits (vDisplay);
822 newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
823 newmode.crtc[0x15] = Set8Bits (vBlankStart);
824 newmode.crtc[0x16] = Set8Bits (vBlankEnd);
825
826 newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)
827 | SetBitField(vBlankStart,10:10,3:3)
828 | SetBitField(vStart,10:10,2:2)
829 | SetBitField(vDisplay,10:10,1:1)
830 | SetBitField(vTotal,10:10,0:0);
831 newmode.ext.horiz = SetBitField(hTotal,8:8,0:0)
832 | SetBitField(hDisplay,8:8,1:1)
833 | SetBitField(hBlankStart,8:8,2:2)
834 | SetBitField(hStart,8:8,3:3);
835 newmode.ext.extra = SetBitField(vTotal,11:11,0:0)
836 | SetBitField(vDisplay,11:11,2:2)
837 | SetBitField(vStart,11:11,4:4)
838 | SetBitField(vBlankStart,11:11,6:6);
839
840 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
841 int tmp = (hTotal >> 1) & ~1;
842 newmode.ext.interlace = Set8Bits(tmp);
843 newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
844 } else
845 newmode.ext.interlace = 0xff; /* interlace off */
846
847 if (par->riva.Architecture >= NV_ARCH_10)
848 par->riva.CURSOR = (U032 __iomem *)(info->screen_base + par->riva.CursorStart);
849
850 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
851 newmode.misc_output &= ~0x40;
852 else
853 newmode.misc_output |= 0x40;
854 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
855 newmode.misc_output &= ~0x80;
856 else
857 newmode.misc_output |= 0x80;
858
859 par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
860 hDisplaySize, height, dotClock);
861
862 newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
863 0xfff000ff;
864 if (par->FlatPanel == 1) {
865 newmode.ext.pixel |= (1 << 7);
866 newmode.ext.scale |= (1 << 8);
867 }
868 if (par->SecondCRTC) {
869 newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) &
870 ~0x00001000;
871 newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) |
872 0x00001000;
873 newmode.ext.crtcOwner = 3;
874 newmode.ext.pllsel |= 0x20000800;
875 newmode.ext.vpll2 = newmode.ext.vpll;
876 } else if (par->riva.twoHeads) {
877 newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) |
878 0x00001000;
879 newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) &
880 ~0x00001000;
881 newmode.ext.crtcOwner = 0;
882 newmode.ext.vpll2 = NV_RD32(par->riva.PRAMDAC0, 0x00000520);
883 }
884 if (par->FlatPanel == 1) {
885 newmode.ext.pixel |= (1 << 7);
886 newmode.ext.scale |= (1 << 8);
887 }
888 newmode.ext.cursorConfig = 0x02000100;
889 par->current_state = newmode;
890 riva_load_state(par, &par->current_state);
891 par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
892 rivafb_blank(0, info);
893 NVTRACE_LEAVE();
894}
895
896static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
897{
898 NVTRACE_ENTER();
899 var->xres = var->xres_virtual = modedb->xres;
900 var->yres = modedb->yres;
901 if (var->yres_virtual < var->yres)
902 var->yres_virtual = var->yres;
903 var->xoffset = var->yoffset = 0;
904 var->pixclock = modedb->pixclock;
905 var->left_margin = modedb->left_margin;
906 var->right_margin = modedb->right_margin;
907 var->upper_margin = modedb->upper_margin;
908 var->lower_margin = modedb->lower_margin;
909 var->hsync_len = modedb->hsync_len;
910 var->vsync_len = modedb->vsync_len;
911 var->sync = modedb->sync;
912 var->vmode = modedb->vmode;
913 NVTRACE_LEAVE();
914}
915
916/**
917 * rivafb_do_maximize -
918 * @info: pointer to fb_info object containing info for current riva board
919 * @var:
920 * @nom:
921 * @den:
922 *
923 * DESCRIPTION:
924 * .
925 *
926 * RETURNS:
927 * -EINVAL on failure, 0 on success
928 *
929 *
930 * CALLED FROM:
931 * rivafb_check_var()
932 */
933static int rivafb_do_maximize(struct fb_info *info,
934 struct fb_var_screeninfo *var,
935 int nom, int den)
936{
937 static struct {
938 int xres, yres;
939 } modes[] = {
940 {1600, 1280},
941 {1280, 1024},
942 {1024, 768},
943 {800, 600},
944 {640, 480},
945 {-1, -1}
946 };
947 int i;
948
949 NVTRACE_ENTER();
950 /* use highest possible virtual resolution */
951 if (var->xres_virtual == -1 && var->yres_virtual == -1) {
952 printk(KERN_WARNING PFX
953 "using maximum available virtual resolution\n");
954 for (i = 0; modes[i].xres != -1; i++) {
955 if (modes[i].xres * nom / den * modes[i].yres <
956 info->fix.smem_len)
957 break;
958 }
959 if (modes[i].xres == -1) {
960 printk(KERN_ERR PFX
961 "could not find a virtual resolution that fits into video memory!!\n");
962 NVTRACE("EXIT - EINVAL error\n");
963 return -EINVAL;
964 }
965 var->xres_virtual = modes[i].xres;
966 var->yres_virtual = modes[i].yres;
967
968 printk(KERN_INFO PFX
969 "virtual resolution set to maximum of %dx%d\n",
970 var->xres_virtual, var->yres_virtual);
971 } else if (var->xres_virtual == -1) {
972 var->xres_virtual = (info->fix.smem_len * den /
973 (nom * var->yres_virtual)) & ~15;
974 printk(KERN_WARNING PFX
975 "setting virtual X resolution to %d\n", var->xres_virtual);
976 } else if (var->yres_virtual == -1) {
977 var->xres_virtual = (var->xres_virtual + 15) & ~15;
978 var->yres_virtual = info->fix.smem_len * den /
979 (nom * var->xres_virtual);
980 printk(KERN_WARNING PFX
981 "setting virtual Y resolution to %d\n", var->yres_virtual);
982 } else {
983 var->xres_virtual = (var->xres_virtual + 15) & ~15;
984 if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
985 printk(KERN_ERR PFX
986 "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
987 var->xres, var->yres, var->bits_per_pixel);
988 NVTRACE("EXIT - EINVAL error\n");
989 return -EINVAL;
990 }
991 }
992
993 if (var->xres_virtual * nom / den >= 8192) {
994 printk(KERN_WARNING PFX
995 "virtual X resolution (%d) is too high, lowering to %d\n",
996 var->xres_virtual, 8192 * den / nom - 16);
997 var->xres_virtual = 8192 * den / nom - 16;
998 }
999
1000 if (var->xres_virtual < var->xres) {
1001 printk(KERN_ERR PFX
1002 "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
1003 return -EINVAL;
1004 }
1005
1006 if (var->yres_virtual < var->yres) {
1007 printk(KERN_ERR PFX
1008 "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
1009 return -EINVAL;
1010 }
1011 if (var->yres_virtual > 0x7fff/nom)
1012 var->yres_virtual = 0x7fff/nom;
1013 if (var->xres_virtual > 0x7fff/nom)
1014 var->xres_virtual = 0x7fff/nom;
1015 NVTRACE_LEAVE();
1016 return 0;
1017}
1018
1019static void
1020riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
1021{
1022 RIVA_FIFO_FREE(par->riva, Patt, 4);
1023 NV_WR32(&par->riva.Patt->Color0, 0, clr0);
1024 NV_WR32(&par->riva.Patt->Color1, 0, clr1);
1025 NV_WR32(par->riva.Patt->Monochrome, 0, pat0);
1026 NV_WR32(par->riva.Patt->Monochrome, 4, pat1);
1027}
1028
1029/* acceleration routines */
1030static inline void wait_for_idle(struct riva_par *par)
1031{
1032 while (par->riva.Busy(&par->riva));
1033}
1034
1035/*
1036 * Set ROP. Translate X rop into ROP3. Internal routine.
1037 */
1038static void
1039riva_set_rop_solid(struct riva_par *par, int rop)
1040{
1041 riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1042 RIVA_FIFO_FREE(par->riva, Rop, 1);
1043 NV_WR32(&par->riva.Rop->Rop3, 0, rop);
1044
1045}
1046
1047static void riva_setup_accel(struct fb_info *info)
1048{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001049 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051 RIVA_FIFO_FREE(par->riva, Clip, 2);
1052 NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0);
1053 NV_WR32(&par->riva.Clip->WidthHeight, 0,
1054 (info->var.xres_virtual & 0xffff) |
1055 (info->var.yres_virtual << 16));
1056 riva_set_rop_solid(par, 0xcc);
1057 wait_for_idle(par);
1058}
1059
1060/**
1061 * riva_get_cmap_len - query current color map length
1062 * @var: standard kernel fb changeable data
1063 *
1064 * DESCRIPTION:
1065 * Get current color map length.
1066 *
1067 * RETURNS:
1068 * Length of color map
1069 *
1070 * CALLED FROM:
1071 * rivafb_setcolreg()
1072 */
1073static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
1074{
1075 int rc = 256; /* reasonable default */
1076
1077 switch (var->green.length) {
1078 case 8:
1079 rc = 256; /* 256 entries (2^8), 8 bpp and RGB8888 */
1080 break;
1081 case 5:
1082 rc = 32; /* 32 entries (2^5), 16 bpp, RGB555 */
1083 break;
1084 case 6:
1085 rc = 64; /* 64 entries (2^6), 16 bpp, RGB565 */
1086 break;
1087 default:
1088 /* should not occur */
1089 break;
1090 }
1091 return rc;
1092}
1093
1094/* ------------------------------------------------------------------------- *
1095 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 * framebuffer operations
1097 *
1098 * ------------------------------------------------------------------------- */
1099
1100static int rivafb_open(struct fb_info *info, int user)
1101{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001102 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 int cnt = atomic_read(&par->ref_count);
1104
1105 NVTRACE_ENTER();
1106 if (!cnt) {
1107#ifdef CONFIG_X86
1108 memset(&par->state, 0, sizeof(struct vgastate));
1109 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
1110 /* save the DAC for Riva128 */
1111 if (par->riva.Architecture == NV_ARCH_03)
1112 par->state.flags |= VGA_SAVE_CMAP;
1113 save_vga(&par->state);
1114#endif
1115 /* vgaHWunlock() + riva unlock (0x7F) */
1116 CRTCout(par, 0x11, 0xFF);
1117 par->riva.LockUnlock(&par->riva, 0);
1118
1119 riva_save_state(par, &par->initial_state);
1120 }
1121 atomic_inc(&par->ref_count);
1122 NVTRACE_LEAVE();
1123 return 0;
1124}
1125
1126static int rivafb_release(struct fb_info *info, int user)
1127{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001128 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 int cnt = atomic_read(&par->ref_count);
1130
1131 NVTRACE_ENTER();
1132 if (!cnt)
1133 return -EINVAL;
1134 if (cnt == 1) {
1135 par->riva.LockUnlock(&par->riva, 0);
1136 par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1137 riva_load_state(par, &par->initial_state);
1138#ifdef CONFIG_X86
1139 restore_vga(&par->state);
1140#endif
1141 par->riva.LockUnlock(&par->riva, 1);
1142 }
1143 atomic_dec(&par->ref_count);
1144 NVTRACE_LEAVE();
1145 return 0;
1146}
1147
1148static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1149{
1150 struct fb_videomode *mode;
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001151 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 int nom, den; /* translating from pixels->bytes */
1153 int mode_valid = 0;
1154
1155 NVTRACE_ENTER();
1156 switch (var->bits_per_pixel) {
1157 case 1 ... 8:
1158 var->red.offset = var->green.offset = var->blue.offset = 0;
1159 var->red.length = var->green.length = var->blue.length = 8;
1160 var->bits_per_pixel = 8;
1161 nom = den = 1;
1162 break;
1163 case 9 ... 15:
1164 var->green.length = 5;
1165 /* fall through */
1166 case 16:
1167 var->bits_per_pixel = 16;
1168 /* The Riva128 supports RGB555 only */
1169 if (par->riva.Architecture == NV_ARCH_03)
1170 var->green.length = 5;
1171 if (var->green.length == 5) {
1172 /* 0rrrrrgg gggbbbbb */
1173 var->red.offset = 10;
1174 var->green.offset = 5;
1175 var->blue.offset = 0;
1176 var->red.length = 5;
1177 var->green.length = 5;
1178 var->blue.length = 5;
1179 } else {
1180 /* rrrrrggg gggbbbbb */
1181 var->red.offset = 11;
1182 var->green.offset = 5;
1183 var->blue.offset = 0;
1184 var->red.length = 5;
1185 var->green.length = 6;
1186 var->blue.length = 5;
1187 }
1188 nom = 2;
1189 den = 1;
1190 break;
1191 case 17 ... 32:
1192 var->red.length = var->green.length = var->blue.length = 8;
1193 var->bits_per_pixel = 32;
1194 var->red.offset = 16;
1195 var->green.offset = 8;
1196 var->blue.offset = 0;
1197 nom = 4;
1198 den = 1;
1199 break;
1200 default:
1201 printk(KERN_ERR PFX
1202 "mode %dx%dx%d rejected...color depth not supported.\n",
1203 var->xres, var->yres, var->bits_per_pixel);
1204 NVTRACE("EXIT, returning -EINVAL\n");
1205 return -EINVAL;
1206 }
1207
1208 if (!strictmode) {
1209 if (!info->monspecs.vfmax || !info->monspecs.hfmax ||
1210 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
1211 mode_valid = 1;
1212 }
1213
1214 /* calculate modeline if supported by monitor */
1215 if (!mode_valid && info->monspecs.gtf) {
1216 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1217 mode_valid = 1;
1218 }
1219
1220 if (!mode_valid) {
1221 mode = fb_find_best_mode(var, &info->modelist);
1222 if (mode) {
1223 riva_update_var(var, mode);
1224 mode_valid = 1;
1225 }
1226 }
1227
1228 if (!mode_valid && info->monspecs.modedb_len)
1229 return -EINVAL;
1230
1231 if (var->xres_virtual < var->xres)
1232 var->xres_virtual = var->xres;
1233 if (var->yres_virtual <= var->yres)
1234 var->yres_virtual = -1;
1235 if (rivafb_do_maximize(info, var, nom, den) < 0)
1236 return -EINVAL;
1237
1238 if (var->xoffset < 0)
1239 var->xoffset = 0;
1240 if (var->yoffset < 0)
1241 var->yoffset = 0;
1242
1243 /* truncate xoffset and yoffset to maximum if too high */
1244 if (var->xoffset > var->xres_virtual - var->xres)
1245 var->xoffset = var->xres_virtual - var->xres - 1;
1246
1247 if (var->yoffset > var->yres_virtual - var->yres)
1248 var->yoffset = var->yres_virtual - var->yres - 1;
1249
1250 var->red.msb_right =
1251 var->green.msb_right =
1252 var->blue.msb_right =
1253 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1254 NVTRACE_LEAVE();
1255 return 0;
1256}
1257
1258static int rivafb_set_par(struct fb_info *info)
1259{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001260 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261
1262 NVTRACE_ENTER();
1263 /* vgaHWunlock() + riva unlock (0x7F) */
1264 CRTCout(par, 0x11, 0xFF);
1265 par->riva.LockUnlock(&par->riva, 0);
1266 riva_load_video_mode(info);
1267 if(!(info->flags & FBINFO_HWACCEL_DISABLED))
1268 riva_setup_accel(info);
1269
1270 par->cursor_reset = 1;
1271 info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1272 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1273 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1274
1275 if (info->flags & FBINFO_HWACCEL_DISABLED)
1276 info->pixmap.scan_align = 1;
1277 else
1278 info->pixmap.scan_align = 4;
1279 NVTRACE_LEAVE();
1280 return 0;
1281}
1282
1283/**
1284 * rivafb_pan_display
1285 * @var: standard kernel fb changeable data
1286 * @con: TODO
1287 * @info: pointer to fb_info object containing info for current riva board
1288 *
1289 * DESCRIPTION:
1290 * Pan (or wrap, depending on the `vmode' field) the display using the
1291 * `xoffset' and `yoffset' fields of the `var' structure.
1292 * If the values don't fit, return -EINVAL.
1293 *
1294 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1295 */
1296static int rivafb_pan_display(struct fb_var_screeninfo *var,
1297 struct fb_info *info)
1298{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001299 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 unsigned int base;
1301
1302 NVTRACE_ENTER();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 base = var->yoffset * info->fix.line_length + var->xoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 par->riva.SetStartAddress(&par->riva, base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 NVTRACE_LEAVE();
1306 return 0;
1307}
1308
1309static int rivafb_blank(int blank, struct fb_info *info)
1310{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001311 struct riva_par *par= info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 unsigned char tmp, vesa;
1313
1314 tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
1315 vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */
1316
1317 NVTRACE_ENTER();
1318
1319 if (blank)
1320 tmp |= 0x20;
1321
1322 switch (blank) {
1323 case FB_BLANK_UNBLANK:
1324 case FB_BLANK_NORMAL:
1325 break;
1326 case FB_BLANK_VSYNC_SUSPEND:
1327 vesa |= 0x80;
1328 break;
1329 case FB_BLANK_HSYNC_SUSPEND:
1330 vesa |= 0x40;
1331 break;
1332 case FB_BLANK_POWERDOWN:
1333 vesa |= 0xc0;
1334 break;
1335 }
1336
1337 SEQout(par, 0x01, tmp);
1338 CRTCout(par, 0x1a, vesa);
1339
Michael Hanselmann5474c122006-06-25 05:47:08 -07001340#ifdef CONFIG_FB_RIVA_BACKLIGHT
1341 mutex_lock(&info->bl_mutex);
1342 if (info->bl_dev) {
1343 down(&info->bl_dev->sem);
1344 info->bl_dev->props->power = blank;
1345 info->bl_dev->props->update_status(info->bl_dev);
1346 up(&info->bl_dev->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 }
Michael Hanselmann5474c122006-06-25 05:47:08 -07001348 mutex_unlock(&info->bl_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349#endif
1350
1351 NVTRACE_LEAVE();
1352
1353 return 0;
1354}
1355
1356/**
1357 * rivafb_setcolreg
1358 * @regno: register index
1359 * @red: red component
1360 * @green: green component
1361 * @blue: blue component
1362 * @transp: transparency
1363 * @info: pointer to fb_info object containing info for current riva board
1364 *
1365 * DESCRIPTION:
1366 * Set a single color register. The values supplied have a 16 bit
1367 * magnitude.
1368 *
1369 * RETURNS:
1370 * Return != 0 for invalid regno.
1371 *
1372 * CALLED FROM:
1373 * fbcmap.c:fb_set_cmap()
1374 */
1375static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1376 unsigned blue, unsigned transp,
1377 struct fb_info *info)
1378{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001379 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 RIVA_HW_INST *chip = &par->riva;
1381 int i;
1382
1383 if (regno >= riva_get_cmap_len(&info->var))
1384 return -EINVAL;
1385
1386 if (info->var.grayscale) {
1387 /* gray = 0.30*R + 0.59*G + 0.11*B */
1388 red = green = blue =
1389 (red * 77 + green * 151 + blue * 28) >> 8;
1390 }
1391
1392 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1393 ((u32 *) info->pseudo_palette)[regno] =
1394 (regno << info->var.red.offset) |
1395 (regno << info->var.green.offset) |
1396 (regno << info->var.blue.offset);
1397 /*
1398 * The Riva128 2D engine requires color information in
1399 * TrueColor format even if framebuffer is in DirectColor
1400 */
1401 if (par->riva.Architecture == NV_ARCH_03) {
1402 switch (info->var.bits_per_pixel) {
1403 case 16:
1404 par->palette[regno] = ((red & 0xf800) >> 1) |
1405 ((green & 0xf800) >> 6) |
1406 ((blue & 0xf800) >> 11);
1407 break;
1408 case 32:
1409 par->palette[regno] = ((red & 0xff00) << 8) |
1410 ((green & 0xff00)) |
1411 ((blue & 0xff00) >> 8);
1412 break;
1413 }
1414 }
1415 }
1416
1417 switch (info->var.bits_per_pixel) {
1418 case 8:
1419 /* "transparent" stuff is completely ignored. */
1420 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1421 break;
1422 case 16:
1423 if (info->var.green.length == 5) {
1424 for (i = 0; i < 8; i++) {
1425 riva_wclut(chip, regno*8+i, red >> 8,
1426 green >> 8, blue >> 8);
1427 }
1428 } else {
1429 u8 r, g, b;
1430
1431 if (regno < 32) {
1432 for (i = 0; i < 8; i++) {
1433 riva_wclut(chip, regno*8+i,
1434 red >> 8, green >> 8,
1435 blue >> 8);
1436 }
1437 }
1438 riva_rclut(chip, regno*4, &r, &g, &b);
1439 for (i = 0; i < 4; i++)
1440 riva_wclut(chip, regno*4+i, r,
1441 green >> 8, b);
1442 }
1443 break;
1444 case 32:
1445 riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1446 break;
1447 default:
1448 /* do nothing */
1449 break;
1450 }
1451 return 0;
1452}
1453
1454/**
1455 * rivafb_fillrect - hardware accelerated color fill function
1456 * @info: pointer to fb_info structure
1457 * @rect: pointer to fb_fillrect structure
1458 *
1459 * DESCRIPTION:
1460 * This function fills up a region of framebuffer memory with a solid
1461 * color with a choice of two different ROP's, copy or invert.
1462 *
1463 * CALLED FROM:
1464 * framebuffer hook
1465 */
1466static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1467{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001468 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 u_int color, rop = 0;
1470
1471 if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
1472 cfb_fillrect(info, rect);
1473 return;
1474 }
1475
1476 if (info->var.bits_per_pixel == 8)
1477 color = rect->color;
1478 else {
1479 if (par->riva.Architecture != NV_ARCH_03)
1480 color = ((u32 *)info->pseudo_palette)[rect->color];
1481 else
1482 color = par->palette[rect->color];
1483 }
1484
1485 switch (rect->rop) {
1486 case ROP_XOR:
1487 rop = 0x66;
1488 break;
1489 case ROP_COPY:
1490 default:
1491 rop = 0xCC;
1492 break;
1493 }
1494
1495 riva_set_rop_solid(par, rop);
1496
1497 RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1498 NV_WR32(&par->riva.Bitmap->Color1A, 0, color);
1499
1500 RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1501 NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].TopLeft, 0,
1502 (rect->dx << 16) | rect->dy);
1503 mb();
1504 NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].WidthHeight, 0,
1505 (rect->width << 16) | rect->height);
1506 mb();
1507 riva_set_rop_solid(par, 0xcc);
1508
1509}
1510
1511/**
1512 * rivafb_copyarea - hardware accelerated blit function
1513 * @info: pointer to fb_info structure
1514 * @region: pointer to fb_copyarea structure
1515 *
1516 * DESCRIPTION:
1517 * This copies an area of pixels from one location to another
1518 *
1519 * CALLED FROM:
1520 * framebuffer hook
1521 */
1522static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1523{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001524 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525
1526 if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
1527 cfb_copyarea(info, region);
1528 return;
1529 }
1530
1531 RIVA_FIFO_FREE(par->riva, Blt, 3);
1532 NV_WR32(&par->riva.Blt->TopLeftSrc, 0,
1533 (region->sy << 16) | region->sx);
1534 NV_WR32(&par->riva.Blt->TopLeftDst, 0,
1535 (region->dy << 16) | region->dx);
1536 mb();
1537 NV_WR32(&par->riva.Blt->WidthHeight, 0,
1538 (region->height << 16) | region->width);
1539 mb();
1540}
1541
1542static inline void convert_bgcolor_16(u32 *col)
1543{
1544 *col = ((*col & 0x0000F800) << 8)
1545 | ((*col & 0x00007E0) << 5)
1546 | ((*col & 0x0000001F) << 3)
1547 | 0xFF000000;
1548 mb();
1549}
1550
1551/**
1552 * rivafb_imageblit: hardware accelerated color expand function
1553 * @info: pointer to fb_info structure
1554 * @image: pointer to fb_image structure
1555 *
1556 * DESCRIPTION:
1557 * If the source is a monochrome bitmap, the function fills up a a region
1558 * of framebuffer memory with pixels whose color is determined by the bit
1559 * setting of the bitmap, 1 - foreground, 0 - background.
1560 *
1561 * If the source is not a monochrome bitmap, color expansion is not done.
1562 * In this case, it is channeled to a software function.
1563 *
1564 * CALLED FROM:
1565 * framebuffer hook
1566 */
1567static void rivafb_imageblit(struct fb_info *info,
1568 const struct fb_image *image)
1569{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001570 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 u32 fgx = 0, bgx = 0, width, tmp;
1572 u8 *cdat = (u8 *) image->data;
1573 volatile u32 __iomem *d;
1574 int i, size;
1575
1576 if ((info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) {
1577 cfb_imageblit(info, image);
1578 return;
1579 }
1580
1581 switch (info->var.bits_per_pixel) {
1582 case 8:
1583 fgx = image->fg_color;
1584 bgx = image->bg_color;
1585 break;
1586 case 16:
1587 case 32:
1588 if (par->riva.Architecture != NV_ARCH_03) {
1589 fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1590 bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1591 } else {
1592 fgx = par->palette[image->fg_color];
1593 bgx = par->palette[image->bg_color];
1594 }
1595 if (info->var.green.length == 6)
1596 convert_bgcolor_16(&bgx);
1597 break;
1598 }
1599
1600 RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1601 NV_WR32(&par->riva.Bitmap->ClipE.TopLeft, 0,
1602 (image->dy << 16) | (image->dx & 0xFFFF));
1603 NV_WR32(&par->riva.Bitmap->ClipE.BottomRight, 0,
1604 (((image->dy + image->height) << 16) |
1605 ((image->dx + image->width) & 0xffff)));
1606 NV_WR32(&par->riva.Bitmap->Color0E, 0, bgx);
1607 NV_WR32(&par->riva.Bitmap->Color1E, 0, fgx);
1608 NV_WR32(&par->riva.Bitmap->WidthHeightInE, 0,
1609 (image->height << 16) | ((image->width + 31) & ~31));
1610 NV_WR32(&par->riva.Bitmap->WidthHeightOutE, 0,
1611 (image->height << 16) | ((image->width + 31) & ~31));
1612 NV_WR32(&par->riva.Bitmap->PointE, 0,
1613 (image->dy << 16) | (image->dx & 0xFFFF));
1614
1615 d = &par->riva.Bitmap->MonochromeData01E;
1616
1617 width = (image->width + 31)/32;
1618 size = width * image->height;
1619 while (size >= 16) {
1620 RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1621 for (i = 0; i < 16; i++) {
1622 tmp = *((u32 *)cdat);
1623 cdat = (u8 *)((u32 *)cdat + 1);
1624 reverse_order(&tmp);
1625 NV_WR32(d, i*4, tmp);
1626 }
1627 size -= 16;
1628 }
1629 if (size) {
1630 RIVA_FIFO_FREE(par->riva, Bitmap, size);
1631 for (i = 0; i < size; i++) {
1632 tmp = *((u32 *) cdat);
1633 cdat = (u8 *)((u32 *)cdat + 1);
1634 reverse_order(&tmp);
1635 NV_WR32(d, i*4, tmp);
1636 }
1637 }
1638}
1639
1640/**
1641 * rivafb_cursor - hardware cursor function
1642 * @info: pointer to info structure
1643 * @cursor: pointer to fbcursor structure
1644 *
1645 * DESCRIPTION:
1646 * A cursor function that supports displaying a cursor image via hardware.
1647 * Within the kernel, copy and invert rops are supported. If exported
1648 * to user space, only the copy rop will be supported.
1649 *
1650 * CALLED FROM
1651 * framebuffer hook
1652 */
1653static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1654{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001655 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 u8 data[MAX_CURS * MAX_CURS/8];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 int i, set = cursor->set;
James Simmonsf1ab5da2005-06-21 17:17:07 -07001658 u16 fg, bg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
James Simmonsf1ab5da2005-06-21 17:17:07 -07001660 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
1661 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
1663 par->riva.ShowHideCursor(&par->riva, 0);
1664
1665 if (par->cursor_reset) {
1666 set = FB_CUR_SETALL;
1667 par->cursor_reset = 0;
1668 }
1669
1670 if (set & FB_CUR_SETSIZE)
1671 memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1672
1673 if (set & FB_CUR_SETPOS) {
1674 u32 xx, yy, temp;
1675
1676 yy = cursor->image.dy - info->var.yoffset;
1677 xx = cursor->image.dx - info->var.xoffset;
1678 temp = xx & 0xFFFF;
1679 temp |= yy << 16;
1680
1681 NV_WR32(par->riva.PRAMDAC, 0x0000300, temp);
1682 }
1683
1684
1685 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
1686 u32 bg_idx = cursor->image.bg_color;
1687 u32 fg_idx = cursor->image.fg_color;
1688 u32 s_pitch = (cursor->image.width+7) >> 3;
1689 u32 d_pitch = MAX_CURS/8;
1690 u8 *dat = (u8 *) cursor->image.data;
1691 u8 *msk = (u8 *) cursor->mask;
1692 u8 *src;
1693
1694 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
1695
1696 if (src) {
1697 switch (cursor->rop) {
1698 case ROP_XOR:
James Simmonsf1ab5da2005-06-21 17:17:07 -07001699 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 src[i] = dat[i] ^ msk[i];
1701 break;
1702 case ROP_COPY:
1703 default:
James Simmonsf1ab5da2005-06-21 17:17:07 -07001704 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 src[i] = dat[i] & msk[i];
1706 break;
1707 }
1708
James Simmonsf1ab5da2005-06-21 17:17:07 -07001709 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
1710 cursor->image.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
1712 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1713 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1714 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
1715 1 << 15;
1716
1717 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1718 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1719 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
1720 1 << 15;
1721
1722 par->riva.LockUnlock(&par->riva, 0);
1723
1724 rivafb_load_cursor_image(par, data, bg, fg,
1725 cursor->image.width,
1726 cursor->image.height);
1727 kfree(src);
1728 }
1729 }
1730
1731 if (cursor->enable)
1732 par->riva.ShowHideCursor(&par->riva, 1);
1733
1734 return 0;
1735}
1736
1737static int rivafb_sync(struct fb_info *info)
1738{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001739 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 wait_for_idle(par);
1742 return 0;
1743}
1744
1745/* ------------------------------------------------------------------------- *
1746 *
1747 * initialization helper functions
1748 *
1749 * ------------------------------------------------------------------------- */
1750
1751/* kernel interface */
1752static struct fb_ops riva_fb_ops = {
1753 .owner = THIS_MODULE,
1754 .fb_open = rivafb_open,
1755 .fb_release = rivafb_release,
1756 .fb_check_var = rivafb_check_var,
1757 .fb_set_par = rivafb_set_par,
1758 .fb_setcolreg = rivafb_setcolreg,
1759 .fb_pan_display = rivafb_pan_display,
1760 .fb_blank = rivafb_blank,
1761 .fb_fillrect = rivafb_fillrect,
1762 .fb_copyarea = rivafb_copyarea,
1763 .fb_imageblit = rivafb_imageblit,
1764 .fb_cursor = rivafb_cursor,
1765 .fb_sync = rivafb_sync,
1766};
1767
1768static int __devinit riva_set_fbinfo(struct fb_info *info)
1769{
1770 unsigned int cmap_len;
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001771 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
1773 NVTRACE_ENTER();
1774 info->flags = FBINFO_DEFAULT
1775 | FBINFO_HWACCEL_XPAN
1776 | FBINFO_HWACCEL_YPAN
1777 | FBINFO_HWACCEL_COPYAREA
1778 | FBINFO_HWACCEL_FILLRECT
1779 | FBINFO_HWACCEL_IMAGEBLIT;
1780
1781 /* Accel seems to not work properly on NV30 yet...*/
1782 if ((par->riva.Architecture == NV_ARCH_30) || noaccel) {
1783 printk(KERN_DEBUG PFX "disabling acceleration\n");
1784 info->flags |= FBINFO_HWACCEL_DISABLED;
1785 }
1786
1787 info->var = rivafb_default_var;
1788 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1789 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1790
1791 info->pseudo_palette = par->pseudo_palette;
1792
1793 cmap_len = riva_get_cmap_len(&info->var);
1794 fb_alloc_cmap(&info->cmap, cmap_len, 0);
1795
1796 info->pixmap.size = 8 * 1024;
1797 info->pixmap.buf_align = 4;
James Simmons58a60642005-06-21 17:17:08 -07001798 info->pixmap.access_align = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1800 info->var.yres_virtual = -1;
1801 NVTRACE_LEAVE();
1802 return (rivafb_check_var(&info->var, info));
1803}
1804
1805#ifdef CONFIG_PPC_OF
1806static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1807{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001808 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 struct device_node *dp;
1810 unsigned char *pedid = NULL;
1811 unsigned char *disptype = NULL;
1812 static char *propnames[] = {
1813 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
1814 int i;
1815
1816 NVTRACE_ENTER();
1817 dp = pci_device_to_OF_node(pd);
1818 for (; dp != NULL; dp = dp->child) {
Jeremy Kerrb04e3dd2006-07-12 15:40:40 +10001819 disptype = get_property(dp, "display-type", NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 if (disptype == NULL)
1821 continue;
1822 if (strncmp(disptype, "LCD", 3) != 0)
1823 continue;
1824 for (i = 0; propnames[i] != NULL; ++i) {
Jeremy Kerrb04e3dd2006-07-12 15:40:40 +10001825 pedid = get_property(dp, propnames[i], NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 if (pedid != NULL) {
1827 par->EDID = pedid;
1828 NVTRACE("LCD found.\n");
1829 return 1;
1830 }
1831 }
1832 }
1833 NVTRACE_LEAVE();
1834 return 0;
1835}
1836#endif /* CONFIG_PPC_OF */
1837
1838#if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF)
1839static int __devinit riva_get_EDID_i2c(struct fb_info *info)
1840{
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001841 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 struct fb_var_screeninfo var;
1843 int i;
1844
1845 NVTRACE_ENTER();
1846 riva_create_i2c_busses(par);
1847 for (i = 0; i < par->bus; i++) {
1848 riva_probe_i2c_connector(par, i+1, &par->EDID);
1849 if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
1850 printk(PFX "Found EDID Block from BUS %i\n", i);
1851 break;
1852 }
1853 }
1854
1855 NVTRACE_LEAVE();
1856 return (par->EDID) ? 1 : 0;
1857}
1858#endif /* CONFIG_FB_RIVA_I2C */
1859
1860static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
1861 struct fb_info *info)
1862{
1863 struct fb_monspecs *specs = &info->monspecs;
1864 struct fb_videomode modedb;
1865
1866 NVTRACE_ENTER();
1867 /* respect mode options */
1868 if (mode_option) {
1869 fb_find_mode(var, info, mode_option,
1870 specs->modedb, specs->modedb_len,
1871 NULL, 8);
1872 } else if (specs->modedb != NULL) {
1873 /* get preferred timing */
1874 if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
1875 int i;
1876
1877 for (i = 0; i < specs->modedb_len; i++) {
1878 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1879 modedb = specs->modedb[i];
1880 break;
1881 }
1882 }
1883 } else {
1884 /* otherwise, get first mode in database */
1885 modedb = specs->modedb[0];
1886 }
1887 var->bits_per_pixel = 8;
1888 riva_update_var(var, &modedb);
1889 }
1890 NVTRACE_LEAVE();
1891}
1892
1893
1894static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1895{
1896 NVTRACE_ENTER();
1897#ifdef CONFIG_PPC_OF
1898 if (!riva_get_EDID_OF(info, pdev))
1899 printk(PFX "could not retrieve EDID from OF\n");
Olaf Hering44456d32005-07-27 11:45:17 -07001900#elif defined(CONFIG_FB_RIVA_I2C)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 if (!riva_get_EDID_i2c(info))
1902 printk(PFX "could not retrieve EDID from DDC/I2C\n");
1903#endif
1904 NVTRACE_LEAVE();
1905}
1906
1907
1908static void __devinit riva_get_edidinfo(struct fb_info *info)
1909{
1910 struct fb_var_screeninfo *var = &rivafb_default_var;
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001911 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
1913 fb_edid_to_monspecs(par->EDID, &info->monspecs);
1914 fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len,
1915 &info->modelist);
1916 riva_update_default_var(var, info);
1917
1918 /* if user specified flatpanel, we respect that */
1919 if (info->monspecs.input & FB_DISP_DDI)
1920 par->FlatPanel = 1;
1921}
1922
1923/* ------------------------------------------------------------------------- *
1924 *
1925 * PCI bus
1926 *
1927 * ------------------------------------------------------------------------- */
1928
1929static u32 __devinit riva_get_arch(struct pci_dev *pd)
1930{
1931 u32 arch = 0;
1932
1933 switch (pd->device & 0x0ff0) {
1934 case 0x0100: /* GeForce 256 */
1935 case 0x0110: /* GeForce2 MX */
1936 case 0x0150: /* GeForce2 */
1937 case 0x0170: /* GeForce4 MX */
1938 case 0x0180: /* GeForce4 MX (8x AGP) */
1939 case 0x01A0: /* nForce */
1940 case 0x01F0: /* nForce2 */
1941 arch = NV_ARCH_10;
1942 break;
1943 case 0x0200: /* GeForce3 */
1944 case 0x0250: /* GeForce4 Ti */
1945 case 0x0280: /* GeForce4 Ti (8x AGP) */
1946 arch = NV_ARCH_20;
1947 break;
1948 case 0x0300: /* GeForceFX 5800 */
1949 case 0x0310: /* GeForceFX 5600 */
1950 case 0x0320: /* GeForceFX 5200 */
1951 case 0x0330: /* GeForceFX 5900 */
1952 case 0x0340: /* GeForceFX 5700 */
1953 arch = NV_ARCH_30;
1954 break;
1955 case 0x0020: /* TNT, TNT2 */
1956 arch = NV_ARCH_04;
1957 break;
1958 case 0x0010: /* Riva128 */
1959 arch = NV_ARCH_03;
1960 break;
1961 default: /* unknown architecture */
1962 break;
1963 }
1964 return arch;
1965}
1966
1967static int __devinit rivafb_probe(struct pci_dev *pd,
1968 const struct pci_device_id *ent)
1969{
1970 struct riva_par *default_par;
1971 struct fb_info *info;
1972 int ret;
1973
1974 NVTRACE_ENTER();
1975 assert(pd != NULL);
1976
1977 info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
1978 if (!info) {
1979 printk (KERN_ERR PFX "could not allocate memory\n");
1980 ret = -ENOMEM;
1981 goto err_ret;
1982 }
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08001983 default_par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 default_par->pdev = pd;
1985
1986 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1987 if (info->pixmap.addr == NULL) {
1988 ret = -ENOMEM;
1989 goto err_framebuffer_release;
1990 }
1991 memset(info->pixmap.addr, 0, 8 * 1024);
1992
1993 ret = pci_enable_device(pd);
1994 if (ret < 0) {
1995 printk(KERN_ERR PFX "cannot enable PCI device\n");
1996 goto err_free_pixmap;
1997 }
1998
1999 ret = pci_request_regions(pd, "rivafb");
2000 if (ret < 0) {
2001 printk(KERN_ERR PFX "cannot request PCI regions\n");
2002 goto err_disable_device;
2003 }
2004
2005 default_par->riva.Architecture = riva_get_arch(pd);
2006
2007 default_par->Chipset = (pd->vendor << 16) | pd->device;
2008 printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
2009
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 if(default_par->riva.Architecture == 0) {
2011 printk(KERN_ERR PFX "unknown NV_ARCH\n");
2012 ret=-ENODEV;
2013 goto err_release_region;
2014 }
2015 if(default_par->riva.Architecture == NV_ARCH_10 ||
2016 default_par->riva.Architecture == NV_ARCH_20 ||
2017 default_par->riva.Architecture == NV_ARCH_30) {
2018 sprintf(rivafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
2019 } else {
2020 sprintf(rivafb_fix.id, "NV%x", default_par->riva.Architecture);
2021 }
2022
2023 default_par->FlatPanel = flatpanel;
2024 if (flatpanel == 1)
2025 printk(KERN_INFO PFX "flatpanel support enabled\n");
2026 default_par->forceCRTC = forceCRTC;
2027
2028 rivafb_fix.mmio_len = pci_resource_len(pd, 0);
2029 rivafb_fix.smem_len = pci_resource_len(pd, 1);
2030
2031 {
2032 /* enable IO and mem if not already done */
2033 unsigned short cmd;
2034
2035 pci_read_config_word(pd, PCI_COMMAND, &cmd);
2036 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
2037 pci_write_config_word(pd, PCI_COMMAND, cmd);
2038 }
2039
2040 rivafb_fix.mmio_start = pci_resource_start(pd, 0);
2041 rivafb_fix.smem_start = pci_resource_start(pd, 1);
2042
2043 default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
2044 rivafb_fix.mmio_len);
2045 if (!default_par->ctrl_base) {
2046 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
2047 ret = -EIO;
2048 goto err_release_region;
2049 }
2050
2051 switch (default_par->riva.Architecture) {
2052 case NV_ARCH_03:
2053 /* Riva128's PRAMIN is in the "framebuffer" space
2054 * Since these cards were never made with more than 8 megabytes
2055 * we can safely allocate this separately.
2056 */
2057 default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
2058 if (!default_par->riva.PRAMIN) {
2059 printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
2060 ret = -EIO;
2061 goto err_iounmap_ctrl_base;
2062 }
2063 break;
2064 case NV_ARCH_04:
2065 case NV_ARCH_10:
2066 case NV_ARCH_20:
2067 case NV_ARCH_30:
2068 default_par->riva.PCRTC0 =
2069 (u32 __iomem *)(default_par->ctrl_base + 0x00600000);
2070 default_par->riva.PRAMIN =
2071 (u32 __iomem *)(default_par->ctrl_base + 0x00710000);
2072 break;
2073 }
2074 riva_common_setup(default_par);
2075
2076 if (default_par->riva.Architecture == NV_ARCH_03) {
2077 default_par->riva.PCRTC = default_par->riva.PCRTC0
2078 = default_par->riva.PGRAPH;
2079 }
2080
2081 rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
2082 default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
2083 info->screen_base = ioremap(rivafb_fix.smem_start,
2084 rivafb_fix.smem_len);
2085 if (!info->screen_base) {
2086 printk(KERN_ERR PFX "cannot ioremap FB base\n");
2087 ret = -EIO;
2088 goto err_iounmap_pramin;
2089 }
2090
2091#ifdef CONFIG_MTRR
2092 if (!nomtrr) {
2093 default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
2094 rivafb_fix.smem_len,
2095 MTRR_TYPE_WRCOMB, 1);
2096 if (default_par->mtrr.vram < 0) {
2097 printk(KERN_ERR PFX "unable to setup MTRR\n");
2098 } else {
2099 default_par->mtrr.vram_valid = 1;
2100 /* let there be speed */
2101 printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
2102 }
2103 }
2104#endif /* CONFIG_MTRR */
2105
2106 info->fbops = &riva_fb_ops;
2107 info->fix = rivafb_fix;
2108 riva_get_EDID(info, pd);
2109 riva_get_edidinfo(info);
2110
2111 ret=riva_set_fbinfo(info);
2112 if (ret < 0) {
2113 printk(KERN_ERR PFX "error setting initial video mode\n");
2114 goto err_iounmap_screen_base;
2115 }
2116
2117 fb_destroy_modedb(info->monspecs.modedb);
2118 info->monspecs.modedb = NULL;
2119 ret = register_framebuffer(info);
2120 if (ret < 0) {
2121 printk(KERN_ERR PFX
2122 "error registering riva framebuffer\n");
2123 goto err_iounmap_screen_base;
2124 }
2125
2126 pci_set_drvdata(pd, info);
2127
2128 printk(KERN_INFO PFX
2129 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
2130 info->fix.id,
2131 RIVAFB_VERSION,
2132 info->fix.smem_len / (1024 * 1024),
2133 info->fix.smem_start);
Michael Hanselmann5474c122006-06-25 05:47:08 -07002134
2135 riva_bl_init(info->par);
2136
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 NVTRACE_LEAVE();
2138 return 0;
2139
2140err_iounmap_screen_base:
2141#ifdef CONFIG_FB_RIVA_I2C
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08002142 riva_delete_i2c_busses(info->par);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143#endif
2144 iounmap(info->screen_base);
2145err_iounmap_pramin:
2146 if (default_par->riva.Architecture == NV_ARCH_03)
2147 iounmap(default_par->riva.PRAMIN);
2148err_iounmap_ctrl_base:
2149 iounmap(default_par->ctrl_base);
2150err_release_region:
2151 pci_release_regions(pd);
2152err_disable_device:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153err_free_pixmap:
2154 kfree(info->pixmap.addr);
2155err_framebuffer_release:
2156 framebuffer_release(info);
2157err_ret:
2158 return ret;
2159}
2160
2161static void __exit rivafb_remove(struct pci_dev *pd)
2162{
2163 struct fb_info *info = pci_get_drvdata(pd);
Antonino A. Daplasf4a41832006-01-09 20:53:04 -08002164 struct riva_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166 NVTRACE_ENTER();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
Michael Hanselmann5474c122006-06-25 05:47:08 -07002168 riva_bl_exit(par);
2169
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170#ifdef CONFIG_FB_RIVA_I2C
2171 riva_delete_i2c_busses(par);
2172 kfree(par->EDID);
2173#endif
2174
2175 unregister_framebuffer(info);
2176#ifdef CONFIG_MTRR
2177 if (par->mtrr.vram_valid)
2178 mtrr_del(par->mtrr.vram, info->fix.smem_start,
2179 info->fix.smem_len);
2180#endif /* CONFIG_MTRR */
2181
2182 iounmap(par->ctrl_base);
2183 iounmap(info->screen_base);
2184 if (par->riva.Architecture == NV_ARCH_03)
2185 iounmap(par->riva.PRAMIN);
2186 pci_release_regions(pd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 kfree(info->pixmap.addr);
2188 framebuffer_release(info);
2189 pci_set_drvdata(pd, NULL);
2190 NVTRACE_LEAVE();
2191}
2192
2193/* ------------------------------------------------------------------------- *
2194 *
2195 * initialization
2196 *
2197 * ------------------------------------------------------------------------- */
2198
2199#ifndef MODULE
2200static int __init rivafb_setup(char *options)
2201{
2202 char *this_opt;
2203
2204 NVTRACE_ENTER();
2205 if (!options || !*options)
2206 return 0;
2207
2208 while ((this_opt = strsep(&options, ",")) != NULL) {
2209 if (!strncmp(this_opt, "forceCRTC", 9)) {
2210 char *p;
2211
2212 p = this_opt + 9;
2213 if (!*p || !*(++p)) continue;
2214 forceCRTC = *p - '0';
2215 if (forceCRTC < 0 || forceCRTC > 1)
2216 forceCRTC = -1;
2217 } else if (!strncmp(this_opt, "flatpanel", 9)) {
2218 flatpanel = 1;
2219#ifdef CONFIG_MTRR
2220 } else if (!strncmp(this_opt, "nomtrr", 6)) {
2221 nomtrr = 1;
2222#endif
2223 } else if (!strncmp(this_opt, "strictmode", 10)) {
2224 strictmode = 1;
2225 } else if (!strncmp(this_opt, "noaccel", 7)) {
2226 noaccel = 1;
2227 } else
2228 mode_option = this_opt;
2229 }
2230 NVTRACE_LEAVE();
2231 return 0;
2232}
2233#endif /* !MODULE */
2234
2235static struct pci_driver rivafb_driver = {
2236 .name = "rivafb",
2237 .id_table = rivafb_pci_tbl,
2238 .probe = rivafb_probe,
2239 .remove = __exit_p(rivafb_remove),
2240};
2241
2242
2243
2244/* ------------------------------------------------------------------------- *
2245 *
2246 * modularization
2247 *
2248 * ------------------------------------------------------------------------- */
2249
2250static int __devinit rivafb_init(void)
2251{
2252#ifndef MODULE
2253 char *option = NULL;
2254
2255 if (fb_get_options("rivafb", &option))
2256 return -ENODEV;
2257 rivafb_setup(option);
2258#endif
2259 return pci_register_driver(&rivafb_driver);
2260}
2261
2262
2263module_init(rivafb_init);
2264
2265#ifdef MODULE
2266static void __exit rivafb_exit(void)
2267{
2268 pci_unregister_driver(&rivafb_driver);
2269}
2270
2271module_exit(rivafb_exit);
2272#endif /* MODULE */
2273
2274module_param(noaccel, bool, 0);
2275MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
2276module_param(flatpanel, int, 0);
2277MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2278module_param(forceCRTC, int, 0);
2279MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2280#ifdef CONFIG_MTRR
2281module_param(nomtrr, bool, 0);
2282MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2283#endif
2284module_param(strictmode, bool, 0);
2285MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
2286
2287MODULE_AUTHOR("Ani Joshi, maintainer");
2288MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
2289MODULE_LICENSE("GPL");