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