backlight: Fix nvidia backlight initial brightness
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / video / nvidia / nvidia.c
CommitLineData
1da177e4
LT
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
1da177e4
LT
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>
1da177e4
LT
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>
7a07cd78 22#include <linux/console.h>
5474c120 23#include <linux/backlight.h>
1da177e4
LT
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
70abac6e
PM
31#ifdef CONFIG_BOOTX_TEXT
32#include <asm/btext.h>
33#endif
1da177e4
LT
34
35#include "nv_local.h"
36#include "nv_type.h"
37#include "nv_proto.h"
38#include "nv_dma.h"
39
1da177e4
LT
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
46
47#define NVTRACE_ENTER(...) NVTRACE("%s START\n", __FUNCTION__)
48#define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __FUNCTION__)
49
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(); \
56 }
57#else
58#define assert(expr)
59#endif
60
61#define PFX "nvidiafb: "
62
63/* HW cursor parameters */
64#define MAX_CURS 32
65
66static struct pci_device_id nvidiafb_pci_tbl[] = {
8eec4981
AD
67 {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
68 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
69 { 0, }
1da177e4 70};
1da177e4
LT
71MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
72
73/* command line data, set in nvidiafb_setup() */
74static int flatpanel __devinitdata = -1; /* Autodetect later */
b8c49ef6 75static int fpdither __devinitdata = -1;
1da177e4
LT
76static int forceCRTC __devinitdata = -1;
77static int hwcur __devinitdata = 0;
78static int noaccel __devinitdata = 0;
79static int noscale __devinitdata = 0;
80static int paneltweak __devinitdata = 0;
917bb077 81static int vram __devinitdata = 0;
ade9185a 82static int bpp __devinitdata = 8;
1da177e4
LT
83#ifdef CONFIG_MTRR
84static int nomtrr __devinitdata = 0;
85#endif
86
87static char *mode_option __devinitdata = NULL;
88
89static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
90 .type = FB_TYPE_PACKED_PIXELS,
91 .xpanstep = 8,
92 .ypanstep = 1,
93};
94
95static 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
116};
117
1da177e4
LT
118static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
119 u16 bg, u16 fg, u32 w, u32 h)
120{
f1ab5dac 121 u32 *data = (u32 *) data8;
1da177e4
LT
122 int i, j, k = 0;
123 u32 b, tmp;
1da177e4
LT
124
125 w = (w + 1) & ~1;
126
127 for (i = 0; i < h; i++) {
128 b = *data++;
129 reverse_order(&b);
130
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);
145 }
146 k += (MAX_CURS - w) / 2;
147 }
148}
149
150static void nvidia_write_clut(struct nvidia_par *par,
151 u8 regnum, u8 red, u8 green, u8 blue)
152{
153 NVWriteDacMask(par, 0xff);
154 NVWriteDacWriteAddr(par, regnum);
155 NVWriteDacData(par, red);
156 NVWriteDacData(par, green);
157 NVWriteDacData(par, blue);
158}
159
160static void nvidia_read_clut(struct nvidia_par *par,
161 u8 regnum, u8 * red, u8 * green, u8 * blue)
162{
163 NVWriteDacMask(par, 0xff);
164 NVWriteDacReadAddr(par, regnum);
165 *red = NVReadDacData(par);
166 *green = NVReadDacData(par);
167 *blue = NVReadDacData(par);
168}
169
170static int nvidia_panel_tweak(struct nvidia_par *par,
171 struct _riva_hw_state *state)
172{
173 int tweak = 0;
174
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. */
183
184 if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
185 /* At least one NV34 laptop needs this workaround. */
186 tweak = -1;
187 }
188
189 if((par->Chipset & 0xfff0) == 0x0310) {
190 tweak = 1;
191 }
192 /* end flat panel hacks */
193 }
194
195 return tweak;
196}
197
7a07cd78
AD
198static void nvidia_vga_protect(struct nvidia_par *par, int on)
199{
200 unsigned char tmp;
201
202 if (on) {
203 /*
204 * Turn off screen and disable sequencer.
205 */
206 tmp = NVReadSeq(par, 0x01);
207
208 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
209 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
210 } else {
211 /*
212 * Reenable sequencer, then turn on screen.
213 */
214
215 tmp = NVReadSeq(par, 0x01);
216
217 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
218 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
219 }
220}
221
1da177e4
LT
222static void nvidia_save_vga(struct nvidia_par *par,
223 struct _riva_hw_state *state)
224{
225 int i;
226
227 NVTRACE_ENTER();
228 NVLockUnlock(par, 0);
229
230 NVUnloadStateExt(par, state);
231
232 state->misc_output = NVReadMiscOut(par);
233
234 for (i = 0; i < NUM_CRT_REGS; i++)
235 state->crtc[i] = NVReadCrtc(par, i);
236
237 for (i = 0; i < NUM_ATC_REGS; i++)
238 state->attr[i] = NVReadAttr(par, i);
239
240 for (i = 0; i < NUM_GRC_REGS; i++)
241 state->gra[i] = NVReadGr(par, i);
242
243 for (i = 0; i < NUM_SEQ_REGS; i++)
244 state->seq[i] = NVReadSeq(par, i);
245 NVTRACE_LEAVE();
246}
247
85f1503a
BH
248#undef DUMP_REG
249
7a07cd78
AD
250static void nvidia_write_regs(struct nvidia_par *par,
251 struct _riva_hw_state *state)
1da177e4 252{
1da177e4
LT
253 int i;
254
255 NVTRACE_ENTER();
1da177e4
LT
256
257 NVLoadStateExt(par, state);
258
259 NVWriteMiscOut(par, state->misc_output);
260
85f1503a
BH
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]);
266 }
267
268 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
269 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
270
1da177e4
LT
271 for (i = 0; i < NUM_CRT_REGS; i++) {
272 switch (i) {
273 case 0x19:
274 case 0x20 ... 0x40:
275 break;
276 default:
85f1503a
BH
277#ifdef DUMP_REG
278 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
279#endif
1da177e4
LT
280 NVWriteCrtc(par, i, state->crtc[i]);
281 }
282 }
283
85f1503a
BH
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
1da177e4 288 NVWriteGr(par, i, state->gra[i]);
85f1503a
BH
289 }
290
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]);
296 }
1da177e4 297
1da177e4
LT
298 NVTRACE_LEAVE();
299}
300
301static int nvidia_calc_regs(struct fb_info *info)
302{
303 struct nvidia_par *par = info->par;
304 struct _riva_hw_state *state = &par->ModeReg;
b8c90945 305 int i, depth = fb_get_color_depth(&info->var, &info->fix);
1da177e4
LT
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;
322
323 /*
324 * Set all CRTC values.
325 */
326
327 if (info->var.vmode & FB_VMODE_INTERLACED)
328 v_total |= 1;
329
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;
337 }
338
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);
366
367 state->attr[0x10] = 0x01;
368
369 if (par->Television)
370 state->attr[0x11] = 0x00;
371
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);
377
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);
382
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);
387
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 */
394 }
395
396 /*
397 * Calculate the extended registers.
398 */
399
400 if (depth < 24)
401 i = depth;
402 else
403 i = 32;
404
405 if (par->Architecture >= NV_ARCH_10)
406 par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
407 par->CursorStart);
408
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;
417
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);
421
422 state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
423 if (par->FlatPanel == 1) {
424 state->pixel |= (1 << 7);
425
426 if (!par->fpScaler || (par->fpWidth <= info->var.xres)
427 || (par->fpHeight <= info->var.yres)) {
428 state->scale |= (1 << 8);
429 }
430
431 if (!par->crtcSync_read) {
432 state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
433 par->crtcSync_read = 1;
434 }
435
436 par->PanelTweak = nvidia_panel_tweak(par, state);
437 }
438
439 state->vpll = state->pll;
440 state->vpll2 = state->pll;
441 state->vpllB = state->pllB;
442 state->vpll2B = state->pllB;
443
444 VGA_WR08(par->PCIO, 0x03D4, 0x1C);
445 state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
446
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);
462 }
463
464 state->cursorConfig = 0x00000100;
465
466 if (info->var.vmode & FB_VMODE_DOUBLE)
467 state->cursorConfig |= (1 << 4);
468
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;
477
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;
488 }
489 }
490
491 state->timingH = 0;
492 state->timingV = 0;
493 state->displayV = info->var.xres;
494
495 return 0;
496}
497
498static void nvidia_init_vga(struct fb_info *info)
499{
500 struct nvidia_par *par = info->par;
501 struct _riva_hw_state *state = &par->ModeReg;
502 int i;
503
504 for (i = 0; i < 0x10; i++)
505 state->attr[i] = i;
506 state->attr[0x10] = 0x41;
85f1503a 507 state->attr[0x11] = 0xff;
1da177e4
LT
508 state->attr[0x12] = 0x0f;
509 state->attr[0x13] = 0x00;
510 state->attr[0x14] = 0x00;
511
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;
517
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;
523
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;
529
530 state->misc_output = 0xeb;
531}
532
533static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
534{
535 struct nvidia_par *par = info->par;
536 u8 data[MAX_CURS * MAX_CURS / 8];
1da177e4 537 int i, set = cursor->set;
f1ab5dac 538 u16 fg, bg;
1da177e4 539
7a482425 540 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
f1ab5dac 541 return -ENXIO;
1da177e4
LT
542
543 NVShowHideCursor(par, 0);
544
545 if (par->cursor_reset) {
546 set = FB_CUR_SETALL;
547 par->cursor_reset = 0;
548 }
549
550 if (set & FB_CUR_SETSIZE)
551 memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
552
553 if (set & FB_CUR_SETPOS) {
554 u32 xx, yy, temp;
555
556 yy = cursor->image.dy - info->var.yoffset;
557 xx = cursor->image.dx - info->var.xoffset;
558 temp = xx & 0xFFFF;
559 temp |= yy << 16;
560
561 NV_WR32(par->PRAMDAC, 0x0000300, temp);
562 }
563
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;
572
573 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
574
575 if (src) {
576 switch (cursor->rop) {
577 case ROP_XOR:
f1ab5dac 578 for (i = 0; i < s_pitch * cursor->image.height; i++)
1da177e4
LT
579 src[i] = dat[i] ^ msk[i];
580 break;
581 case ROP_COPY:
582 default:
f1ab5dac 583 for (i = 0; i < s_pitch * cursor->image.height; i++)
1da177e4
LT
584 src[i] = dat[i] & msk[i];
585 break;
586 }
587
f1ab5dac
JS
588 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
589 cursor->image.height);
1da177e4
LT
590
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;
594
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;
598
599 NVLockUnlock(par, 0);
600
601 nvidiafb_load_cursor_image(par, data, bg, fg,
602 cursor->image.width,
603 cursor->image.height);
604 kfree(src);
605 }
606 }
607
608 if (cursor->enable)
609 NVShowHideCursor(par, 1);
610
611 return 0;
612}
613
614static int nvidiafb_set_par(struct fb_info *info)
615{
616 struct nvidia_par *par = info->par;
617
618 NVTRACE_ENTER();
619
620 NVLockUnlock(par, 1);
b8c49ef6 621 if (!par->FlatPanel || !par->twoHeads)
1da177e4
LT
622 par->FPDither = 0;
623
b8c49ef6
BH
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");
632 }
633
b8c90945
AD
634 info->fix.visual = (info->var.bits_per_pixel == 8) ?
635 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
636
1da177e4
LT
637 nvidia_init_vga(info);
638 nvidia_calc_regs(info);
1da177e4
LT
639
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);
645 }
646
85f1503a
BH
647 nvidia_vga_protect(par, 1);
648
7a07cd78
AD
649 nvidia_write_regs(par, &par->ModeReg);
650 NVSetStartAddress(par, 0);
85f1503a
BH
651
652#if defined (__BIG_ENDIAN)
653 /* turn on LFB swapping */
654 {
655 unsigned char tmp;
656
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);
661 }
662#endif
663
1da177e4
LT
664 info->fix.line_length = (info->var.xres_virtual *
665 info->var.bits_per_pixel) >> 3;
1da177e4
LT
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;
681 }
682
683 par->cursor_reset = 1;
684
85f1503a 685 nvidia_vga_protect(par, 0);
1da177e4 686
70abac6e
PM
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
693
1da177e4
LT
694 NVTRACE_LEAVE();
695 return 0;
696}
697
698static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
699 unsigned blue, unsigned transp,
700 struct fb_info *info)
701{
702 struct nvidia_par *par = info->par;
703 int i;
704
705 NVTRACE_ENTER();
706 if (regno >= (1 << info->var.green.length))
707 return -EINVAL;
708
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;
712 }
713
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);
719 }
720
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);
731 }
732 } else {
733 u8 r, g, b;
734
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);
740 }
741 }
742
743 nvidia_read_clut(par, regno * 4, &r, &g, &b);
744
745 for (i = 0; i < 4; i++)
746 nvidia_write_clut(par, regno * 4 + i, r,
747 green >> 8, b);
748 }
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;
756 }
757
758 NVTRACE_LEAVE();
759 return 0;
760}
761
762static int nvidiafb_check_var(struct fb_var_screeninfo *var,
763 struct fb_info *info)
764{
765 struct nvidia_par *par = info->par;
766 int memlen, vramlen, mode_valid = 0;
767 int pitch, err = 0;
768
769 NVTRACE_ENTER();
770
771 var->transp.offset = 0;
772 var->transp.length = 0;
773
774 var->xres &= ~7;
775
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;
782
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;
814 }
815
816 var->red.msb_right = 0;
817 var->green.msb_right = 0;
818 var->blue.msb_right = 0;
819 var->transp.msb_right = 0;
820
821 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
822 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
823 mode_valid = 1;
824
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;
829 }
830
831 if (!mode_valid) {
9791d763 832 const struct fb_videomode *mode;
1da177e4
LT
833
834 mode = fb_find_best_mode(var, &info->modelist);
835 if (mode) {
836 fb_videomode_to_var(var, mode);
837 mode_valid = 1;
838 }
839 }
840
841 if (!mode_valid && info->monspecs.modedb_len)
842 return -EINVAL;
843
844 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
845 par->fpHeight < var->yres))
846 return -EINVAL;
847
848 if (var->yres_virtual < var->yres)
849 var->yres_virtual = var->yres;
850
851 if (var->xres_virtual < var->xres)
852 var->xres_virtual = var->xres;
853
854 var->xres_virtual = (var->xres_virtual + 63) & ~63;
855
917bb077 856 vramlen = info->screen_size;
1da177e4
LT
857 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
858 memlen = pitch * var->yres_virtual;
859
860 if (memlen > vramlen) {
861 var->yres_virtual = vramlen / pitch;
862
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;
871
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;
879 }
880 }
881 }
882
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;
888 }
889
890 var->xres_virtual &= ~63;
891
892 NVTRACE_LEAVE();
893
894 return err;
895}
896
897static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
898 struct fb_info *info)
899{
900 struct nvidia_par *par = info->par;
901 u32 total;
902
3c8d61bc 903 total = var->yoffset * info->fix.line_length + var->xoffset;
1da177e4
LT
904
905 NVSetStartAddress(par, total);
906
907 return 0;
908}
909
910static int nvidiafb_blank(int blank, struct fb_info *info)
911{
912 struct nvidia_par *par = info->par;
913 unsigned char tmp, vesa;
914
915 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
916 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
917
918 NVTRACE_ENTER();
919
920 if (blank)
921 tmp |= 0x20;
922
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;
936 }
937
938 NVWriteSeq(par, 0x01, tmp);
939 NVWriteCrtc(par, 0x1a, vesa);
940
1da177e4
LT
941 NVTRACE_LEAVE();
942
943 return 0;
944}
945
946static struct fb_ops nvidia_fb_ops = {
947 .owner = THIS_MODULE,
948 .fb_check_var = nvidiafb_check_var,
949 .fb_set_par = nvidiafb_set_par,
950 .fb_setcolreg = nvidiafb_setcolreg,
951 .fb_pan_display = nvidiafb_pan_display,
952 .fb_blank = nvidiafb_blank,
953 .fb_fillrect = nvidiafb_fillrect,
954 .fb_copyarea = nvidiafb_copyarea,
955 .fb_imageblit = nvidiafb_imageblit,
956 .fb_cursor = nvidiafb_cursor,
957 .fb_sync = nvidiafb_sync,
958};
959
7a07cd78 960#ifdef CONFIG_PM
c78a7c2d 961static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
7a07cd78
AD
962{
963 struct fb_info *info = pci_get_drvdata(dev);
964 struct nvidia_par *par = info->par;
965
c78a7c2d
DB
966 if (mesg.event == PM_EVENT_PRETHAW)
967 mesg.event = PM_EVENT_FREEZE;
7a07cd78 968 acquire_console_sem();
c78a7c2d 969 par->pm_state = mesg.event;
7a07cd78 970
c78a7c2d 971 if (mesg.event == PM_EVENT_SUSPEND) {
7a07cd78
AD
972 fb_set_suspend(info, 1);
973 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
974 nvidia_write_regs(par, &par->SavedReg);
975 pci_save_state(dev);
976 pci_disable_device(dev);
c78a7c2d 977 pci_set_power_state(dev, pci_choose_state(dev, mesg));
7a07cd78 978 }
c78a7c2d 979 dev->dev.power.power_state = mesg;
7a07cd78
AD
980
981 release_console_sem();
982 return 0;
983}
984
985static int nvidiafb_resume(struct pci_dev *dev)
986{
987 struct fb_info *info = pci_get_drvdata(dev);
988 struct nvidia_par *par = info->par;
989
990 acquire_console_sem();
991 pci_set_power_state(dev, PCI_D0);
992
993 if (par->pm_state != PM_EVENT_FREEZE) {
994 pci_restore_state(dev);
7b566b1f
AD
995
996 if (pci_enable_device(dev))
997 goto fail;
998
7a07cd78
AD
999 pci_set_master(dev);
1000 }
1001
1002 par->pm_state = PM_EVENT_ON;
1003 nvidiafb_set_par(info);
1004 fb_set_suspend (info, 0);
1005 nvidiafb_blank(FB_BLANK_UNBLANK, info);
1006
7b566b1f 1007fail:
7a07cd78
AD
1008 release_console_sem();
1009 return 0;
1010}
1011#else
1012#define nvidiafb_suspend NULL
1013#define nvidiafb_resume NULL
1014#endif
1015
1da177e4
LT
1016static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1017{
1018 struct fb_monspecs *specs = &info->monspecs;
1019 struct fb_videomode modedb;
1020 struct nvidia_par *par = info->par;
1021 int lpitch;
1022
1023 NVTRACE_ENTER();
1024 info->flags = FBINFO_DEFAULT
1025 | FBINFO_HWACCEL_IMAGEBLIT
1026 | FBINFO_HWACCEL_FILLRECT
1027 | FBINFO_HWACCEL_COPYAREA
1028 | FBINFO_HWACCEL_YPAN;
1029
1030 fb_videomode_to_modelist(info->monspecs.modedb,
1031 info->monspecs.modedb_len, &info->modelist);
1032 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1033
ade9185a
AD
1034 switch (bpp) {
1035 case 0 ... 8:
1036 bpp = 8;
1037 break;
1038 case 9 ... 16:
1039 bpp = 16;
1040 break;
1041 default:
1042 bpp = 32;
1043 break;
1044 }
1045
1da177e4 1046 if (specs->modedb != NULL) {
9791d763 1047 const struct fb_videomode *mode;
1da177e4 1048
9791d763
GU
1049 mode = fb_find_best_display(specs, &info->modelist);
1050 fb_videomode_to_var(&nvidiafb_default_var, mode);
ade9185a 1051 nvidiafb_default_var.bits_per_pixel = bpp;
db6778db
AD
1052 } else if (par->fpWidth && par->fpHeight) {
1053 char buf[16];
1054
1055 memset(buf, 0, 16);
948a95ff 1056 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
db6778db 1057 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
ade9185a 1058 specs->modedb_len, &modedb, bpp);
1da177e4
LT
1059 }
1060
1061 if (mode_option)
1062 fb_find_mode(&nvidiafb_default_var, info, mode_option,
ade9185a 1063 specs->modedb, specs->modedb_len, &modedb, bpp);
1da177e4
LT
1064
1065 info->var = nvidiafb_default_var;
1066 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1067 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1068 info->pseudo_palette = par->pseudo_palette;
1069 fb_alloc_cmap(&info->cmap, 256, 0);
1070 fb_destroy_modedb(info->monspecs.modedb);
1071 info->monspecs.modedb = NULL;
1072
1073 /* maximize virtual vertical length */
1074 lpitch = info->var.xres_virtual *
1075 ((info->var.bits_per_pixel + 7) >> 3);
917bb077 1076 info->var.yres_virtual = info->screen_size / lpitch;
1da177e4
LT
1077
1078 info->pixmap.scan_align = 4;
1079 info->pixmap.buf_align = 4;
58a60643 1080 info->pixmap.access_align = 32;
1da177e4
LT
1081 info->pixmap.size = 8 * 1024;
1082 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1083
7a482425 1084 if (!hwcur)
c465e05a 1085 info->fbops->fb_cursor = NULL;
7a482425 1086
1da177e4
LT
1087 info->var.accel_flags = (!noaccel);
1088
1089 switch (par->Architecture) {
1090 case NV_ARCH_04:
1091 info->fix.accel = FB_ACCEL_NV4;
1092 break;
1093 case NV_ARCH_10:
1094 info->fix.accel = FB_ACCEL_NV_10;
1095 break;
1096 case NV_ARCH_20:
1097 info->fix.accel = FB_ACCEL_NV_20;
1098 break;
1099 case NV_ARCH_30:
1100 info->fix.accel = FB_ACCEL_NV_30;
1101 break;
1102 case NV_ARCH_40:
1103 info->fix.accel = FB_ACCEL_NV_40;
1104 break;
1105 }
1106
1107 NVTRACE_LEAVE();
1108
1109 return nvidiafb_check_var(&info->var, info);
1110}
1111
c549dc64 1112static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1da177e4 1113{
c549dc64
AD
1114 struct nvidia_par *par = info->par;
1115 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1116
8eec4981
AD
1117 printk(KERN_INFO PFX "Device ID: %x \n", id);
1118
c549dc64
AD
1119 if ((id & 0xfff0) == 0x00f0) {
1120 /* pci-e */
c549dc64
AD
1121 id = NV_RD32(par->REGS, 0x1800);
1122
1123 if ((id & 0x0000ffff) == 0x000010DE)
1124 id = 0x10DE0000 | (id >> 16);
1125 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1126 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1127 ((id >> 8) & 0x000000ff);
8eec4981 1128 printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
c549dc64
AD
1129 }
1130
c549dc64
AD
1131 return id;
1132}
1133
1134static u32 __devinit nvidia_get_arch(struct fb_info *info)
1135{
1136 struct nvidia_par *par = info->par;
1da177e4
LT
1137 u32 arch = 0;
1138
c549dc64 1139 switch (par->Chipset & 0x0ff0) {
1da177e4
LT
1140 case 0x0100: /* GeForce 256 */
1141 case 0x0110: /* GeForce2 MX */
1142 case 0x0150: /* GeForce2 */
1143 case 0x0170: /* GeForce4 MX */
1144 case 0x0180: /* GeForce4 MX (8x AGP) */
1145 case 0x01A0: /* nForce */
1146 case 0x01F0: /* nForce2 */
1147 arch = NV_ARCH_10;
1148 break;
1149 case 0x0200: /* GeForce3 */
1150 case 0x0250: /* GeForce4 Ti */
1151 case 0x0280: /* GeForce4 Ti (8x AGP) */
1152 arch = NV_ARCH_20;
1153 break;
1154 case 0x0300: /* GeForceFX 5800 */
1155 case 0x0310: /* GeForceFX 5600 */
1156 case 0x0320: /* GeForceFX 5200 */
1157 case 0x0330: /* GeForceFX 5900 */
1158 case 0x0340: /* GeForceFX 5700 */
1159 arch = NV_ARCH_30;
1160 break;
e40c6759
WS
1161 case 0x0040: /* GeForce 6800 */
1162 case 0x00C0: /* GeForce 6800 */
1163 case 0x0120: /* GeForce 6800 */
1da177e4 1164 case 0x0130:
e40c6759
WS
1165 case 0x0140: /* GeForce 6600 */
1166 case 0x0160: /* GeForce 6200 */
1167 case 0x01D0: /* GeForce 7200, 7300, 7400 */
1168 case 0x0090: /* GeForce 7800 */
1169 case 0x0210: /* GeForce 6800 */
1170 case 0x0220: /* GeForce 6200 */
1da177e4 1171 case 0x0230:
e40c6759
WS
1172 case 0x0240: /* GeForce 6100 */
1173 case 0x0290: /* GeForce 7900 */
1174 case 0x0390: /* GeForce 7600 */
1da177e4
LT
1175 arch = NV_ARCH_40;
1176 break;
1177 case 0x0020: /* TNT, TNT2 */
1178 arch = NV_ARCH_04;
1179 break;
1180 default: /* unknown architecture */
1181 break;
1182 }
1183
1184 return arch;
1185}
1186
1187static int __devinit nvidiafb_probe(struct pci_dev *pd,
1188 const struct pci_device_id *ent)
1189{
1190 struct nvidia_par *par;
1191 struct fb_info *info;
1192 unsigned short cmd;
1193
1194
1195 NVTRACE_ENTER();
1196 assert(pd != NULL);
1197
1198 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1199
1200 if (!info)
1201 goto err_out;
1202
c439e345 1203 par = info->par;
1da177e4
LT
1204 par->pci_dev = pd;
1205
f5610b9c 1206 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
1da177e4
LT
1207
1208 if (info->pixmap.addr == NULL)
1209 goto err_out_kfree;
1210
1da177e4
LT
1211 if (pci_enable_device(pd)) {
1212 printk(KERN_ERR PFX "cannot enable PCI device\n");
1213 goto err_out_enable;
1214 }
1215
1216 if (pci_request_regions(pd, "nvidiafb")) {
1217 printk(KERN_ERR PFX "cannot request PCI regions\n");
a06630f3 1218 goto err_out_enable;
1da177e4
LT
1219 }
1220
1da177e4 1221 par->FlatPanel = flatpanel;
1da177e4
LT
1222 if (flatpanel == 1)
1223 printk(KERN_INFO PFX "flatpanel support enabled\n");
b8c49ef6 1224 par->FPDither = fpdither;
1da177e4
LT
1225
1226 par->CRTCnumber = forceCRTC;
1227 par->FpScale = (!noscale);
1228 par->paneltweak = paneltweak;
1229
1230 /* enable IO and mem if not already done */
1231 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1232 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1233 pci_write_config_word(pd, PCI_COMMAND, cmd);
1234
1235 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1236 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1237 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1238
1239 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1240
1241 if (!par->REGS) {
1242 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1243 goto err_out_free_base0;
1244 }
1245
c549dc64 1246 par->Chipset = nvidia_get_chipset(info);
c549dc64
AD
1247 par->Architecture = nvidia_get_arch(info);
1248
1249 if (par->Architecture == 0) {
1250 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1251 goto err_out_arch;
1252 }
1253
1254 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1255
918799ab
AD
1256 if (NVCommonSetup(info))
1257 goto err_out_arch;
1da177e4
LT
1258
1259 par->FbAddress = nvidiafb_fix.smem_start;
1260 par->FbMapSize = par->RamAmountKBytes * 1024;
917bb077
AD
1261 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1262 par->FbMapSize = vram * 1024 * 1024;
1263
1264 /* Limit amount of vram to 64 MB */
1265 if (par->FbMapSize > 64 * 1024 * 1024)
1266 par->FbMapSize = 64 * 1024 * 1024;
1267
0137ecfd
BH
1268 if(par->Architecture >= NV_ARCH_40)
1269 par->FbUsableSize = par->FbMapSize - (560 * 1024);
1270 else
1271 par->FbUsableSize = par->FbMapSize - (128 * 1024);
1da177e4
LT
1272 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1273 16 * 1024;
1274 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
0137ecfd
BH
1275 par->CursorStart = par->FbUsableSize + (32 * 1024);
1276
1da177e4 1277 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
917bb077
AD
1278 info->screen_size = par->FbUsableSize;
1279 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
1da177e4
LT
1280
1281 if (!info->screen_base) {
1282 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1283 goto err_out_free_base1;
1284 }
1285
1286 par->FbStart = info->screen_base;
1287
1288#ifdef CONFIG_MTRR
1289 if (!nomtrr) {
1290 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
917bb077
AD
1291 par->RamAmountKBytes * 1024,
1292 MTRR_TYPE_WRCOMB, 1);
1da177e4
LT
1293 if (par->mtrr.vram < 0) {
1294 printk(KERN_ERR PFX "unable to setup MTRR\n");
1295 } else {
1296 par->mtrr.vram_valid = 1;
1297 /* let there be speed */
1298 printk(KERN_INFO PFX "MTRR set to ON\n");
1299 }
1300 }
1301#endif /* CONFIG_MTRR */
1302
1303 info->fbops = &nvidia_fb_ops;
1304 info->fix = nvidiafb_fix;
1305
1306 if (nvidia_set_fbinfo(info) < 0) {
1307 printk(KERN_ERR PFX "error setting initial video mode\n");
1308 goto err_out_iounmap_fb;
1309 }
1310
1311 nvidia_save_vga(par, &par->SavedReg);
1312
ce38cac4
GG
1313 pci_set_drvdata(pd, info);
1314 nvidia_bl_init(par);
1da177e4
LT
1315 if (register_framebuffer(info) < 0) {
1316 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1317 goto err_out_iounmap_fb;
1318 }
1319
1da177e4
LT
1320
1321 printk(KERN_INFO PFX
1322 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1323 info->fix.id,
1324 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
5474c120 1325
1da177e4
LT
1326 NVTRACE_LEAVE();
1327 return 0;
1328
c549dc64 1329err_out_iounmap_fb:
1da177e4 1330 iounmap(info->screen_base);
c549dc64 1331err_out_free_base1:
1da177e4
LT
1332 fb_destroy_modedb(info->monspecs.modedb);
1333 nvidia_delete_i2c_busses(par);
c549dc64 1334err_out_arch:
1da177e4 1335 iounmap(par->REGS);
a06630f3 1336 err_out_free_base0:
1da177e4 1337 pci_release_regions(pd);
c549dc64 1338err_out_enable:
1da177e4 1339 kfree(info->pixmap.addr);
c549dc64 1340err_out_kfree:
1da177e4 1341 framebuffer_release(info);
c549dc64 1342err_out:
1da177e4
LT
1343 return -ENODEV;
1344}
1345
5e14ab8b 1346static void __devexit nvidiafb_remove(struct pci_dev *pd)
1da177e4
LT
1347{
1348 struct fb_info *info = pci_get_drvdata(pd);
1349 struct nvidia_par *par = info->par;
1350
1351 NVTRACE_ENTER();
1da177e4 1352
37ce69a5
RP
1353 unregister_framebuffer(info);
1354
5474c120
MH
1355 nvidia_bl_exit(par);
1356
1da177e4
LT
1357#ifdef CONFIG_MTRR
1358 if (par->mtrr.vram_valid)
1359 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1360 info->fix.smem_len);
1361#endif /* CONFIG_MTRR */
1362
1363 iounmap(info->screen_base);
1364 fb_destroy_modedb(info->monspecs.modedb);
1365 nvidia_delete_i2c_busses(par);
1366 iounmap(par->REGS);
1367 pci_release_regions(pd);
1da177e4
LT
1368 kfree(info->pixmap.addr);
1369 framebuffer_release(info);
1370 pci_set_drvdata(pd, NULL);
1371 NVTRACE_LEAVE();
1372}
1373
1374/* ------------------------------------------------------------------------- *
1375 *
1376 * initialization
1377 *
1378 * ------------------------------------------------------------------------- */
1379
1380#ifndef MODULE
1381static int __devinit nvidiafb_setup(char *options)
1382{
1383 char *this_opt;
1384
1385 NVTRACE_ENTER();
1386 if (!options || !*options)
1387 return 0;
1388
1389 while ((this_opt = strsep(&options, ",")) != NULL) {
1390 if (!strncmp(this_opt, "forceCRTC", 9)) {
1391 char *p;
1392
1393 p = this_opt + 9;
1394 if (!*p || !*(++p))
1395 continue;
1396 forceCRTC = *p - '0';
1397 if (forceCRTC < 0 || forceCRTC > 1)
1398 forceCRTC = -1;
1399 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1400 flatpanel = 1;
1401 } else if (!strncmp(this_opt, "hwcur", 5)) {
1402 hwcur = 1;
1403 } else if (!strncmp(this_opt, "noaccel", 6)) {
1404 noaccel = 1;
1405 } else if (!strncmp(this_opt, "noscale", 7)) {
1406 noscale = 1;
1407 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1408 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
917bb077
AD
1409 } else if (!strncmp(this_opt, "vram:", 5)) {
1410 vram = simple_strtoul(this_opt+5, NULL, 0);
1da177e4
LT
1411#ifdef CONFIG_MTRR
1412 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1413 nomtrr = 1;
1414#endif
b8c49ef6
BH
1415 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1416 fpdither = simple_strtol(this_opt+9, NULL, 0);
ade9185a
AD
1417 } else if (!strncmp(this_opt, "bpp:", 4)) {
1418 bpp = simple_strtoul(this_opt+4, NULL, 0);
1da177e4
LT
1419 } else
1420 mode_option = this_opt;
1421 }
1422 NVTRACE_LEAVE();
1423 return 0;
1424}
1425#endif /* !MODULE */
1426
1427static struct pci_driver nvidiafb_driver = {
1428 .name = "nvidiafb",
1429 .id_table = nvidiafb_pci_tbl,
7a07cd78
AD
1430 .probe = nvidiafb_probe,
1431 .suspend = nvidiafb_suspend,
1432 .resume = nvidiafb_resume,
5e14ab8b 1433 .remove = __devexit_p(nvidiafb_remove),
1da177e4
LT
1434};
1435
1436/* ------------------------------------------------------------------------- *
1437 *
1438 * modularization
1439 *
1440 * ------------------------------------------------------------------------- */
1441
1442static int __devinit nvidiafb_init(void)
1443{
1444#ifndef MODULE
1445 char *option = NULL;
1446
1447 if (fb_get_options("nvidiafb", &option))
1448 return -ENODEV;
1449 nvidiafb_setup(option);
1450#endif
1451 return pci_register_driver(&nvidiafb_driver);
1452}
1453
1454module_init(nvidiafb_init);
1455
1456#ifdef MODULE
1457static void __exit nvidiafb_exit(void)
1458{
1459 pci_unregister_driver(&nvidiafb_driver);
1460}
1461
1462module_exit(nvidiafb_exit);
1463
1464module_param(flatpanel, int, 0);
1465MODULE_PARM_DESC(flatpanel,
1466 "Enables experimental flat panel support for some chipsets. "
b8c49ef6
BH
1467 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1468module_param(fpdither, int, 0);
1469MODULE_PARM_DESC(fpdither,
1470 "Enables dithering of flat panel for 6 bits panels. "
1471 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1da177e4
LT
1472module_param(hwcur, int, 0);
1473MODULE_PARM_DESC(hwcur,
1474 "Enables hardware cursor implementation. (0 or 1=enabled) "
1475 "(default=0)");
1476module_param(noaccel, int, 0);
1477MODULE_PARM_DESC(noaccel,
1478 "Disables hardware acceleration. (0 or 1=disable) "
1479 "(default=0)");
1480module_param(noscale, int, 0);
1481MODULE_PARM_DESC(noscale,
1482 "Disables screen scaleing. (0 or 1=disable) "
1483 "(default=0, do scaling)");
1484module_param(paneltweak, int, 0);
1485MODULE_PARM_DESC(paneltweak,
1486 "Tweak display settings for flatpanels. "
1487 "(default=0, no tweaks)");
1488module_param(forceCRTC, int, 0);
1489MODULE_PARM_DESC(forceCRTC,
1490 "Forces usage of a particular CRTC in case autodetection "
1491 "fails. (0 or 1) (default=autodetect)");
917bb077
AD
1492module_param(vram, int, 0);
1493MODULE_PARM_DESC(vram,
1494 "amount of framebuffer memory to remap in MiB"
1495 "(default=0 - remap entire memory)");
c439e345
AD
1496module_param(mode_option, charp, 0);
1497MODULE_PARM_DESC(mode_option, "Specify initial video mode");
ade9185a
AD
1498module_param(bpp, int, 0);
1499MODULE_PARM_DESC(bpp, "pixel width in bits"
1500 "(default=8)");
1da177e4
LT
1501#ifdef CONFIG_MTRR
1502module_param(nomtrr, bool, 0);
1503MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1504 "(default=0)");
1505#endif
1506
1507MODULE_AUTHOR("Antonino Daplas");
1508MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1509MODULE_LICENSE("GPL");
1510#endif /* MODULE */
1511