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.c84
1 files changed, 71 insertions, 13 deletions
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 308defc389a2..96d51144094a 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -627,41 +627,85 @@ static void nvidia_save_vga(struct nvidia_par *par,
627 NVTRACE_LEAVE(); 627 NVTRACE_LEAVE();
628} 628}
629 629
630#undef DUMP_REG
631
630static void nvidia_write_regs(struct nvidia_par *par) 632static void nvidia_write_regs(struct nvidia_par *par)
631{ 633{
632 struct _riva_hw_state *state = &par->ModeReg; 634 struct _riva_hw_state *state = &par->ModeReg;
633 int i; 635 int i;
634 636
635 NVTRACE_ENTER(); 637 NVTRACE_ENTER();
636 NVWriteCrtc(par, 0x11, 0x00);
637
638 NVLockUnlock(par, 0);
639 638
640 NVLoadStateExt(par, state); 639 NVLoadStateExt(par, state);
641 640
642 NVWriteMiscOut(par, state->misc_output); 641 NVWriteMiscOut(par, state->misc_output);
643 642
643 for (i = 1; i < NUM_SEQ_REGS; i++) {
644#ifdef DUMP_REG
645 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
646#endif
647 NVWriteSeq(par, i, state->seq[i]);
648 }
649
650 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
651 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
652
644 for (i = 0; i < NUM_CRT_REGS; i++) { 653 for (i = 0; i < NUM_CRT_REGS; i++) {
645 switch (i) { 654 switch (i) {
646 case 0x19: 655 case 0x19:
647 case 0x20 ... 0x40: 656 case 0x20 ... 0x40:
648 break; 657 break;
649 default: 658 default:
659#ifdef DUMP_REG
660 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
661#endif
650 NVWriteCrtc(par, i, state->crtc[i]); 662 NVWriteCrtc(par, i, state->crtc[i]);
651 } 663 }
652 } 664 }
653 665
654 for (i = 0; i < NUM_ATC_REGS; i++) 666 for (i = 0; i < NUM_GRC_REGS; i++) {
655 NVWriteAttr(par, i, state->attr[i]); 667#ifdef DUMP_REG
656 668 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
657 for (i = 0; i < NUM_GRC_REGS; i++) 669#endif
658 NVWriteGr(par, i, state->gra[i]); 670 NVWriteGr(par, i, state->gra[i]);
671 }
672
673 for (i = 0; i < NUM_ATC_REGS; i++) {
674#ifdef DUMP_REG
675 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
676#endif
677 NVWriteAttr(par, i, state->attr[i]);
678 }
659 679
660 for (i = 0; i < NUM_SEQ_REGS; i++)
661 NVWriteSeq(par, i, state->seq[i]);
662 NVTRACE_LEAVE(); 680 NVTRACE_LEAVE();
663} 681}
664 682
683static void nvidia_vga_protect(struct nvidia_par *par, int on)
684{
685 unsigned char tmp;
686
687 if (on) {
688 /*
689 * Turn off screen and disable sequencer.
690 */
691 tmp = NVReadSeq(par, 0x01);
692
693 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
694 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
695 } else {
696 /*
697 * Reenable sequencer, then turn on screen.
698 */
699
700 tmp = NVReadSeq(par, 0x01);
701
702 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
703 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
704 }
705}
706
707
708
665static int nvidia_calc_regs(struct fb_info *info) 709static int nvidia_calc_regs(struct fb_info *info)
666{ 710{
667 struct nvidia_par *par = info->par; 711 struct nvidia_par *par = info->par;
@@ -868,7 +912,7 @@ static void nvidia_init_vga(struct fb_info *info)
868 for (i = 0; i < 0x10; i++) 912 for (i = 0; i < 0x10; i++)
869 state->attr[i] = i; 913 state->attr[i] = i;
870 state->attr[0x10] = 0x41; 914 state->attr[0x10] = 0x41;
871 state->attr[0x11] = 0x01; 915 state->attr[0x11] = 0xff;
872 state->attr[0x12] = 0x0f; 916 state->attr[0x12] = 0x0f;
873 state->attr[0x13] = 0x00; 917 state->attr[0x13] = 0x00;
874 state->attr[0x14] = 0x00; 918 state->attr[0x14] = 0x00;
@@ -991,7 +1035,6 @@ static int nvidiafb_set_par(struct fb_info *info)
991 1035
992 nvidia_init_vga(info); 1036 nvidia_init_vga(info);
993 nvidia_calc_regs(info); 1037 nvidia_calc_regs(info);
994 nvidia_write_regs(par);
995 1038
996 NVLockUnlock(par, 0); 1039 NVLockUnlock(par, 0);
997 if (par->twoHeads) { 1040 if (par->twoHeads) {
@@ -1000,7 +1043,22 @@ static int nvidiafb_set_par(struct fb_info *info)
1000 NVLockUnlock(par, 0); 1043 NVLockUnlock(par, 0);
1001 } 1044 }
1002 1045
1003 NVWriteCrtc(par, 0x11, 0x00); 1046 nvidia_vga_protect(par, 1);
1047
1048 nvidia_write_regs(par);
1049
1050#if defined (__BIG_ENDIAN)
1051 /* turn on LFB swapping */
1052 {
1053 unsigned char tmp;
1054
1055 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1056 tmp = VGA_RD08(par->PCIO, 0x3d5);
1057 tmp |= (1 << 7);
1058 VGA_WR08(par->PCIO, 0x3d5, tmp);
1059 }
1060#endif
1061
1004 info->fix.line_length = (info->var.xres_virtual * 1062 info->fix.line_length = (info->var.xres_virtual *
1005 info->var.bits_per_pixel) >> 3; 1063 info->var.bits_per_pixel) >> 3;
1006 if (info->var.accel_flags) { 1064 if (info->var.accel_flags) {
@@ -1022,7 +1080,7 @@ static int nvidiafb_set_par(struct fb_info *info)
1022 1080
1023 par->cursor_reset = 1; 1081 par->cursor_reset = 1;
1024 1082
1025 NVWriteCrtc(par, 0x11, 0xff); 1083 nvidia_vga_protect(par, 0);
1026 1084
1027 NVTRACE_LEAVE(); 1085 NVTRACE_LEAVE();
1028 return 0; 1086 return 0;