diff options
Diffstat (limited to 'drivers/video/nvidia/nvidia.c')
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 84 |
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 | |||
630 | static void nvidia_write_regs(struct nvidia_par *par) | 632 | static 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 | ||
683 | static 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 | |||
665 | static int nvidia_calc_regs(struct fb_info *info) | 709 | static 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; |