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