blacklight: remove redundant spi driver bus initialization
[deliverable/linux.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#ifdef CONFIG_FB_NVIDIA_DEBUG
41#define NVTRACE printk
42#else
43#define NVTRACE if (0) printk
44#endif
45
5ae12170
HH
46#define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__)
47#define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__)
1da177e4
LT
48
49#ifdef CONFIG_FB_NVIDIA_DEBUG
50#define assert(expr) \
51 if (!(expr)) { \
52 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
5ae12170 53 #expr,__FILE__,__func__,__LINE__); \
1da177e4
LT
54 BUG(); \
55 }
56#else
57#define assert(expr)
58#endif
59
60#define PFX "nvidiafb: "
61
62/* HW cursor parameters */
63#define MAX_CURS 32
64
65static struct pci_device_id nvidiafb_pci_tbl[] = {
8eec4981
AD
66 {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
67 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
68 { 0, }
1da177e4 69};
1da177e4
LT
70MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
71
72/* command line data, set in nvidiafb_setup() */
73static int flatpanel __devinitdata = -1; /* Autodetect later */
b8c49ef6 74static int fpdither __devinitdata = -1;
1da177e4
LT
75static int forceCRTC __devinitdata = -1;
76static int hwcur __devinitdata = 0;
77static int noaccel __devinitdata = 0;
78static int noscale __devinitdata = 0;
79static int paneltweak __devinitdata = 0;
917bb077 80static int vram __devinitdata = 0;
ade9185a 81static int bpp __devinitdata = 8;
3c03ec20 82static int reverse_i2c __devinitdata;
1da177e4 83#ifdef CONFIG_MTRR
08346bf8 84static bool nomtrr __devinitdata = false;
1da177e4 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;
01b15bd4 678 info->flags |= FBINFO_READS_FAST;
1da177e4
LT
679 NVResetGraphics(info);
680 } else {
681 info->fbops->fb_imageblit = cfb_imageblit;
682 info->fbops->fb_fillrect = cfb_fillrect;
683 info->fbops->fb_copyarea = cfb_copyarea;
684 info->fbops->fb_sync = NULL;
685 info->pixmap.scan_align = 1;
686 info->flags |= FBINFO_HWACCEL_DISABLED;
01b15bd4 687 info->flags &= ~FBINFO_READS_FAST;
1da177e4
LT
688 }
689
690 par->cursor_reset = 1;
691
b9b2696d 692 nvidia_screen_off(par, 0);
1da177e4 693
70abac6e
PM
694#ifdef CONFIG_BOOTX_TEXT
695 /* Update debug text engine */
696 btext_update_display(info->fix.smem_start,
697 info->var.xres, info->var.yres,
698 info->var.bits_per_pixel, info->fix.line_length);
699#endif
700
b9b2696d 701 NVLockUnlock(par, 0);
1da177e4
LT
702 NVTRACE_LEAVE();
703 return 0;
704}
705
706static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
707 unsigned blue, unsigned transp,
708 struct fb_info *info)
709{
710 struct nvidia_par *par = info->par;
711 int i;
712
713 NVTRACE_ENTER();
714 if (regno >= (1 << info->var.green.length))
715 return -EINVAL;
716
717 if (info->var.grayscale) {
718 /* gray = 0.30*R + 0.59*G + 0.11*B */
719 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
720 }
721
722 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
723 ((u32 *) info->pseudo_palette)[regno] =
724 (regno << info->var.red.offset) |
725 (regno << info->var.green.offset) |
726 (regno << info->var.blue.offset);
727 }
728
729 switch (info->var.bits_per_pixel) {
730 case 8:
731 /* "transparent" stuff is completely ignored. */
732 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
733 break;
734 case 16:
735 if (info->var.green.length == 5) {
736 for (i = 0; i < 8; i++) {
737 nvidia_write_clut(par, regno * 8 + i, red >> 8,
738 green >> 8, blue >> 8);
739 }
740 } else {
741 u8 r, g, b;
742
743 if (regno < 32) {
744 for (i = 0; i < 8; i++) {
745 nvidia_write_clut(par, regno * 8 + i,
746 red >> 8, green >> 8,
747 blue >> 8);
748 }
749 }
750
751 nvidia_read_clut(par, regno * 4, &r, &g, &b);
752
753 for (i = 0; i < 4; i++)
754 nvidia_write_clut(par, regno * 4 + i, r,
755 green >> 8, b);
756 }
757 break;
758 case 32:
759 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
760 break;
761 default:
762 /* do nothing */
763 break;
764 }
765
766 NVTRACE_LEAVE();
767 return 0;
768}
769
770static int nvidiafb_check_var(struct fb_var_screeninfo *var,
771 struct fb_info *info)
772{
773 struct nvidia_par *par = info->par;
774 int memlen, vramlen, mode_valid = 0;
775 int pitch, err = 0;
776
777 NVTRACE_ENTER();
778
779 var->transp.offset = 0;
780 var->transp.length = 0;
781
782 var->xres &= ~7;
783
784 if (var->bits_per_pixel <= 8)
785 var->bits_per_pixel = 8;
786 else if (var->bits_per_pixel <= 16)
787 var->bits_per_pixel = 16;
788 else
789 var->bits_per_pixel = 32;
790
791 switch (var->bits_per_pixel) {
792 case 8:
793 var->red.offset = 0;
794 var->red.length = 8;
795 var->green.offset = 0;
796 var->green.length = 8;
797 var->blue.offset = 0;
798 var->blue.length = 8;
799 var->transp.offset = 0;
800 var->transp.length = 0;
801 break;
802 case 16:
803 var->green.length = (var->green.length < 6) ? 5 : 6;
804 var->red.length = 5;
805 var->blue.length = 5;
806 var->transp.length = 6 - var->green.length;
807 var->blue.offset = 0;
808 var->green.offset = 5;
809 var->red.offset = 5 + var->green.length;
810 var->transp.offset = (5 + var->red.offset) & 15;
811 break;
812 case 32: /* RGBA 8888 */
813 var->red.offset = 16;
814 var->red.length = 8;
815 var->green.offset = 8;
816 var->green.length = 8;
817 var->blue.offset = 0;
818 var->blue.length = 8;
819 var->transp.length = 8;
820 var->transp.offset = 24;
821 break;
822 }
823
824 var->red.msb_right = 0;
825 var->green.msb_right = 0;
826 var->blue.msb_right = 0;
827 var->transp.msb_right = 0;
828
829 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
830 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
831 mode_valid = 1;
832
833 /* calculate modeline if supported by monitor */
834 if (!mode_valid && info->monspecs.gtf) {
835 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
836 mode_valid = 1;
837 }
838
839 if (!mode_valid) {
9791d763 840 const struct fb_videomode *mode;
1da177e4
LT
841
842 mode = fb_find_best_mode(var, &info->modelist);
843 if (mode) {
844 fb_videomode_to_var(var, mode);
845 mode_valid = 1;
846 }
847 }
848
849 if (!mode_valid && info->monspecs.modedb_len)
850 return -EINVAL;
851
74f482cc
PM
852 /*
853 * If we're on a flat panel, check if the mode is outside of the
854 * panel dimensions. If so, cap it and try for the next best mode
855 * before bailing out.
856 */
1da177e4 857 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
74f482cc
PM
858 par->fpHeight < var->yres)) {
859 const struct fb_videomode *mode;
860
861 var->xres = par->fpWidth;
862 var->yres = par->fpHeight;
863
864 mode = fb_find_best_mode(var, &info->modelist);
865 if (!mode) {
866 printk(KERN_ERR PFX "mode out of range of flat "
867 "panel dimensions\n");
868 return -EINVAL;
869 }
870
871 fb_videomode_to_var(var, mode);
872 }
1da177e4
LT
873
874 if (var->yres_virtual < var->yres)
875 var->yres_virtual = var->yres;
876
877 if (var->xres_virtual < var->xres)
878 var->xres_virtual = var->xres;
879
880 var->xres_virtual = (var->xres_virtual + 63) & ~63;
881
917bb077 882 vramlen = info->screen_size;
1da177e4
LT
883 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
884 memlen = pitch * var->yres_virtual;
885
886 if (memlen > vramlen) {
887 var->yres_virtual = vramlen / pitch;
888
889 if (var->yres_virtual < var->yres) {
890 var->yres_virtual = var->yres;
891 var->xres_virtual = vramlen / var->yres_virtual;
892 var->xres_virtual /= var->bits_per_pixel / 8;
893 var->xres_virtual &= ~63;
894 pitch = (var->xres_virtual *
895 var->bits_per_pixel + 7) / 8;
896 memlen = pitch * var->yres;
897
898 if (var->xres_virtual < var->xres) {
899 printk("nvidiafb: required video memory, "
900 "%d bytes, for %dx%d-%d (virtual) "
901 "is out of range\n",
902 memlen, var->xres_virtual,
903 var->yres_virtual, var->bits_per_pixel);
904 err = -ENOMEM;
905 }
906 }
907 }
908
909 if (var->accel_flags) {
910 if (var->yres_virtual > 0x7fff)
911 var->yres_virtual = 0x7fff;
912 if (var->xres_virtual > 0x7fff)
913 var->xres_virtual = 0x7fff;
914 }
915
916 var->xres_virtual &= ~63;
917
918 NVTRACE_LEAVE();
919
920 return err;
921}
922
923static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
924 struct fb_info *info)
925{
926 struct nvidia_par *par = info->par;
927 u32 total;
928
3c8d61bc 929 total = var->yoffset * info->fix.line_length + var->xoffset;
1da177e4
LT
930
931 NVSetStartAddress(par, total);
932
933 return 0;
934}
935
936static int nvidiafb_blank(int blank, struct fb_info *info)
937{
938 struct nvidia_par *par = info->par;
939 unsigned char tmp, vesa;
940
941 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
942 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
943
944 NVTRACE_ENTER();
945
946 if (blank)
947 tmp |= 0x20;
948
949 switch (blank) {
950 case FB_BLANK_UNBLANK:
951 case FB_BLANK_NORMAL:
952 break;
953 case FB_BLANK_VSYNC_SUSPEND:
954 vesa |= 0x80;
955 break;
956 case FB_BLANK_HSYNC_SUSPEND:
957 vesa |= 0x40;
958 break;
959 case FB_BLANK_POWERDOWN:
960 vesa |= 0xc0;
961 break;
962 }
963
964 NVWriteSeq(par, 0x01, tmp);
965 NVWriteCrtc(par, 0x1a, vesa);
966
1da177e4
LT
967 NVTRACE_LEAVE();
968
969 return 0;
970}
971
7dfe50b3
AD
972/*
973 * Because the VGA registers are not mapped linearly in its MMIO space,
974 * restrict VGA register saving and restore to x86 only, where legacy VGA IO
975 * access is legal. Consequently, we must also check if the device is the
976 * primary display.
977 */
978#ifdef CONFIG_X86
979static void save_vga_x86(struct nvidia_par *par)
980{
981 struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
982
983 if (res && res->flags & IORESOURCE_ROM_SHADOW) {
984 memset(&par->vgastate, 0, sizeof(par->vgastate));
985 par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
986 VGA_SAVE_CMAP;
987 save_vga(&par->vgastate);
988 }
989}
990
991static void restore_vga_x86(struct nvidia_par *par)
992{
993 struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
994
995 if (res && res->flags & IORESOURCE_ROM_SHADOW)
996 restore_vga(&par->vgastate);
997}
998#else
999#define save_vga_x86(x) do {} while (0)
1000#define restore_vga_x86(x) do {} while (0)
1001#endif /* X86 */
1002
1003static int nvidiafb_open(struct fb_info *info, int user)
1004{
1005 struct nvidia_par *par = info->par;
1006
7dfe50b3
AD
1007 if (!par->open_count) {
1008 save_vga_x86(par);
1009 nvidia_save_vga(par, &par->initial_state);
1010 }
1011
1012 par->open_count++;
7dfe50b3
AD
1013 return 0;
1014}
1015
1016static int nvidiafb_release(struct fb_info *info, int user)
1017{
1018 struct nvidia_par *par = info->par;
1019 int err = 0;
1020
7dfe50b3
AD
1021 if (!par->open_count) {
1022 err = -EINVAL;
1023 goto done;
1024 }
1025
1026 if (par->open_count == 1) {
1027 nvidia_write_regs(par, &par->initial_state);
1028 restore_vga_x86(par);
1029 }
1030
1031 par->open_count--;
1032done:
2620c6e3 1033 return err;
7dfe50b3
AD
1034}
1035
1da177e4
LT
1036static struct fb_ops nvidia_fb_ops = {
1037 .owner = THIS_MODULE,
7dfe50b3
AD
1038 .fb_open = nvidiafb_open,
1039 .fb_release = nvidiafb_release,
1da177e4
LT
1040 .fb_check_var = nvidiafb_check_var,
1041 .fb_set_par = nvidiafb_set_par,
1042 .fb_setcolreg = nvidiafb_setcolreg,
1043 .fb_pan_display = nvidiafb_pan_display,
1044 .fb_blank = nvidiafb_blank,
1045 .fb_fillrect = nvidiafb_fillrect,
1046 .fb_copyarea = nvidiafb_copyarea,
1047 .fb_imageblit = nvidiafb_imageblit,
1048 .fb_cursor = nvidiafb_cursor,
1049 .fb_sync = nvidiafb_sync,
1050};
1051
7a07cd78 1052#ifdef CONFIG_PM
c78a7c2d 1053static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
7a07cd78
AD
1054{
1055 struct fb_info *info = pci_get_drvdata(dev);
1056 struct nvidia_par *par = info->par;
1057
c78a7c2d
DB
1058 if (mesg.event == PM_EVENT_PRETHAW)
1059 mesg.event = PM_EVENT_FREEZE;
ac751efa 1060 console_lock();
c78a7c2d 1061 par->pm_state = mesg.event;
7a07cd78 1062
3a2d5b70 1063 if (mesg.event & PM_EVENT_SLEEP) {
7a07cd78
AD
1064 fb_set_suspend(info, 1);
1065 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
1066 nvidia_write_regs(par, &par->SavedReg);
1067 pci_save_state(dev);
1068 pci_disable_device(dev);
c78a7c2d 1069 pci_set_power_state(dev, pci_choose_state(dev, mesg));
7a07cd78 1070 }
c78a7c2d 1071 dev->dev.power.power_state = mesg;
7a07cd78 1072
ac751efa 1073 console_unlock();
7a07cd78
AD
1074 return 0;
1075}
1076
1077static int nvidiafb_resume(struct pci_dev *dev)
1078{
1079 struct fb_info *info = pci_get_drvdata(dev);
1080 struct nvidia_par *par = info->par;
1081
ac751efa 1082 console_lock();
7a07cd78
AD
1083 pci_set_power_state(dev, PCI_D0);
1084
1085 if (par->pm_state != PM_EVENT_FREEZE) {
1086 pci_restore_state(dev);
7b566b1f
AD
1087
1088 if (pci_enable_device(dev))
1089 goto fail;
1090
7a07cd78
AD
1091 pci_set_master(dev);
1092 }
1093
1094 par->pm_state = PM_EVENT_ON;
1095 nvidiafb_set_par(info);
1096 fb_set_suspend (info, 0);
1097 nvidiafb_blank(FB_BLANK_UNBLANK, info);
1098
7b566b1f 1099fail:
ac751efa 1100 console_unlock();
7a07cd78
AD
1101 return 0;
1102}
1103#else
1104#define nvidiafb_suspend NULL
1105#define nvidiafb_resume NULL
1106#endif
1107
1da177e4
LT
1108static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1109{
1110 struct fb_monspecs *specs = &info->monspecs;
1111 struct fb_videomode modedb;
1112 struct nvidia_par *par = info->par;
1113 int lpitch;
1114
1115 NVTRACE_ENTER();
1116 info->flags = FBINFO_DEFAULT
1117 | FBINFO_HWACCEL_IMAGEBLIT
1118 | FBINFO_HWACCEL_FILLRECT
1119 | FBINFO_HWACCEL_COPYAREA
1120 | FBINFO_HWACCEL_YPAN;
1121
1122 fb_videomode_to_modelist(info->monspecs.modedb,
1123 info->monspecs.modedb_len, &info->modelist);
1124 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1125
ade9185a
AD
1126 switch (bpp) {
1127 case 0 ... 8:
1128 bpp = 8;
1129 break;
1130 case 9 ... 16:
1131 bpp = 16;
1132 break;
1133 default:
1134 bpp = 32;
1135 break;
1136 }
1137
1da177e4 1138 if (specs->modedb != NULL) {
9791d763 1139 const struct fb_videomode *mode;
1da177e4 1140
9791d763
GU
1141 mode = fb_find_best_display(specs, &info->modelist);
1142 fb_videomode_to_var(&nvidiafb_default_var, mode);
ade9185a 1143 nvidiafb_default_var.bits_per_pixel = bpp;
db6778db
AD
1144 } else if (par->fpWidth && par->fpHeight) {
1145 char buf[16];
1146
1147 memset(buf, 0, 16);
948a95ff 1148 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
db6778db 1149 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
ade9185a 1150 specs->modedb_len, &modedb, bpp);
1da177e4
LT
1151 }
1152
1153 if (mode_option)
1154 fb_find_mode(&nvidiafb_default_var, info, mode_option,
ade9185a 1155 specs->modedb, specs->modedb_len, &modedb, bpp);
1da177e4
LT
1156
1157 info->var = nvidiafb_default_var;
1158 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1159 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1160 info->pseudo_palette = par->pseudo_palette;
1161 fb_alloc_cmap(&info->cmap, 256, 0);
1162 fb_destroy_modedb(info->monspecs.modedb);
1163 info->monspecs.modedb = NULL;
1164
1165 /* maximize virtual vertical length */
1166 lpitch = info->var.xres_virtual *
1167 ((info->var.bits_per_pixel + 7) >> 3);
917bb077 1168 info->var.yres_virtual = info->screen_size / lpitch;
1da177e4
LT
1169
1170 info->pixmap.scan_align = 4;
1171 info->pixmap.buf_align = 4;
58a60643 1172 info->pixmap.access_align = 32;
1da177e4
LT
1173 info->pixmap.size = 8 * 1024;
1174 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1175
7a482425 1176 if (!hwcur)
c465e05a 1177 info->fbops->fb_cursor = NULL;
7a482425 1178
1da177e4
LT
1179 info->var.accel_flags = (!noaccel);
1180
1181 switch (par->Architecture) {
1182 case NV_ARCH_04:
1183 info->fix.accel = FB_ACCEL_NV4;
1184 break;
1185 case NV_ARCH_10:
1186 info->fix.accel = FB_ACCEL_NV_10;
1187 break;
1188 case NV_ARCH_20:
1189 info->fix.accel = FB_ACCEL_NV_20;
1190 break;
1191 case NV_ARCH_30:
1192 info->fix.accel = FB_ACCEL_NV_30;
1193 break;
1194 case NV_ARCH_40:
1195 info->fix.accel = FB_ACCEL_NV_40;
1196 break;
1197 }
1198
1199 NVTRACE_LEAVE();
1200
1201 return nvidiafb_check_var(&info->var, info);
1202}
1203
c549dc64 1204static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1da177e4 1205{
c549dc64
AD
1206 struct nvidia_par *par = info->par;
1207 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1208
8eec4981
AD
1209 printk(KERN_INFO PFX "Device ID: %x \n", id);
1210
ac1ae162
AD
1211 if ((id & 0xfff0) == 0x00f0 ||
1212 (id & 0xfff0) == 0x02e0) {
c549dc64 1213 /* pci-e */
c549dc64
AD
1214 id = NV_RD32(par->REGS, 0x1800);
1215
1216 if ((id & 0x0000ffff) == 0x000010DE)
1217 id = 0x10DE0000 | (id >> 16);
1218 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1219 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1220 ((id >> 8) & 0x000000ff);
8eec4981 1221 printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
c549dc64
AD
1222 }
1223
c549dc64
AD
1224 return id;
1225}
1226
1227static u32 __devinit nvidia_get_arch(struct fb_info *info)
1228{
1229 struct nvidia_par *par = info->par;
1da177e4
LT
1230 u32 arch = 0;
1231
c549dc64 1232 switch (par->Chipset & 0x0ff0) {
1da177e4
LT
1233 case 0x0100: /* GeForce 256 */
1234 case 0x0110: /* GeForce2 MX */
1235 case 0x0150: /* GeForce2 */
1236 case 0x0170: /* GeForce4 MX */
1237 case 0x0180: /* GeForce4 MX (8x AGP) */
1238 case 0x01A0: /* nForce */
1239 case 0x01F0: /* nForce2 */
1240 arch = NV_ARCH_10;
1241 break;
1242 case 0x0200: /* GeForce3 */
1243 case 0x0250: /* GeForce4 Ti */
1244 case 0x0280: /* GeForce4 Ti (8x AGP) */
1245 arch = NV_ARCH_20;
1246 break;
1247 case 0x0300: /* GeForceFX 5800 */
1248 case 0x0310: /* GeForceFX 5600 */
1249 case 0x0320: /* GeForceFX 5200 */
1250 case 0x0330: /* GeForceFX 5900 */
1251 case 0x0340: /* GeForceFX 5700 */
1252 arch = NV_ARCH_30;
1253 break;
e40c6759
WS
1254 case 0x0040: /* GeForce 6800 */
1255 case 0x00C0: /* GeForce 6800 */
1256 case 0x0120: /* GeForce 6800 */
e40c6759
WS
1257 case 0x0140: /* GeForce 6600 */
1258 case 0x0160: /* GeForce 6200 */
1259 case 0x01D0: /* GeForce 7200, 7300, 7400 */
1260 case 0x0090: /* GeForce 7800 */
1261 case 0x0210: /* GeForce 6800 */
1262 case 0x0220: /* GeForce 6200 */
e40c6759
WS
1263 case 0x0240: /* GeForce 6100 */
1264 case 0x0290: /* GeForce 7900 */
1265 case 0x0390: /* GeForce 7600 */
ac1ae162 1266 case 0x03D0:
1da177e4
LT
1267 arch = NV_ARCH_40;
1268 break;
1269 case 0x0020: /* TNT, TNT2 */
1270 arch = NV_ARCH_04;
1271 break;
1272 default: /* unknown architecture */
1273 break;
1274 }
1275
1276 return arch;
1277}
1278
1279static int __devinit nvidiafb_probe(struct pci_dev *pd,
1280 const struct pci_device_id *ent)
1281{
1282 struct nvidia_par *par;
1283 struct fb_info *info;
1284 unsigned short cmd;
1285
1286
1287 NVTRACE_ENTER();
1288 assert(pd != NULL);
1289
1290 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1291
1292 if (!info)
1293 goto err_out;
1294
c439e345 1295 par = info->par;
1da177e4 1296 par->pci_dev = pd;
f5610b9c 1297 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
1da177e4
LT
1298
1299 if (info->pixmap.addr == NULL)
1300 goto err_out_kfree;
1301
1da177e4
LT
1302 if (pci_enable_device(pd)) {
1303 printk(KERN_ERR PFX "cannot enable PCI device\n");
1304 goto err_out_enable;
1305 }
1306
1307 if (pci_request_regions(pd, "nvidiafb")) {
1308 printk(KERN_ERR PFX "cannot request PCI regions\n");
a06630f3 1309 goto err_out_enable;
1da177e4
LT
1310 }
1311
1da177e4 1312 par->FlatPanel = flatpanel;
1da177e4
LT
1313 if (flatpanel == 1)
1314 printk(KERN_INFO PFX "flatpanel support enabled\n");
b8c49ef6 1315 par->FPDither = fpdither;
1da177e4
LT
1316
1317 par->CRTCnumber = forceCRTC;
1318 par->FpScale = (!noscale);
1319 par->paneltweak = paneltweak;
3c03ec20 1320 par->reverse_i2c = reverse_i2c;
1da177e4
LT
1321
1322 /* enable IO and mem if not already done */
1323 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1324 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1325 pci_write_config_word(pd, PCI_COMMAND, cmd);
1326
1327 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1328 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1329 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1330
1331 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1332
1333 if (!par->REGS) {
1334 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1335 goto err_out_free_base0;
1336 }
1337
c549dc64 1338 par->Chipset = nvidia_get_chipset(info);
c549dc64
AD
1339 par->Architecture = nvidia_get_arch(info);
1340
1341 if (par->Architecture == 0) {
1342 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1343 goto err_out_arch;
1344 }
1345
1346 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1347
918799ab
AD
1348 if (NVCommonSetup(info))
1349 goto err_out_arch;
1da177e4
LT
1350
1351 par->FbAddress = nvidiafb_fix.smem_start;
1352 par->FbMapSize = par->RamAmountKBytes * 1024;
917bb077
AD
1353 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1354 par->FbMapSize = vram * 1024 * 1024;
1355
1356 /* Limit amount of vram to 64 MB */
1357 if (par->FbMapSize > 64 * 1024 * 1024)
1358 par->FbMapSize = 64 * 1024 * 1024;
1359
0137ecfd
BH
1360 if(par->Architecture >= NV_ARCH_40)
1361 par->FbUsableSize = par->FbMapSize - (560 * 1024);
1362 else
1363 par->FbUsableSize = par->FbMapSize - (128 * 1024);
1da177e4
LT
1364 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1365 16 * 1024;
1366 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
0137ecfd
BH
1367 par->CursorStart = par->FbUsableSize + (32 * 1024);
1368
1da177e4 1369 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
917bb077
AD
1370 info->screen_size = par->FbUsableSize;
1371 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
1da177e4
LT
1372
1373 if (!info->screen_base) {
1374 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1375 goto err_out_free_base1;
1376 }
1377
1378 par->FbStart = info->screen_base;
1379
1380#ifdef CONFIG_MTRR
1381 if (!nomtrr) {
1382 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
917bb077
AD
1383 par->RamAmountKBytes * 1024,
1384 MTRR_TYPE_WRCOMB, 1);
1da177e4
LT
1385 if (par->mtrr.vram < 0) {
1386 printk(KERN_ERR PFX "unable to setup MTRR\n");
1387 } else {
1388 par->mtrr.vram_valid = 1;
1389 /* let there be speed */
1390 printk(KERN_INFO PFX "MTRR set to ON\n");
1391 }
1392 }
1393#endif /* CONFIG_MTRR */
1394
1395 info->fbops = &nvidia_fb_ops;
1396 info->fix = nvidiafb_fix;
1397
1398 if (nvidia_set_fbinfo(info) < 0) {
1399 printk(KERN_ERR PFX "error setting initial video mode\n");
1400 goto err_out_iounmap_fb;
1401 }
1402
1403 nvidia_save_vga(par, &par->SavedReg);
1404
ce38cac4 1405 pci_set_drvdata(pd, info);
202d4e60
RP
1406
1407 if (backlight)
1408 nvidia_bl_init(par);
1409
1da177e4
LT
1410 if (register_framebuffer(info) < 0) {
1411 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1412 goto err_out_iounmap_fb;
1413 }
1414
1da177e4
LT
1415
1416 printk(KERN_INFO PFX
1417 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1418 info->fix.id,
1419 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
5474c120 1420
1da177e4
LT
1421 NVTRACE_LEAVE();
1422 return 0;
1423
c549dc64 1424err_out_iounmap_fb:
1da177e4 1425 iounmap(info->screen_base);
c549dc64 1426err_out_free_base1:
1da177e4
LT
1427 fb_destroy_modedb(info->monspecs.modedb);
1428 nvidia_delete_i2c_busses(par);
c549dc64 1429err_out_arch:
1da177e4 1430 iounmap(par->REGS);
a06630f3 1431 err_out_free_base0:
1da177e4 1432 pci_release_regions(pd);
c549dc64 1433err_out_enable:
1da177e4 1434 kfree(info->pixmap.addr);
c549dc64 1435err_out_kfree:
1da177e4 1436 framebuffer_release(info);
c549dc64 1437err_out:
1da177e4
LT
1438 return -ENODEV;
1439}
1440
5e14ab8b 1441static void __devexit nvidiafb_remove(struct pci_dev *pd)
1da177e4
LT
1442{
1443 struct fb_info *info = pci_get_drvdata(pd);
1444 struct nvidia_par *par = info->par;
1445
1446 NVTRACE_ENTER();
1da177e4 1447
37ce69a5
RP
1448 unregister_framebuffer(info);
1449
5474c120
MH
1450 nvidia_bl_exit(par);
1451
1da177e4
LT
1452#ifdef CONFIG_MTRR
1453 if (par->mtrr.vram_valid)
1454 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1455 info->fix.smem_len);
1456#endif /* CONFIG_MTRR */
1457
1458 iounmap(info->screen_base);
1459 fb_destroy_modedb(info->monspecs.modedb);
1460 nvidia_delete_i2c_busses(par);
1461 iounmap(par->REGS);
1462 pci_release_regions(pd);
1da177e4
LT
1463 kfree(info->pixmap.addr);
1464 framebuffer_release(info);
1465 pci_set_drvdata(pd, NULL);
1466 NVTRACE_LEAVE();
1467}
1468
1469/* ------------------------------------------------------------------------- *
1470 *
1471 * initialization
1472 *
1473 * ------------------------------------------------------------------------- */
1474
1475#ifndef MODULE
1476static int __devinit nvidiafb_setup(char *options)
1477{
1478 char *this_opt;
1479
1480 NVTRACE_ENTER();
1481 if (!options || !*options)
1482 return 0;
1483
1484 while ((this_opt = strsep(&options, ",")) != NULL) {
1485 if (!strncmp(this_opt, "forceCRTC", 9)) {
1486 char *p;
1487
1488 p = this_opt + 9;
1489 if (!*p || !*(++p))
1490 continue;
1491 forceCRTC = *p - '0';
1492 if (forceCRTC < 0 || forceCRTC > 1)
1493 forceCRTC = -1;
1494 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1495 flatpanel = 1;
1496 } else if (!strncmp(this_opt, "hwcur", 5)) {
1497 hwcur = 1;
1498 } else if (!strncmp(this_opt, "noaccel", 6)) {
1499 noaccel = 1;
1500 } else if (!strncmp(this_opt, "noscale", 7)) {
1501 noscale = 1;
3c03ec20
AD
1502 } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
1503 reverse_i2c = 1;
1da177e4
LT
1504 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1505 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
917bb077
AD
1506 } else if (!strncmp(this_opt, "vram:", 5)) {
1507 vram = simple_strtoul(this_opt+5, NULL, 0);
202d4e60
RP
1508 } else if (!strncmp(this_opt, "backlight:", 10)) {
1509 backlight = simple_strtoul(this_opt+10, NULL, 0);
1da177e4
LT
1510#ifdef CONFIG_MTRR
1511 } else if (!strncmp(this_opt, "nomtrr", 6)) {
08346bf8 1512 nomtrr = true;
1da177e4 1513#endif
b8c49ef6
BH
1514 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1515 fpdither = simple_strtol(this_opt+9, NULL, 0);
ade9185a
AD
1516 } else if (!strncmp(this_opt, "bpp:", 4)) {
1517 bpp = simple_strtoul(this_opt+4, NULL, 0);
1da177e4
LT
1518 } else
1519 mode_option = this_opt;
1520 }
1521 NVTRACE_LEAVE();
1522 return 0;
1523}
1524#endif /* !MODULE */
1525
1526static struct pci_driver nvidiafb_driver = {
1527 .name = "nvidiafb",
1528 .id_table = nvidiafb_pci_tbl,
7a07cd78
AD
1529 .probe = nvidiafb_probe,
1530 .suspend = nvidiafb_suspend,
1531 .resume = nvidiafb_resume,
5e14ab8b 1532 .remove = __devexit_p(nvidiafb_remove),
1da177e4
LT
1533};
1534
1535/* ------------------------------------------------------------------------- *
1536 *
1537 * modularization
1538 *
1539 * ------------------------------------------------------------------------- */
1540
1541static int __devinit nvidiafb_init(void)
1542{
1543#ifndef MODULE
1544 char *option = NULL;
1545
1546 if (fb_get_options("nvidiafb", &option))
1547 return -ENODEV;
1548 nvidiafb_setup(option);
1549#endif
1550 return pci_register_driver(&nvidiafb_driver);
1551}
1552
1553module_init(nvidiafb_init);
1554
1da177e4
LT
1555static void __exit nvidiafb_exit(void)
1556{
1557 pci_unregister_driver(&nvidiafb_driver);
1558}
1559
1560module_exit(nvidiafb_exit);
1561
1562module_param(flatpanel, int, 0);
1563MODULE_PARM_DESC(flatpanel,
1564 "Enables experimental flat panel support for some chipsets. "
b8c49ef6
BH
1565 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1566module_param(fpdither, int, 0);
1567MODULE_PARM_DESC(fpdither,
1568 "Enables dithering of flat panel for 6 bits panels. "
1569 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1da177e4
LT
1570module_param(hwcur, int, 0);
1571MODULE_PARM_DESC(hwcur,
1572 "Enables hardware cursor implementation. (0 or 1=enabled) "
1573 "(default=0)");
1574module_param(noaccel, int, 0);
1575MODULE_PARM_DESC(noaccel,
1576 "Disables hardware acceleration. (0 or 1=disable) "
1577 "(default=0)");
1578module_param(noscale, int, 0);
1579MODULE_PARM_DESC(noscale,
1580 "Disables screen scaleing. (0 or 1=disable) "
1581 "(default=0, do scaling)");
1582module_param(paneltweak, int, 0);
1583MODULE_PARM_DESC(paneltweak,
1584 "Tweak display settings for flatpanels. "
1585 "(default=0, no tweaks)");
1586module_param(forceCRTC, int, 0);
1587MODULE_PARM_DESC(forceCRTC,
1588 "Forces usage of a particular CRTC in case autodetection "
1589 "fails. (0 or 1) (default=autodetect)");
917bb077
AD
1590module_param(vram, int, 0);
1591MODULE_PARM_DESC(vram,
1592 "amount of framebuffer memory to remap in MiB"
1593 "(default=0 - remap entire memory)");
c439e345
AD
1594module_param(mode_option, charp, 0);
1595MODULE_PARM_DESC(mode_option, "Specify initial video mode");
ade9185a
AD
1596module_param(bpp, int, 0);
1597MODULE_PARM_DESC(bpp, "pixel width in bits"
1598 "(default=8)");
3c03ec20
AD
1599module_param(reverse_i2c, int, 0);
1600MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
1da177e4 1601#ifdef CONFIG_MTRR
08346bf8 1602module_param(nomtrr, bool, false);
1da177e4
LT
1603MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1604 "(default=0)");
1605#endif
1606
1607MODULE_AUTHOR("Antonino Daplas");
1608MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1609MODULE_LICENSE("GPL");
This page took 0.903683 seconds and 5 git commands to generate.