aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/nvidia/nvidia.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/nvidia/nvidia.c')
-rw-r--r--drivers/video/nvidia/nvidia.c128
1 files changed, 95 insertions, 33 deletions
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 308defc389a2..0b40a2a721c1 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -411,6 +411,7 @@ MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
411 411
412/* command line data, set in nvidiafb_setup() */ 412/* command line data, set in nvidiafb_setup() */
413static int flatpanel __devinitdata = -1; /* Autodetect later */ 413static int flatpanel __devinitdata = -1; /* Autodetect later */
414static int fpdither __devinitdata = -1;
414static int forceCRTC __devinitdata = -1; 415static int forceCRTC __devinitdata = -1;
415static int hwcur __devinitdata = 0; 416static int hwcur __devinitdata = 0;
416static int noaccel __devinitdata = 0; 417static int noaccel __devinitdata = 0;
@@ -627,41 +628,85 @@ static void nvidia_save_vga(struct nvidia_par *par,
627 NVTRACE_LEAVE(); 628 NVTRACE_LEAVE();
628} 629}
629 630
631#undef DUMP_REG
632
630static void nvidia_write_regs(struct nvidia_par *par) 633static void nvidia_write_regs(struct nvidia_par *par)
631{ 634{
632 struct _riva_hw_state *state = &par->ModeReg; 635 struct _riva_hw_state *state = &par->ModeReg;
633 int i; 636 int i;
634 637
635 NVTRACE_ENTER(); 638 NVTRACE_ENTER();
636 NVWriteCrtc(par, 0x11, 0x00);
637
638 NVLockUnlock(par, 0);
639 639
640 NVLoadStateExt(par, state); 640 NVLoadStateExt(par, state);
641 641
642 NVWriteMiscOut(par, state->misc_output); 642 NVWriteMiscOut(par, state->misc_output);
643 643
644 for (i = 1; i < NUM_SEQ_REGS; i++) {
645#ifdef DUMP_REG
646 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
647#endif
648 NVWriteSeq(par, i, state->seq[i]);
649 }
650
651 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
652 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
653
644 for (i = 0; i < NUM_CRT_REGS; i++) { 654 for (i = 0; i < NUM_CRT_REGS; i++) {
645 switch (i) { 655 switch (i) {
646 case 0x19: 656 case 0x19:
647 case 0x20 ... 0x40: 657 case 0x20 ... 0x40:
648 break; 658 break;
649 default: 659 default:
660#ifdef DUMP_REG
661 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
662#endif
650 NVWriteCrtc(par, i, state->crtc[i]); 663 NVWriteCrtc(par, i, state->crtc[i]);
651 } 664 }
652 } 665 }
653 666
654 for (i = 0; i < NUM_ATC_REGS; i++) 667 for (i = 0; i < NUM_GRC_REGS; i++) {
655 NVWriteAttr(par, i, state->attr[i]); 668#ifdef DUMP_REG
656 669 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
657 for (i = 0; i < NUM_GRC_REGS; i++) 670#endif
658 NVWriteGr(par, i, state->gra[i]); 671 NVWriteGr(par, i, state->gra[i]);
672 }
673
674 for (i = 0; i < NUM_ATC_REGS; i++) {
675#ifdef DUMP_REG
676 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
677#endif
678 NVWriteAttr(par, i, state->attr[i]);
679 }
659 680
660 for (i = 0; i < NUM_SEQ_REGS; i++)
661 NVWriteSeq(par, i, state->seq[i]);
662 NVTRACE_LEAVE(); 681 NVTRACE_LEAVE();
663} 682}
664 683
684static void nvidia_vga_protect(struct nvidia_par *par, int on)
685{
686 unsigned char tmp;
687
688 if (on) {
689 /*
690 * Turn off screen and disable sequencer.
691 */
692 tmp = NVReadSeq(par, 0x01);
693
694 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
695 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
696 } else {
697 /*
698 * Reenable sequencer, then turn on screen.
699 */
700
701 tmp = NVReadSeq(par, 0x01);
702
703 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
704 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
705 }
706}
707
708
709
665static int nvidia_calc_regs(struct fb_info *info) 710static int nvidia_calc_regs(struct fb_info *info)
666{ 711{
667 struct nvidia_par *par = info->par; 712 struct nvidia_par *par = info->par;
@@ -868,7 +913,7 @@ static void nvidia_init_vga(struct fb_info *info)
868 for (i = 0; i < 0x10; i++) 913 for (i = 0; i < 0x10; i++)
869 state->attr[i] = i; 914 state->attr[i] = i;
870 state->attr[0x10] = 0x41; 915 state->attr[0x10] = 0x41;
871 state->attr[0x11] = 0x01; 916 state->attr[0x11] = 0xff;
872 state->attr[0x12] = 0x0f; 917 state->attr[0x12] = 0x0f;
873 state->attr[0x13] = 0x00; 918 state->attr[0x13] = 0x00;
874 state->attr[0x14] = 0x00; 919 state->attr[0x14] = 0x00;
@@ -982,16 +1027,24 @@ static int nvidiafb_set_par(struct fb_info *info)
982 NVTRACE_ENTER(); 1027 NVTRACE_ENTER();
983 1028
984 NVLockUnlock(par, 1); 1029 NVLockUnlock(par, 1);
985 if (!par->FlatPanel || (info->var.bits_per_pixel != 24) || 1030 if (!par->FlatPanel || !par->twoHeads)
986 !par->twoHeads)
987 par->FPDither = 0; 1031 par->FPDither = 0;
988 1032
1033 if (par->FPDither < 0) {
1034 if ((par->Chipset & 0x0ff0) == 0x0110)
1035 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
1036 & 0x00010000);
1037 else
1038 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
1039 printk(KERN_INFO PFX "Flat panel dithering %s\n",
1040 par->FPDither ? "enabled" : "disabled");
1041 }
1042
989 info->fix.visual = (info->var.bits_per_pixel == 8) ? 1043 info->fix.visual = (info->var.bits_per_pixel == 8) ?
990 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 1044 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
991 1045
992 nvidia_init_vga(info); 1046 nvidia_init_vga(info);
993 nvidia_calc_regs(info); 1047 nvidia_calc_regs(info);
994 nvidia_write_regs(par);
995 1048
996 NVLockUnlock(par, 0); 1049 NVLockUnlock(par, 0);
997 if (par->twoHeads) { 1050 if (par->twoHeads) {
@@ -1000,7 +1053,22 @@ static int nvidiafb_set_par(struct fb_info *info)
1000 NVLockUnlock(par, 0); 1053 NVLockUnlock(par, 0);
1001 } 1054 }
1002 1055
1003 NVWriteCrtc(par, 0x11, 0x00); 1056 nvidia_vga_protect(par, 1);
1057
1058 nvidia_write_regs(par);
1059
1060#if defined (__BIG_ENDIAN)
1061 /* turn on LFB swapping */
1062 {
1063 unsigned char tmp;
1064
1065 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1066 tmp = VGA_RD08(par->PCIO, 0x3d5);
1067 tmp |= (1 << 7);
1068 VGA_WR08(par->PCIO, 0x3d5, tmp);
1069 }
1070#endif
1071
1004 info->fix.line_length = (info->var.xres_virtual * 1072 info->fix.line_length = (info->var.xres_virtual *
1005 info->var.bits_per_pixel) >> 3; 1073 info->var.bits_per_pixel) >> 3;
1006 if (info->var.accel_flags) { 1074 if (info->var.accel_flags) {
@@ -1022,7 +1090,7 @@ static int nvidiafb_set_par(struct fb_info *info)
1022 1090
1023 par->cursor_reset = 1; 1091 par->cursor_reset = 1;
1024 1092
1025 NVWriteCrtc(par, 0x11, 0xff); 1093 nvidia_vga_protect(par, 0);
1026 1094
1027 NVTRACE_LEAVE(); 1095 NVTRACE_LEAVE();
1028 return 0; 1096 return 0;
@@ -1315,22 +1383,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1315 fb_var_to_videomode(&modedb, &nvidiafb_default_var); 1383 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1316 1384
1317 if (specs->modedb != NULL) { 1385 if (specs->modedb != NULL) {
1318 /* get preferred timing */ 1386 struct fb_videomode *modedb;
1319 if (specs->misc & FB_MISC_1ST_DETAIL) {
1320 int i;
1321
1322 for (i = 0; i < specs->modedb_len; i++) {
1323 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1324 modedb = specs->modedb[i];
1325 break;
1326 }
1327 }
1328 } else {
1329 /* otherwise, get first mode in database */
1330 modedb = specs->modedb[0];
1331 }
1332 1387
1333 fb_videomode_to_var(&nvidiafb_default_var, &modedb); 1388 modedb = fb_find_best_display(specs, &info->modelist);
1389 fb_videomode_to_var(&nvidiafb_default_var, modedb);
1334 nvidiafb_default_var.bits_per_pixel = 8; 1390 nvidiafb_default_var.bits_per_pixel = 8;
1335 } else if (par->fpWidth && par->fpHeight) { 1391 } else if (par->fpWidth && par->fpHeight) {
1336 char buf[16]; 1392 char buf[16];
@@ -1365,7 +1421,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1365 info->pixmap.flags = FB_PIXMAP_SYSTEM; 1421 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1366 1422
1367 if (!hwcur) 1423 if (!hwcur)
1368 info->fbops->fb_cursor = soft_cursor; 1424 info->fbops->fb_cursor = NULL;
1369 1425
1370 info->var.accel_flags = (!noaccel); 1426 info->var.accel_flags = (!noaccel);
1371 1427
@@ -1490,9 +1546,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1490 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); 1546 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1491 1547
1492 par->FlatPanel = flatpanel; 1548 par->FlatPanel = flatpanel;
1493
1494 if (flatpanel == 1) 1549 if (flatpanel == 1)
1495 printk(KERN_INFO PFX "flatpanel support enabled\n"); 1550 printk(KERN_INFO PFX "flatpanel support enabled\n");
1551 par->FPDither = fpdither;
1496 1552
1497 par->CRTCnumber = forceCRTC; 1553 par->CRTCnumber = forceCRTC;
1498 par->FpScale = (!noscale); 1554 par->FpScale = (!noscale);
@@ -1671,6 +1727,8 @@ static int __devinit nvidiafb_setup(char *options)
1671 } else if (!strncmp(this_opt, "nomtrr", 6)) { 1727 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1672 nomtrr = 1; 1728 nomtrr = 1;
1673#endif 1729#endif
1730 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1731 fpdither = simple_strtol(this_opt+9, NULL, 0);
1674 } else 1732 } else
1675 mode_option = this_opt; 1733 mode_option = this_opt;
1676 } 1734 }
@@ -1717,7 +1775,11 @@ module_exit(nvidiafb_exit);
1717module_param(flatpanel, int, 0); 1775module_param(flatpanel, int, 0);
1718MODULE_PARM_DESC(flatpanel, 1776MODULE_PARM_DESC(flatpanel,
1719 "Enables experimental flat panel support for some chipsets. " 1777 "Enables experimental flat panel support for some chipsets. "
1720 "(0 or 1=enabled) (default=0)"); 1778 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1779module_param(fpdither, int, 0);
1780MODULE_PARM_DESC(fpdither,
1781 "Enables dithering of flat panel for 6 bits panels. "
1782 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1721module_param(hwcur, int, 0); 1783module_param(hwcur, int, 0);
1722MODULE_PARM_DESC(hwcur, 1784MODULE_PARM_DESC(hwcur,
1723 "Enables hardware cursor implementation. (0 or 1=enabled) " 1785 "Enables hardware cursor implementation. (0 or 1=enabled) "