12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
17 #include <linux/slab.h>
21 #include <linux/pci.h>
29 #include <asm/pci-bridge.h>
31 #ifdef CONFIG_BOOTX_TEXT
32 #include <asm/btext.h>
40 #ifdef CONFIG_FB_NVIDIA_DEBUG
41 #define NVTRACE printk
43 #define NVTRACE if (0) printk
46 #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__)
47 #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__)
49 #ifdef CONFIG_FB_NVIDIA_DEBUG
50 #define assert(expr) \
52 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
53 #expr,__FILE__,__func__,__LINE__); \
60 #define PFX "nvidiafb: "
86 #ifdef CONFIG_PMAC_BACKLIGHT
123 static void nvidiafb_load_cursor_image(
struct nvidia_par *par,
u8 * data8,
132 for (i = 0; i <
h; i++) {
136 for (j = 0; j < w / 2; j++) {
138 #if defined (__BIG_ENDIAN)
139 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
141 tmp |= (b & (1 << 31)) ? fg :
bg;
144 tmp = (b & 1) ? fg : bg;
146 tmp |= (b & 1) ? fg << 16 : bg << 16;
155 static void nvidia_write_clut(
struct nvidia_par *par,
165 static void nvidia_read_clut(
struct nvidia_par *par,
175 static int nvidia_panel_tweak(
struct nvidia_par *par,
189 if(((par->
Chipset & 0xffff) == 0x0328) && (state->
bpp == 32)) {
194 if((par->
Chipset & 0xfff0) == 0x0310) {
203 static void nvidia_screen_off(
struct nvidia_par *par,
int on)
227 static void nvidia_save_vga(
struct nvidia_par *par,
255 static void nvidia_write_regs(
struct nvidia_par *par,
268 printk(
" SEQ[%02x] = %08x\n", i, state->
seq[i]);
283 printk(
"CRTC[%02x] = %08x\n", i, state->
crtc[i]);
291 printk(
" GRA[%02x] = %08x\n", i, state->
gra[i]);
298 printk(
"ATTR[%02x] = %08x\n", i, state->
attr[i]);
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;
336 v_start = v_total - 3;
339 h_start = h_total - 5;
341 h_blank_e = h_total + 4;
367 state->
crtc[0x13] = ((info->
var.xres_virtual / 8) *
368 (info->
var.bits_per_pixel / 8));
372 state->
attr[0x10] = 0x01;
375 state->
attr[0x11] = 0x00;
394 h_total = (h_total >> 1) & ~1;
424 info->
var.xres, info->
var.yres_virtual,
425 1000000000 / info->
var.pixclock, info->
var.vmode);
429 state->
pixel |= (1 << 7);
433 state->
scale |= (1 << 8);
441 par->
PanelTweak = nvidia_panel_tweak(par, state);
456 state->
pllsel |= 0x20000800;
475 if ((par->
Chipset & 0x0ff0) != 0x0110)
484 if ((par->
Chipset & 0x0ff0) == 0x0110) {
488 state->
dither |= 0x00010000;
503 static void nvidia_init_vga(
struct fb_info *info)
509 for (i = 0; i < 0x10; i++)
511 state->
attr[0x10] = 0x41;
512 state->
attr[0x11] = 0xff;
513 state->
attr[0x12] = 0x0f;
514 state->
attr[0x13] = 0x00;
515 state->
attr[0x14] = 0x00;
518 state->
crtc[0x0a] = 0x20;
519 state->
crtc[0x17] = 0xe3;
520 state->
crtc[0x18] = 0xff;
521 state->
crtc[0x28] = 0x40;
524 state->
gra[0x05] = 0x40;
525 state->
gra[0x06] = 0x05;
526 state->
gra[0x07] = 0x0f;
527 state->
gra[0x08] = 0xff;
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;
542 int i,
set = cursor->
set;
561 yy = cursor->
image.dy - info->
var.yoffset;
562 xx = cursor->
image.dx - info->
var.xoffset;
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;
581 switch (cursor->
rop) {
583 for (i = 0; i < s_pitch * cursor->
image.height; i++)
584 src[i] = dat[i] ^
msk[i];
588 for (i = 0; i < s_pitch * cursor->
image.height; i++)
589 src[i] = dat[i] &
msk[i];
594 cursor->
image.height);
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;
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;
606 nvidiafb_load_cursor_image(par, data, bg, fg,
608 cursor->
image.height);
619 static int nvidiafb_set_par(
struct fb_info *info)
630 if ((par->
Chipset & 0x0ff0) == 0x0110)
636 par->
FPDither ?
"enabled" :
"disabled");
639 info->
fix.visual = (info->
var.bits_per_pixel == 8) ?
642 nvidia_init_vga(info);
643 nvidia_calc_regs(info);
652 nvidia_screen_off(par, 1);
654 nvidia_write_regs(par, &par->
ModeReg);
657 #if defined (__BIG_ENDIAN)
669 info->
fix.line_length = (info->
var.xres_virtual *
670 info->
var.bits_per_pixel) >> 3;
671 if (info->
var.accel_flags) {
676 info->
pixmap.scan_align = 4;
685 info->
pixmap.scan_align = 1;
692 nvidia_screen_off(par, 0);
694 #ifdef CONFIG_BOOTX_TEXT
697 info->
var.xres, info->
var.yres,
698 info->
var.bits_per_pixel, info->
fix.line_length);
706 static int nvidiafb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
714 if (regno >= (1 << info->
var.green.length))
717 if (info->
var.grayscale) {
719 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
724 (regno << info->
var.red.offset) |
725 (regno << info->
var.green.offset) |
726 (regno << info->
var.blue.offset);
729 switch (info->
var.bits_per_pixel) {
732 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
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);
744 for (i = 0; i < 8; i++) {
745 nvidia_write_clut(par, regno * 8 + i,
746 red >> 8, green >> 8,
751 nvidia_read_clut(par, regno * 4, &r, &g, &b);
753 for (i = 0; i < 4; i++)
754 nvidia_write_clut(par, regno * 4 + i, r,
759 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
774 int memlen, vramlen, mode_valid = 0;
795 var->
green.offset = 0;
796 var->
green.length = 8;
797 var->
blue.offset = 0;
798 var->
blue.length = 8;
803 var->
green.length = (var->
green.length < 6) ? 5 : 6;
805 var->
blue.length = 5;
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;
813 var->
red.offset = 16;
815 var->
green.offset = 8;
816 var->
green.length = 8;
817 var->
blue.offset = 0;
818 var->
blue.length = 8;
824 var->
red.msb_right = 0;
825 var->
green.msb_right = 0;
826 var->
blue.msb_right = 0;
827 var->
transp.msb_right = 0;
834 if (!mode_valid && info->
monspecs.gtf) {
849 if (!mode_valid && info->
monspecs.modedb_len)
867 "panel dimensions\n");
886 if (memlen > vramlen) {
896 memlen = pitch * var->
yres;
899 printk(
"nvidiafb: required video memory, "
900 "%d bytes, for %dx%d-%d (virtual) "
936 static int nvidiafb_blank(
int blank,
struct fb_info *info)
939 unsigned char tmp, vesa;
999 #define save_vga_x86(x) do {} while (0)
1000 #define restore_vga_x86(x) do {} while (0)
1003 static int nvidiafb_open(
struct fb_info *info,
int user)
1016 static int nvidiafb_release(
struct fb_info *info,
int user)
1036 static struct fb_ops nvidia_fb_ops = {
1038 .fb_open = nvidiafb_open,
1039 .fb_release = nvidiafb_release,
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,
1048 .fb_cursor = nvidiafb_cursor,
1055 struct fb_info *info = pci_get_drvdata(dev);
1066 nvidia_write_regs(par, &par->
SavedReg);
1071 dev->
dev.power.power_state = mesg;
1079 struct fb_info *info = pci_get_drvdata(dev);
1095 nvidiafb_set_par(info);
1104 #define nvidiafb_suspend NULL
1105 #define nvidiafb_resume NULL
1157 info->
var = nvidiafb_default_var;
1158 info->
fix.visual = (info->
var.bits_per_pixel == 8) ?
1166 lpitch = info->
var.xres_virtual *
1167 ((info->
var.bits_per_pixel + 7) >> 3);
1170 info->
pixmap.scan_align = 4;
1171 info->
pixmap.buf_align = 4;
1172 info->
pixmap.access_align = 32;
1173 info->
pixmap.size = 8 * 1024;
1179 info->
var.accel_flags = (!noaccel);
1201 return nvidiafb_check_var(&info->
var, info);
1211 if ((
id & 0xfff0) == 0x00f0 ||
1212 (
id & 0xfff0) == 0x02e0) {
1216 if ((
id & 0x0000ffff) == 0x000010DE)
1217 id = 0x10DE0000 | (
id >> 16);
1218 else if ((
id & 0xffff0000) == 0xDE100000)
1219 id = 0x10DE0000 | ((
id << 8) & 0x0000ff00) |
1220 ((
id >> 8) & 0x000000ff);
1232 switch (par->
Chipset & 0x0ff0) {
1304 goto err_out_enable;
1309 goto err_out_enable;
1335 goto err_out_free_base0;
1338 par->
Chipset = nvidia_get_chipset(info);
1353 if (vram && vram * 1024 * 1024 < par->
FbMapSize)
1375 goto err_out_free_base1;
1385 if (par->mtrr.vram < 0) {
1388 par->mtrr.vram_valid = 1;
1395 info->
fbops = &nvidia_fb_ops;
1396 info->
fix = nvidiafb_fix;
1398 if (nvidia_set_fbinfo(info) < 0) {
1400 goto err_out_iounmap_fb;
1403 nvidia_save_vga(par, &par->
SavedReg);
1405 pci_set_drvdata(pd, info);
1412 goto err_out_iounmap_fb;
1417 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1443 struct fb_info *info = pci_get_drvdata(pd);
1453 if (par->mtrr.vram_valid)
1455 info->
fix.smem_len);
1465 pci_set_drvdata(pd,
NULL);
1481 if (!options || !*options)
1484 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
1485 if (!
strncmp(this_opt,
"forceCRTC", 9)) {
1492 if (forceCRTC < 0 || forceCRTC > 1)
1494 }
else if (!
strncmp(this_opt,
"flatpanel", 9)) {
1496 }
else if (!
strncmp(this_opt,
"hwcur", 5)) {
1498 }
else if (!
strncmp(this_opt,
"noaccel", 6)) {
1500 }
else if (!
strncmp(this_opt,
"noscale", 7)) {
1502 }
else if (!
strncmp(this_opt,
"reverse_i2c", 11)) {
1504 }
else if (!
strncmp(this_opt,
"paneltweak:", 11)) {
1506 }
else if (!
strncmp(this_opt,
"vram:", 5)) {
1508 }
else if (!
strncmp(this_opt,
"backlight:", 10)) {
1511 }
else if (!
strncmp(this_opt,
"nomtrr", 6)) {
1514 }
else if (!
strncmp(this_opt,
"fpdither:", 9)) {
1516 }
else if (!
strncmp(this_opt,
"bpp:", 4)) {
1519 mode_option = this_opt;
1528 .id_table = nvidiafb_pci_tbl,
1529 .probe = nvidiafb_probe,
1541 static int __devinit nvidiafb_init(
void)
1548 nvidiafb_setup(option);
1550 return pci_register_driver(&nvidiafb_driver);
1555 static void __exit nvidiafb_exit(
void)
1564 "Enables experimental flat panel support for some chipsets. "
1565 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1568 "Enables dithering of flat panel for 6 bits panels. "
1569 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1572 "Enables hardware cursor implementation. (0 or 1=enabled) "
1576 "Disables hardware acceleration. (0 or 1=disable) "
1580 "Disables screen scaleing. (0 or 1=disable) "
1581 "(default=0, do scaling)");
1584 "Tweak display settings for flatpanels. "
1585 "(default=0, no tweaks)");
1588 "Forces usage of a particular CRTC in case autodetection "
1589 "fails. (0 or 1) (default=autodetect)");
1592 "amount of framebuffer memory to remap in MiB"
1593 "(default=0 - remap entire memory)");