sync hh.org
[hh.org.git] / drivers / video / nvidia / nvidia.c
blob538e947610e19374dfa71c66d310f444262ac636
1 /*
2 * linux/drivers/video/nvidia/nvidia.c - nVidia fb driver
4 * Copyright 2004 Antonino Daplas <adaplas@pol.net>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
16 #include <linux/mm.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/fb.h>
20 #include <linux/init.h>
21 #include <linux/pci.h>
22 #include <linux/console.h>
23 #include <linux/backlight.h>
24 #ifdef CONFIG_MTRR
25 #include <asm/mtrr.h>
26 #endif
27 #ifdef CONFIG_PPC_OF
28 #include <asm/prom.h>
29 #include <asm/pci-bridge.h>
30 #endif
31 #ifdef CONFIG_BOOTX_TEXT
32 #include <asm/btext.h>
33 #endif
35 #include "nv_local.h"
36 #include "nv_type.h"
37 #include "nv_proto.h"
38 #include "nv_dma.h"
40 #undef CONFIG_FB_NVIDIA_DEBUG
41 #ifdef CONFIG_FB_NVIDIA_DEBUG
42 #define NVTRACE printk
43 #else
44 #define NVTRACE if (0) printk
45 #endif
47 #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __FUNCTION__)
48 #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __FUNCTION__)
50 #ifdef CONFIG_FB_NVIDIA_DEBUG
51 #define assert(expr) \
52 if (!(expr)) { \
53 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
54 #expr,__FILE__,__FUNCTION__,__LINE__); \
55 BUG(); \
57 #else
58 #define assert(expr)
59 #endif
61 #define PFX "nvidiafb: "
63 /* HW cursor parameters */
64 #define MAX_CURS 32
66 static struct pci_device_id nvidiafb_pci_tbl[] = {
67 {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
68 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
69 { 0, }
71 MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
73 /* command line data, set in nvidiafb_setup() */
74 static int flatpanel __devinitdata = -1; /* Autodetect later */
75 static int fpdither __devinitdata = -1;
76 static int forceCRTC __devinitdata = -1;
77 static int hwcur __devinitdata = 0;
78 static int noaccel __devinitdata = 0;
79 static int noscale __devinitdata = 0;
80 static int paneltweak __devinitdata = 0;
81 static int vram __devinitdata = 0;
82 static int bpp __devinitdata = 8;
83 #ifdef CONFIG_MTRR
84 static int nomtrr __devinitdata = 0;
85 #endif
87 static char *mode_option __devinitdata = NULL;
89 static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
90 .type = FB_TYPE_PACKED_PIXELS,
91 .xpanstep = 8,
92 .ypanstep = 1,
95 static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
96 .xres = 640,
97 .yres = 480,
98 .xres_virtual = 640,
99 .yres_virtual = 480,
100 .bits_per_pixel = 8,
101 .red = {0, 8, 0},
102 .green = {0, 8, 0},
103 .blue = {0, 8, 0},
104 .transp = {0, 0, 0},
105 .activate = FB_ACTIVATE_NOW,
106 .height = -1,
107 .width = -1,
108 .pixclock = 39721,
109 .left_margin = 40,
110 .right_margin = 24,
111 .upper_margin = 32,
112 .lower_margin = 11,
113 .hsync_len = 96,
114 .vsync_len = 2,
115 .vmode = FB_VMODE_NONINTERLACED
118 static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
119 u16 bg, u16 fg, u32 w, u32 h)
121 u32 *data = (u32 *) data8;
122 int i, j, k = 0;
123 u32 b, tmp;
125 w = (w + 1) & ~1;
127 for (i = 0; i < h; i++) {
128 b = *data++;
129 reverse_order(&b);
131 for (j = 0; j < w / 2; j++) {
132 tmp = 0;
133 #if defined (__BIG_ENDIAN)
134 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
135 b <<= 1;
136 tmp |= (b & (1 << 31)) ? fg : bg;
137 b <<= 1;
138 #else
139 tmp = (b & 1) ? fg : bg;
140 b >>= 1;
141 tmp |= (b & 1) ? fg << 16 : bg << 16;
142 b >>= 1;
143 #endif
144 NV_WR32(&par->CURSOR[k++], 0, tmp);
146 k += (MAX_CURS - w) / 2;
150 static void nvidia_write_clut(struct nvidia_par *par,
151 u8 regnum, u8 red, u8 green, u8 blue)
153 NVWriteDacMask(par, 0xff);
154 NVWriteDacWriteAddr(par, regnum);
155 NVWriteDacData(par, red);
156 NVWriteDacData(par, green);
157 NVWriteDacData(par, blue);
160 static void nvidia_read_clut(struct nvidia_par *par,
161 u8 regnum, u8 * red, u8 * green, u8 * blue)
163 NVWriteDacMask(par, 0xff);
164 NVWriteDacReadAddr(par, regnum);
165 *red = NVReadDacData(par);
166 *green = NVReadDacData(par);
167 *blue = NVReadDacData(par);
170 static int nvidia_panel_tweak(struct nvidia_par *par,
171 struct _riva_hw_state *state)
173 int tweak = 0;
175 if (par->paneltweak) {
176 tweak = par->paneltweak;
177 } else {
178 /* begin flat panel hacks */
179 /* This is unfortunate, but some chips need this register
180 tweaked or else you get artifacts where adjacent pixels are
181 swapped. There are no hard rules for what to set here so all
182 we can do is experiment and apply hacks. */
184 if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
185 /* At least one NV34 laptop needs this workaround. */
186 tweak = -1;
189 if((par->Chipset & 0xfff0) == 0x0310) {
190 tweak = 1;
192 /* end flat panel hacks */
195 return tweak;
198 static void nvidia_vga_protect(struct nvidia_par *par, int on)
200 unsigned char tmp;
202 if (on) {
204 * Turn off screen and disable sequencer.
206 tmp = NVReadSeq(par, 0x01);
208 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
209 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
210 } else {
212 * Reenable sequencer, then turn on screen.
215 tmp = NVReadSeq(par, 0x01);
217 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
218 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
222 static void nvidia_save_vga(struct nvidia_par *par,
223 struct _riva_hw_state *state)
225 int i;
227 NVTRACE_ENTER();
228 NVLockUnlock(par, 0);
230 NVUnloadStateExt(par, state);
232 state->misc_output = NVReadMiscOut(par);
234 for (i = 0; i < NUM_CRT_REGS; i++)
235 state->crtc[i] = NVReadCrtc(par, i);
237 for (i = 0; i < NUM_ATC_REGS; i++)
238 state->attr[i] = NVReadAttr(par, i);
240 for (i = 0; i < NUM_GRC_REGS; i++)
241 state->gra[i] = NVReadGr(par, i);
243 for (i = 0; i < NUM_SEQ_REGS; i++)
244 state->seq[i] = NVReadSeq(par, i);
245 NVTRACE_LEAVE();
248 #undef DUMP_REG
250 static void nvidia_write_regs(struct nvidia_par *par,
251 struct _riva_hw_state *state)
253 int i;
255 NVTRACE_ENTER();
257 NVLoadStateExt(par, state);
259 NVWriteMiscOut(par, state->misc_output);
261 for (i = 1; i < NUM_SEQ_REGS; i++) {
262 #ifdef DUMP_REG
263 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
264 #endif
265 NVWriteSeq(par, i, state->seq[i]);
268 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
269 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
271 for (i = 0; i < NUM_CRT_REGS; i++) {
272 switch (i) {
273 case 0x19:
274 case 0x20 ... 0x40:
275 break;
276 default:
277 #ifdef DUMP_REG
278 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
279 #endif
280 NVWriteCrtc(par, i, state->crtc[i]);
284 for (i = 0; i < NUM_GRC_REGS; i++) {
285 #ifdef DUMP_REG
286 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
287 #endif
288 NVWriteGr(par, i, state->gra[i]);
291 for (i = 0; i < NUM_ATC_REGS; i++) {
292 #ifdef DUMP_REG
293 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
294 #endif
295 NVWriteAttr(par, i, state->attr[i]);
298 NVTRACE_LEAVE();
301 static int nvidia_calc_regs(struct fb_info *info)
303 struct nvidia_par *par = info->par;
304 struct _riva_hw_state *state = &par->ModeReg;
305 int i, depth = fb_get_color_depth(&info->var, &info->fix);
306 int h_display = info->var.xres / 8 - 1;
307 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
308 int h_end = (info->var.xres + info->var.right_margin +
309 info->var.hsync_len) / 8 - 1;
310 int h_total = (info->var.xres + info->var.right_margin +
311 info->var.hsync_len + info->var.left_margin) / 8 - 5;
312 int h_blank_s = h_display;
313 int h_blank_e = h_total + 4;
314 int v_display = info->var.yres - 1;
315 int v_start = info->var.yres + info->var.lower_margin - 1;
316 int v_end = (info->var.yres + info->var.lower_margin +
317 info->var.vsync_len) - 1;
318 int v_total = (info->var.yres + info->var.lower_margin +
319 info->var.vsync_len + info->var.upper_margin) - 2;
320 int v_blank_s = v_display;
321 int v_blank_e = v_total + 1;
324 * Set all CRTC values.
327 if (info->var.vmode & FB_VMODE_INTERLACED)
328 v_total |= 1;
330 if (par->FlatPanel == 1) {
331 v_start = v_total - 3;
332 v_end = v_total - 2;
333 v_blank_s = v_start;
334 h_start = h_total - 5;
335 h_end = h_total - 2;
336 h_blank_e = h_total + 4;
339 state->crtc[0x0] = Set8Bits(h_total);
340 state->crtc[0x1] = Set8Bits(h_display);
341 state->crtc[0x2] = Set8Bits(h_blank_s);
342 state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
343 | SetBit(7);
344 state->crtc[0x4] = Set8Bits(h_start);
345 state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
346 | SetBitField(h_end, 4: 0, 4:0);
347 state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
348 state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
349 | SetBitField(v_display, 8: 8, 1:1)
350 | SetBitField(v_start, 8: 8, 2:2)
351 | SetBitField(v_blank_s, 8: 8, 3:3)
352 | SetBit(4)
353 | SetBitField(v_total, 9: 9, 5:5)
354 | SetBitField(v_display, 9: 9, 6:6)
355 | SetBitField(v_start, 9: 9, 7:7);
356 state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
357 | SetBit(6)
358 | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
359 state->crtc[0x10] = Set8Bits(v_start);
360 state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
361 state->crtc[0x12] = Set8Bits(v_display);
362 state->crtc[0x13] = ((info->var.xres_virtual / 8) *
363 (info->var.bits_per_pixel / 8));
364 state->crtc[0x15] = Set8Bits(v_blank_s);
365 state->crtc[0x16] = Set8Bits(v_blank_e);
367 state->attr[0x10] = 0x01;
369 if (par->Television)
370 state->attr[0x11] = 0x00;
372 state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
373 | SetBitField(v_blank_s, 10: 10, 3:3)
374 | SetBitField(v_start, 10: 10, 2:2)
375 | SetBitField(v_display, 10: 10, 1:1)
376 | SetBitField(v_total, 10: 10, 0:0);
378 state->horiz = SetBitField(h_total, 8: 8, 0:0)
379 | SetBitField(h_display, 8: 8, 1:1)
380 | SetBitField(h_blank_s, 8: 8, 2:2)
381 | SetBitField(h_start, 8: 8, 3:3);
383 state->extra = SetBitField(v_total, 11: 11, 0:0)
384 | SetBitField(v_display, 11: 11, 2:2)
385 | SetBitField(v_start, 11: 11, 4:4)
386 | SetBitField(v_blank_s, 11: 11, 6:6);
388 if (info->var.vmode & FB_VMODE_INTERLACED) {
389 h_total = (h_total >> 1) & ~1;
390 state->interlace = Set8Bits(h_total);
391 state->horiz |= SetBitField(h_total, 8: 8, 4:4);
392 } else {
393 state->interlace = 0xff; /* interlace off */
397 * Calculate the extended registers.
400 if (depth < 24)
401 i = depth;
402 else
403 i = 32;
405 if (par->Architecture >= NV_ARCH_10)
406 par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
407 par->CursorStart);
409 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
410 state->misc_output &= ~0x40;
411 else
412 state->misc_output |= 0x40;
413 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
414 state->misc_output &= ~0x80;
415 else
416 state->misc_output |= 0x80;
418 NVCalcStateExt(par, state, i, info->var.xres_virtual,
419 info->var.xres, info->var.yres_virtual,
420 1000000000 / info->var.pixclock, info->var.vmode);
422 state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
423 if (par->FlatPanel == 1) {
424 state->pixel |= (1 << 7);
426 if (!par->fpScaler || (par->fpWidth <= info->var.xres)
427 || (par->fpHeight <= info->var.yres)) {
428 state->scale |= (1 << 8);
431 if (!par->crtcSync_read) {
432 state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
433 par->crtcSync_read = 1;
436 par->PanelTweak = nvidia_panel_tweak(par, state);
439 state->vpll = state->pll;
440 state->vpll2 = state->pll;
441 state->vpllB = state->pllB;
442 state->vpll2B = state->pllB;
444 VGA_WR08(par->PCIO, 0x03D4, 0x1C);
445 state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
447 if (par->CRTCnumber) {
448 state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
449 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
450 state->crtcOwner = 3;
451 state->pllsel |= 0x20000800;
452 state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
453 if (par->twoStagePLL)
454 state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
455 } else if (par->twoHeads) {
456 state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
457 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
458 state->crtcOwner = 0;
459 state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
460 if (par->twoStagePLL)
461 state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
464 state->cursorConfig = 0x00000100;
466 if (info->var.vmode & FB_VMODE_DOUBLE)
467 state->cursorConfig |= (1 << 4);
469 if (par->alphaCursor) {
470 if ((par->Chipset & 0x0ff0) != 0x0110)
471 state->cursorConfig |= 0x04011000;
472 else
473 state->cursorConfig |= 0x14011000;
474 state->general |= (1 << 29);
475 } else
476 state->cursorConfig |= 0x02000000;
478 if (par->twoHeads) {
479 if ((par->Chipset & 0x0ff0) == 0x0110) {
480 state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
481 ~0x00010000;
482 if (par->FPDither)
483 state->dither |= 0x00010000;
484 } else {
485 state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
486 if (par->FPDither)
487 state->dither |= 1;
491 state->timingH = 0;
492 state->timingV = 0;
493 state->displayV = info->var.xres;
495 return 0;
498 static void nvidia_init_vga(struct fb_info *info)
500 struct nvidia_par *par = info->par;
501 struct _riva_hw_state *state = &par->ModeReg;
502 int i;
504 for (i = 0; i < 0x10; i++)
505 state->attr[i] = i;
506 state->attr[0x10] = 0x41;
507 state->attr[0x11] = 0xff;
508 state->attr[0x12] = 0x0f;
509 state->attr[0x13] = 0x00;
510 state->attr[0x14] = 0x00;
512 memset(state->crtc, 0x00, NUM_CRT_REGS);
513 state->crtc[0x0a] = 0x20;
514 state->crtc[0x17] = 0xe3;
515 state->crtc[0x18] = 0xff;
516 state->crtc[0x28] = 0x40;
518 memset(state->gra, 0x00, NUM_GRC_REGS);
519 state->gra[0x05] = 0x40;
520 state->gra[0x06] = 0x05;
521 state->gra[0x07] = 0x0f;
522 state->gra[0x08] = 0xff;
524 state->seq[0x00] = 0x03;
525 state->seq[0x01] = 0x01;
526 state->seq[0x02] = 0x0f;
527 state->seq[0x03] = 0x00;
528 state->seq[0x04] = 0x0e;
530 state->misc_output = 0xeb;
533 static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
535 struct nvidia_par *par = info->par;
536 u8 data[MAX_CURS * MAX_CURS / 8];
537 int i, set = cursor->set;
538 u16 fg, bg;
540 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
541 return -ENXIO;
543 NVShowHideCursor(par, 0);
545 if (par->cursor_reset) {
546 set = FB_CUR_SETALL;
547 par->cursor_reset = 0;
550 if (set & FB_CUR_SETSIZE)
551 memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
553 if (set & FB_CUR_SETPOS) {
554 u32 xx, yy, temp;
556 yy = cursor->image.dy - info->var.yoffset;
557 xx = cursor->image.dx - info->var.xoffset;
558 temp = xx & 0xFFFF;
559 temp |= yy << 16;
561 NV_WR32(par->PRAMDAC, 0x0000300, temp);
564 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
565 u32 bg_idx = cursor->image.bg_color;
566 u32 fg_idx = cursor->image.fg_color;
567 u32 s_pitch = (cursor->image.width + 7) >> 3;
568 u32 d_pitch = MAX_CURS / 8;
569 u8 *dat = (u8 *) cursor->image.data;
570 u8 *msk = (u8 *) cursor->mask;
571 u8 *src;
573 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
575 if (src) {
576 switch (cursor->rop) {
577 case ROP_XOR:
578 for (i = 0; i < s_pitch * cursor->image.height; i++)
579 src[i] = dat[i] ^ msk[i];
580 break;
581 case ROP_COPY:
582 default:
583 for (i = 0; i < s_pitch * cursor->image.height; i++)
584 src[i] = dat[i] & msk[i];
585 break;
588 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
589 cursor->image.height);
591 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
592 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
593 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
595 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
596 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
597 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
599 NVLockUnlock(par, 0);
601 nvidiafb_load_cursor_image(par, data, bg, fg,
602 cursor->image.width,
603 cursor->image.height);
604 kfree(src);
608 if (cursor->enable)
609 NVShowHideCursor(par, 1);
611 return 0;
614 static int nvidiafb_set_par(struct fb_info *info)
616 struct nvidia_par *par = info->par;
618 NVTRACE_ENTER();
620 NVLockUnlock(par, 1);
621 if (!par->FlatPanel || !par->twoHeads)
622 par->FPDither = 0;
624 if (par->FPDither < 0) {
625 if ((par->Chipset & 0x0ff0) == 0x0110)
626 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
627 & 0x00010000);
628 else
629 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
630 printk(KERN_INFO PFX "Flat panel dithering %s\n",
631 par->FPDither ? "enabled" : "disabled");
634 info->fix.visual = (info->var.bits_per_pixel == 8) ?
635 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
637 nvidia_init_vga(info);
638 nvidia_calc_regs(info);
640 NVLockUnlock(par, 0);
641 if (par->twoHeads) {
642 VGA_WR08(par->PCIO, 0x03D4, 0x44);
643 VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
644 NVLockUnlock(par, 0);
647 nvidia_vga_protect(par, 1);
649 nvidia_write_regs(par, &par->ModeReg);
650 NVSetStartAddress(par, 0);
652 #if defined (__BIG_ENDIAN)
653 /* turn on LFB swapping */
655 unsigned char tmp;
657 VGA_WR08(par->PCIO, 0x3d4, 0x46);
658 tmp = VGA_RD08(par->PCIO, 0x3d5);
659 tmp |= (1 << 7);
660 VGA_WR08(par->PCIO, 0x3d5, tmp);
662 #endif
664 info->fix.line_length = (info->var.xres_virtual *
665 info->var.bits_per_pixel) >> 3;
666 if (info->var.accel_flags) {
667 info->fbops->fb_imageblit = nvidiafb_imageblit;
668 info->fbops->fb_fillrect = nvidiafb_fillrect;
669 info->fbops->fb_copyarea = nvidiafb_copyarea;
670 info->fbops->fb_sync = nvidiafb_sync;
671 info->pixmap.scan_align = 4;
672 info->flags &= ~FBINFO_HWACCEL_DISABLED;
673 NVResetGraphics(info);
674 } else {
675 info->fbops->fb_imageblit = cfb_imageblit;
676 info->fbops->fb_fillrect = cfb_fillrect;
677 info->fbops->fb_copyarea = cfb_copyarea;
678 info->fbops->fb_sync = NULL;
679 info->pixmap.scan_align = 1;
680 info->flags |= FBINFO_HWACCEL_DISABLED;
683 par->cursor_reset = 1;
685 nvidia_vga_protect(par, 0);
687 #ifdef CONFIG_BOOTX_TEXT
688 /* Update debug text engine */
689 btext_update_display(info->fix.smem_start,
690 info->var.xres, info->var.yres,
691 info->var.bits_per_pixel, info->fix.line_length);
692 #endif
694 NVTRACE_LEAVE();
695 return 0;
698 static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
699 unsigned blue, unsigned transp,
700 struct fb_info *info)
702 struct nvidia_par *par = info->par;
703 int i;
705 NVTRACE_ENTER();
706 if (regno >= (1 << info->var.green.length))
707 return -EINVAL;
709 if (info->var.grayscale) {
710 /* gray = 0.30*R + 0.59*G + 0.11*B */
711 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
714 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
715 ((u32 *) info->pseudo_palette)[regno] =
716 (regno << info->var.red.offset) |
717 (regno << info->var.green.offset) |
718 (regno << info->var.blue.offset);
721 switch (info->var.bits_per_pixel) {
722 case 8:
723 /* "transparent" stuff is completely ignored. */
724 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
725 break;
726 case 16:
727 if (info->var.green.length == 5) {
728 for (i = 0; i < 8; i++) {
729 nvidia_write_clut(par, regno * 8 + i, red >> 8,
730 green >> 8, blue >> 8);
732 } else {
733 u8 r, g, b;
735 if (regno < 32) {
736 for (i = 0; i < 8; i++) {
737 nvidia_write_clut(par, regno * 8 + i,
738 red >> 8, green >> 8,
739 blue >> 8);
743 nvidia_read_clut(par, regno * 4, &r, &g, &b);
745 for (i = 0; i < 4; i++)
746 nvidia_write_clut(par, regno * 4 + i, r,
747 green >> 8, b);
749 break;
750 case 32:
751 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
752 break;
753 default:
754 /* do nothing */
755 break;
758 NVTRACE_LEAVE();
759 return 0;
762 static int nvidiafb_check_var(struct fb_var_screeninfo *var,
763 struct fb_info *info)
765 struct nvidia_par *par = info->par;
766 int memlen, vramlen, mode_valid = 0;
767 int pitch, err = 0;
769 NVTRACE_ENTER();
771 var->transp.offset = 0;
772 var->transp.length = 0;
774 var->xres &= ~7;
776 if (var->bits_per_pixel <= 8)
777 var->bits_per_pixel = 8;
778 else if (var->bits_per_pixel <= 16)
779 var->bits_per_pixel = 16;
780 else
781 var->bits_per_pixel = 32;
783 switch (var->bits_per_pixel) {
784 case 8:
785 var->red.offset = 0;
786 var->red.length = 8;
787 var->green.offset = 0;
788 var->green.length = 8;
789 var->blue.offset = 0;
790 var->blue.length = 8;
791 var->transp.offset = 0;
792 var->transp.length = 0;
793 break;
794 case 16:
795 var->green.length = (var->green.length < 6) ? 5 : 6;
796 var->red.length = 5;
797 var->blue.length = 5;
798 var->transp.length = 6 - var->green.length;
799 var->blue.offset = 0;
800 var->green.offset = 5;
801 var->red.offset = 5 + var->green.length;
802 var->transp.offset = (5 + var->red.offset) & 15;
803 break;
804 case 32: /* RGBA 8888 */
805 var->red.offset = 16;
806 var->red.length = 8;
807 var->green.offset = 8;
808 var->green.length = 8;
809 var->blue.offset = 0;
810 var->blue.length = 8;
811 var->transp.length = 8;
812 var->transp.offset = 24;
813 break;
816 var->red.msb_right = 0;
817 var->green.msb_right = 0;
818 var->blue.msb_right = 0;
819 var->transp.msb_right = 0;
821 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
822 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
823 mode_valid = 1;
825 /* calculate modeline if supported by monitor */
826 if (!mode_valid && info->monspecs.gtf) {
827 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
828 mode_valid = 1;
831 if (!mode_valid) {
832 struct fb_videomode *mode;
834 mode = fb_find_best_mode(var, &info->modelist);
835 if (mode) {
836 fb_videomode_to_var(var, mode);
837 mode_valid = 1;
841 if (!mode_valid && info->monspecs.modedb_len)
842 return -EINVAL;
844 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
845 par->fpHeight < var->yres))
846 return -EINVAL;
848 if (var->yres_virtual < var->yres)
849 var->yres_virtual = var->yres;
851 if (var->xres_virtual < var->xres)
852 var->xres_virtual = var->xres;
854 var->xres_virtual = (var->xres_virtual + 63) & ~63;
856 vramlen = info->screen_size;
857 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
858 memlen = pitch * var->yres_virtual;
860 if (memlen > vramlen) {
861 var->yres_virtual = vramlen / pitch;
863 if (var->yres_virtual < var->yres) {
864 var->yres_virtual = var->yres;
865 var->xres_virtual = vramlen / var->yres_virtual;
866 var->xres_virtual /= var->bits_per_pixel / 8;
867 var->xres_virtual &= ~63;
868 pitch = (var->xres_virtual *
869 var->bits_per_pixel + 7) / 8;
870 memlen = pitch * var->yres;
872 if (var->xres_virtual < var->xres) {
873 printk("nvidiafb: required video memory, "
874 "%d bytes, for %dx%d-%d (virtual) "
875 "is out of range\n",
876 memlen, var->xres_virtual,
877 var->yres_virtual, var->bits_per_pixel);
878 err = -ENOMEM;
883 if (var->accel_flags) {
884 if (var->yres_virtual > 0x7fff)
885 var->yres_virtual = 0x7fff;
886 if (var->xres_virtual > 0x7fff)
887 var->xres_virtual = 0x7fff;
890 var->xres_virtual &= ~63;
892 NVTRACE_LEAVE();
894 return err;
897 static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
898 struct fb_info *info)
900 struct nvidia_par *par = info->par;
901 u32 total;
903 total = var->yoffset * info->fix.line_length + var->xoffset;
905 NVSetStartAddress(par, total);
907 return 0;
910 static int nvidiafb_blank(int blank, struct fb_info *info)
912 struct nvidia_par *par = info->par;
913 unsigned char tmp, vesa;
915 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
916 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
918 NVTRACE_ENTER();
920 if (blank)
921 tmp |= 0x20;
923 switch (blank) {
924 case FB_BLANK_UNBLANK:
925 case FB_BLANK_NORMAL:
926 break;
927 case FB_BLANK_VSYNC_SUSPEND:
928 vesa |= 0x80;
929 break;
930 case FB_BLANK_HSYNC_SUSPEND:
931 vesa |= 0x40;
932 break;
933 case FB_BLANK_POWERDOWN:
934 vesa |= 0xc0;
935 break;
938 NVWriteSeq(par, 0x01, tmp);
939 NVWriteCrtc(par, 0x1a, vesa);
941 nvidia_bl_set_power(info, blank);
943 NVTRACE_LEAVE();
945 return 0;
948 static struct fb_ops nvidia_fb_ops = {
949 .owner = THIS_MODULE,
950 .fb_check_var = nvidiafb_check_var,
951 .fb_set_par = nvidiafb_set_par,
952 .fb_setcolreg = nvidiafb_setcolreg,
953 .fb_pan_display = nvidiafb_pan_display,
954 .fb_blank = nvidiafb_blank,
955 .fb_fillrect = nvidiafb_fillrect,
956 .fb_copyarea = nvidiafb_copyarea,
957 .fb_imageblit = nvidiafb_imageblit,
958 .fb_cursor = nvidiafb_cursor,
959 .fb_sync = nvidiafb_sync,
962 #ifdef CONFIG_PM
963 static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
965 struct fb_info *info = pci_get_drvdata(dev);
966 struct nvidia_par *par = info->par;
968 if (mesg.event == PM_EVENT_PRETHAW)
969 mesg.event = PM_EVENT_FREEZE;
970 acquire_console_sem();
971 par->pm_state = mesg.event;
973 if (mesg.event == PM_EVENT_SUSPEND) {
974 fb_set_suspend(info, 1);
975 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
976 nvidia_write_regs(par, &par->SavedReg);
977 pci_save_state(dev);
978 pci_disable_device(dev);
979 pci_set_power_state(dev, pci_choose_state(dev, mesg));
981 dev->dev.power.power_state = mesg;
983 release_console_sem();
984 return 0;
987 static int nvidiafb_resume(struct pci_dev *dev)
989 struct fb_info *info = pci_get_drvdata(dev);
990 struct nvidia_par *par = info->par;
992 acquire_console_sem();
993 pci_set_power_state(dev, PCI_D0);
995 if (par->pm_state != PM_EVENT_FREEZE) {
996 pci_restore_state(dev);
998 if (pci_enable_device(dev))
999 goto fail;
1001 pci_set_master(dev);
1004 par->pm_state = PM_EVENT_ON;
1005 nvidiafb_set_par(info);
1006 fb_set_suspend (info, 0);
1007 nvidiafb_blank(FB_BLANK_UNBLANK, info);
1009 fail:
1010 release_console_sem();
1011 return 0;
1013 #else
1014 #define nvidiafb_suspend NULL
1015 #define nvidiafb_resume NULL
1016 #endif
1018 static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1020 struct fb_monspecs *specs = &info->monspecs;
1021 struct fb_videomode modedb;
1022 struct nvidia_par *par = info->par;
1023 int lpitch;
1025 NVTRACE_ENTER();
1026 info->flags = FBINFO_DEFAULT
1027 | FBINFO_HWACCEL_IMAGEBLIT
1028 | FBINFO_HWACCEL_FILLRECT
1029 | FBINFO_HWACCEL_COPYAREA
1030 | FBINFO_HWACCEL_YPAN;
1032 fb_videomode_to_modelist(info->monspecs.modedb,
1033 info->monspecs.modedb_len, &info->modelist);
1034 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1036 switch (bpp) {
1037 case 0 ... 8:
1038 bpp = 8;
1039 break;
1040 case 9 ... 16:
1041 bpp = 16;
1042 break;
1043 default:
1044 bpp = 32;
1045 break;
1048 if (specs->modedb != NULL) {
1049 struct fb_videomode *modedb;
1051 modedb = fb_find_best_display(specs, &info->modelist);
1052 fb_videomode_to_var(&nvidiafb_default_var, modedb);
1053 nvidiafb_default_var.bits_per_pixel = bpp;
1054 } else if (par->fpWidth && par->fpHeight) {
1055 char buf[16];
1057 memset(buf, 0, 16);
1058 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
1059 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1060 specs->modedb_len, &modedb, bpp);
1063 if (mode_option)
1064 fb_find_mode(&nvidiafb_default_var, info, mode_option,
1065 specs->modedb, specs->modedb_len, &modedb, bpp);
1067 info->var = nvidiafb_default_var;
1068 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1069 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1070 info->pseudo_palette = par->pseudo_palette;
1071 fb_alloc_cmap(&info->cmap, 256, 0);
1072 fb_destroy_modedb(info->monspecs.modedb);
1073 info->monspecs.modedb = NULL;
1075 /* maximize virtual vertical length */
1076 lpitch = info->var.xres_virtual *
1077 ((info->var.bits_per_pixel + 7) >> 3);
1078 info->var.yres_virtual = info->screen_size / lpitch;
1080 info->pixmap.scan_align = 4;
1081 info->pixmap.buf_align = 4;
1082 info->pixmap.access_align = 32;
1083 info->pixmap.size = 8 * 1024;
1084 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1086 if (!hwcur)
1087 info->fbops->fb_cursor = NULL;
1089 info->var.accel_flags = (!noaccel);
1091 switch (par->Architecture) {
1092 case NV_ARCH_04:
1093 info->fix.accel = FB_ACCEL_NV4;
1094 break;
1095 case NV_ARCH_10:
1096 info->fix.accel = FB_ACCEL_NV_10;
1097 break;
1098 case NV_ARCH_20:
1099 info->fix.accel = FB_ACCEL_NV_20;
1100 break;
1101 case NV_ARCH_30:
1102 info->fix.accel = FB_ACCEL_NV_30;
1103 break;
1104 case NV_ARCH_40:
1105 info->fix.accel = FB_ACCEL_NV_40;
1106 break;
1109 NVTRACE_LEAVE();
1111 return nvidiafb_check_var(&info->var, info);
1114 static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1116 struct nvidia_par *par = info->par;
1117 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1119 printk(KERN_INFO PFX "Device ID: %x \n", id);
1121 if ((id & 0xfff0) == 0x00f0) {
1122 /* pci-e */
1123 id = NV_RD32(par->REGS, 0x1800);
1125 if ((id & 0x0000ffff) == 0x000010DE)
1126 id = 0x10DE0000 | (id >> 16);
1127 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1128 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1129 ((id >> 8) & 0x000000ff);
1130 printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
1133 return id;
1136 static u32 __devinit nvidia_get_arch(struct fb_info *info)
1138 struct nvidia_par *par = info->par;
1139 u32 arch = 0;
1141 switch (par->Chipset & 0x0ff0) {
1142 case 0x0100: /* GeForce 256 */
1143 case 0x0110: /* GeForce2 MX */
1144 case 0x0150: /* GeForce2 */
1145 case 0x0170: /* GeForce4 MX */
1146 case 0x0180: /* GeForce4 MX (8x AGP) */
1147 case 0x01A0: /* nForce */
1148 case 0x01F0: /* nForce2 */
1149 arch = NV_ARCH_10;
1150 break;
1151 case 0x0200: /* GeForce3 */
1152 case 0x0250: /* GeForce4 Ti */
1153 case 0x0280: /* GeForce4 Ti (8x AGP) */
1154 arch = NV_ARCH_20;
1155 break;
1156 case 0x0300: /* GeForceFX 5800 */
1157 case 0x0310: /* GeForceFX 5600 */
1158 case 0x0320: /* GeForceFX 5200 */
1159 case 0x0330: /* GeForceFX 5900 */
1160 case 0x0340: /* GeForceFX 5700 */
1161 arch = NV_ARCH_30;
1162 break;
1163 case 0x0040: /* GeForce 6800 */
1164 case 0x00C0: /* GeForce 6800 */
1165 case 0x0120: /* GeForce 6800 */
1166 case 0x0130:
1167 case 0x0140: /* GeForce 6600 */
1168 case 0x0160: /* GeForce 6200 */
1169 case 0x01D0: /* GeForce 7200, 7300, 7400 */
1170 case 0x0090: /* GeForce 7800 */
1171 case 0x0210: /* GeForce 6800 */
1172 case 0x0220: /* GeForce 6200 */
1173 case 0x0230:
1174 case 0x0240: /* GeForce 6100 */
1175 case 0x0290: /* GeForce 7900 */
1176 case 0x0390: /* GeForce 7600 */
1177 arch = NV_ARCH_40;
1178 break;
1179 case 0x0020: /* TNT, TNT2 */
1180 arch = NV_ARCH_04;
1181 break;
1182 default: /* unknown architecture */
1183 break;
1186 return arch;
1189 static int __devinit nvidiafb_probe(struct pci_dev *pd,
1190 const struct pci_device_id *ent)
1192 struct nvidia_par *par;
1193 struct fb_info *info;
1194 unsigned short cmd;
1197 NVTRACE_ENTER();
1198 assert(pd != NULL);
1200 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1202 if (!info)
1203 goto err_out;
1205 par = info->par;
1206 par->pci_dev = pd;
1208 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1210 if (info->pixmap.addr == NULL)
1211 goto err_out_kfree;
1213 memset(info->pixmap.addr, 0, 8 * 1024);
1215 if (pci_enable_device(pd)) {
1216 printk(KERN_ERR PFX "cannot enable PCI device\n");
1217 goto err_out_enable;
1220 if (pci_request_regions(pd, "nvidiafb")) {
1221 printk(KERN_ERR PFX "cannot request PCI regions\n");
1222 goto err_out_enable;
1225 par->FlatPanel = flatpanel;
1226 if (flatpanel == 1)
1227 printk(KERN_INFO PFX "flatpanel support enabled\n");
1228 par->FPDither = fpdither;
1230 par->CRTCnumber = forceCRTC;
1231 par->FpScale = (!noscale);
1232 par->paneltweak = paneltweak;
1234 /* enable IO and mem if not already done */
1235 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1236 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1237 pci_write_config_word(pd, PCI_COMMAND, cmd);
1239 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1240 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1241 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1243 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1245 if (!par->REGS) {
1246 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1247 goto err_out_free_base0;
1250 par->Chipset = nvidia_get_chipset(info);
1251 par->Architecture = nvidia_get_arch(info);
1253 if (par->Architecture == 0) {
1254 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1255 goto err_out_arch;
1258 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1260 if (NVCommonSetup(info))
1261 goto err_out_arch;
1263 par->FbAddress = nvidiafb_fix.smem_start;
1264 par->FbMapSize = par->RamAmountKBytes * 1024;
1265 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1266 par->FbMapSize = vram * 1024 * 1024;
1268 /* Limit amount of vram to 64 MB */
1269 if (par->FbMapSize > 64 * 1024 * 1024)
1270 par->FbMapSize = 64 * 1024 * 1024;
1272 if(par->Architecture >= NV_ARCH_40)
1273 par->FbUsableSize = par->FbMapSize - (560 * 1024);
1274 else
1275 par->FbUsableSize = par->FbMapSize - (128 * 1024);
1276 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1277 16 * 1024;
1278 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
1279 par->CursorStart = par->FbUsableSize + (32 * 1024);
1281 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
1282 info->screen_size = par->FbUsableSize;
1283 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
1285 if (!info->screen_base) {
1286 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1287 goto err_out_free_base1;
1290 par->FbStart = info->screen_base;
1292 #ifdef CONFIG_MTRR
1293 if (!nomtrr) {
1294 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
1295 par->RamAmountKBytes * 1024,
1296 MTRR_TYPE_WRCOMB, 1);
1297 if (par->mtrr.vram < 0) {
1298 printk(KERN_ERR PFX "unable to setup MTRR\n");
1299 } else {
1300 par->mtrr.vram_valid = 1;
1301 /* let there be speed */
1302 printk(KERN_INFO PFX "MTRR set to ON\n");
1305 #endif /* CONFIG_MTRR */
1307 info->fbops = &nvidia_fb_ops;
1308 info->fix = nvidiafb_fix;
1310 if (nvidia_set_fbinfo(info) < 0) {
1311 printk(KERN_ERR PFX "error setting initial video mode\n");
1312 goto err_out_iounmap_fb;
1315 nvidia_save_vga(par, &par->SavedReg);
1317 pci_set_drvdata(pd, info);
1318 nvidia_bl_init(par);
1319 if (register_framebuffer(info) < 0) {
1320 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1321 goto err_out_iounmap_fb;
1325 printk(KERN_INFO PFX
1326 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1327 info->fix.id,
1328 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1330 NVTRACE_LEAVE();
1331 return 0;
1333 err_out_iounmap_fb:
1334 iounmap(info->screen_base);
1335 err_out_free_base1:
1336 fb_destroy_modedb(info->monspecs.modedb);
1337 nvidia_delete_i2c_busses(par);
1338 err_out_arch:
1339 iounmap(par->REGS);
1340 err_out_free_base0:
1341 pci_release_regions(pd);
1342 err_out_enable:
1343 kfree(info->pixmap.addr);
1344 err_out_kfree:
1345 framebuffer_release(info);
1346 err_out:
1347 return -ENODEV;
1350 static void __exit nvidiafb_remove(struct pci_dev *pd)
1352 struct fb_info *info = pci_get_drvdata(pd);
1353 struct nvidia_par *par = info->par;
1355 NVTRACE_ENTER();
1357 nvidia_bl_exit(par);
1359 unregister_framebuffer(info);
1360 #ifdef CONFIG_MTRR
1361 if (par->mtrr.vram_valid)
1362 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1363 info->fix.smem_len);
1364 #endif /* CONFIG_MTRR */
1366 iounmap(info->screen_base);
1367 fb_destroy_modedb(info->monspecs.modedb);
1368 nvidia_delete_i2c_busses(par);
1369 iounmap(par->REGS);
1370 pci_release_regions(pd);
1371 kfree(info->pixmap.addr);
1372 framebuffer_release(info);
1373 pci_set_drvdata(pd, NULL);
1374 NVTRACE_LEAVE();
1377 /* ------------------------------------------------------------------------- *
1379 * initialization
1381 * ------------------------------------------------------------------------- */
1383 #ifndef MODULE
1384 static int __devinit nvidiafb_setup(char *options)
1386 char *this_opt;
1388 NVTRACE_ENTER();
1389 if (!options || !*options)
1390 return 0;
1392 while ((this_opt = strsep(&options, ",")) != NULL) {
1393 if (!strncmp(this_opt, "forceCRTC", 9)) {
1394 char *p;
1396 p = this_opt + 9;
1397 if (!*p || !*(++p))
1398 continue;
1399 forceCRTC = *p - '0';
1400 if (forceCRTC < 0 || forceCRTC > 1)
1401 forceCRTC = -1;
1402 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1403 flatpanel = 1;
1404 } else if (!strncmp(this_opt, "hwcur", 5)) {
1405 hwcur = 1;
1406 } else if (!strncmp(this_opt, "noaccel", 6)) {
1407 noaccel = 1;
1408 } else if (!strncmp(this_opt, "noscale", 7)) {
1409 noscale = 1;
1410 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1411 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
1412 } else if (!strncmp(this_opt, "vram:", 5)) {
1413 vram = simple_strtoul(this_opt+5, NULL, 0);
1414 #ifdef CONFIG_MTRR
1415 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1416 nomtrr = 1;
1417 #endif
1418 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1419 fpdither = simple_strtol(this_opt+9, NULL, 0);
1420 } else if (!strncmp(this_opt, "bpp:", 4)) {
1421 bpp = simple_strtoul(this_opt+4, NULL, 0);
1422 } else
1423 mode_option = this_opt;
1425 NVTRACE_LEAVE();
1426 return 0;
1428 #endif /* !MODULE */
1430 static struct pci_driver nvidiafb_driver = {
1431 .name = "nvidiafb",
1432 .id_table = nvidiafb_pci_tbl,
1433 .probe = nvidiafb_probe,
1434 .suspend = nvidiafb_suspend,
1435 .resume = nvidiafb_resume,
1436 .remove = __exit_p(nvidiafb_remove),
1439 /* ------------------------------------------------------------------------- *
1441 * modularization
1443 * ------------------------------------------------------------------------- */
1445 static int __devinit nvidiafb_init(void)
1447 #ifndef MODULE
1448 char *option = NULL;
1450 if (fb_get_options("nvidiafb", &option))
1451 return -ENODEV;
1452 nvidiafb_setup(option);
1453 #endif
1454 return pci_register_driver(&nvidiafb_driver);
1457 module_init(nvidiafb_init);
1459 #ifdef MODULE
1460 static void __exit nvidiafb_exit(void)
1462 pci_unregister_driver(&nvidiafb_driver);
1465 module_exit(nvidiafb_exit);
1467 module_param(flatpanel, int, 0);
1468 MODULE_PARM_DESC(flatpanel,
1469 "Enables experimental flat panel support for some chipsets. "
1470 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1471 module_param(fpdither, int, 0);
1472 MODULE_PARM_DESC(fpdither,
1473 "Enables dithering of flat panel for 6 bits panels. "
1474 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1475 module_param(hwcur, int, 0);
1476 MODULE_PARM_DESC(hwcur,
1477 "Enables hardware cursor implementation. (0 or 1=enabled) "
1478 "(default=0)");
1479 module_param(noaccel, int, 0);
1480 MODULE_PARM_DESC(noaccel,
1481 "Disables hardware acceleration. (0 or 1=disable) "
1482 "(default=0)");
1483 module_param(noscale, int, 0);
1484 MODULE_PARM_DESC(noscale,
1485 "Disables screen scaleing. (0 or 1=disable) "
1486 "(default=0, do scaling)");
1487 module_param(paneltweak, int, 0);
1488 MODULE_PARM_DESC(paneltweak,
1489 "Tweak display settings for flatpanels. "
1490 "(default=0, no tweaks)");
1491 module_param(forceCRTC, int, 0);
1492 MODULE_PARM_DESC(forceCRTC,
1493 "Forces usage of a particular CRTC in case autodetection "
1494 "fails. (0 or 1) (default=autodetect)");
1495 module_param(vram, int, 0);
1496 MODULE_PARM_DESC(vram,
1497 "amount of framebuffer memory to remap in MiB"
1498 "(default=0 - remap entire memory)");
1499 module_param(mode_option, charp, 0);
1500 MODULE_PARM_DESC(mode_option, "Specify initial video mode");
1501 module_param(bpp, int, 0);
1502 MODULE_PARM_DESC(bpp, "pixel width in bits"
1503 "(default=8)");
1504 #ifdef CONFIG_MTRR
1505 module_param(nomtrr, bool, 0);
1506 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1507 "(default=0)");
1508 #endif
1510 MODULE_AUTHOR("Antonino Daplas");
1511 MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1512 MODULE_LICENSE("GPL");
1513 #endif /* MODULE */