diff options
-rw-r--r-- | drivers/video/savage/savagefb_driver.c | 209 |
1 files changed, 191 insertions, 18 deletions
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 267d4e5c9991..3bd0a573d755 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -305,7 +305,7 @@ savage2000_waitidle(struct savagefb_par *par) | |||
305 | while ((savage_in32(0x48C60, par) & 0x009fffff)); | 305 | while ((savage_in32(0x48C60, par) & 0x009fffff)); |
306 | } | 306 | } |
307 | 307 | ||
308 | 308 | #ifdef CONFIG_FB_SAVAGE_ACCEL | |
309 | static void | 309 | static void |
310 | SavageSetup2DEngine (struct savagefb_par *par) | 310 | SavageSetup2DEngine (struct savagefb_par *par) |
311 | { | 311 | { |
@@ -388,6 +388,22 @@ SavageSetup2DEngine (struct savagefb_par *par) | |||
388 | BCI_SEND( GlobalBitmapDescriptor ); | 388 | BCI_SEND( GlobalBitmapDescriptor ); |
389 | } | 389 | } |
390 | 390 | ||
391 | static void savagefb_set_clip(struct fb_info *info) | ||
392 | { | ||
393 | struct savagefb_par *par = info->par; | ||
394 | int cmd; | ||
395 | |||
396 | cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; | ||
397 | par->bci_ptr = 0; | ||
398 | par->SavageWaitFifo(par,3); | ||
399 | BCI_SEND(cmd); | ||
400 | BCI_SEND(BCI_CLIP_TL(0, 0)); | ||
401 | BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); | ||
402 | } | ||
403 | #else | ||
404 | static void SavageSetup2DEngine (struct savagefb_par *par) {} | ||
405 | |||
406 | #endif | ||
391 | 407 | ||
392 | static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, | 408 | static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, |
393 | int min_n2, int max_n2, long freq_min, | 409 | int min_n2, int max_n2, long freq_min, |
@@ -666,6 +682,159 @@ static void savage_get_default_par(struct savagefb_par *par, struct savage_reg * | |||
666 | vga_out8 (0x3d5, cr66, par); | 682 | vga_out8 (0x3d5, cr66, par); |
667 | } | 683 | } |
668 | 684 | ||
685 | static void savage_set_default_par(struct savagefb_par *par, | ||
686 | struct savage_reg *reg) | ||
687 | { | ||
688 | unsigned char cr3a, cr53, cr66; | ||
689 | |||
690 | vga_out16(0x3d4, 0x4838, par); | ||
691 | vga_out16(0x3d4, 0xa039, par); | ||
692 | vga_out16(0x3c4, 0x0608, par); | ||
693 | |||
694 | vga_out8(0x3d4, 0x66, par); | ||
695 | cr66 = vga_in8(0x3d5, par); | ||
696 | vga_out8(0x3d5, cr66 | 0x80, par); | ||
697 | vga_out8(0x3d4, 0x3a, par); | ||
698 | cr3a = vga_in8(0x3d5, par); | ||
699 | vga_out8(0x3d5, cr3a | 0x80, par); | ||
700 | vga_out8(0x3d4, 0x53, par); | ||
701 | cr53 = vga_in8(0x3d5, par); | ||
702 | vga_out8(0x3d5, cr53 & 0x7f, par); | ||
703 | |||
704 | vga_out8(0x3d4, 0x66, par); | ||
705 | vga_out8(0x3d5, cr66, par); | ||
706 | vga_out8(0x3d4, 0x3a, par); | ||
707 | vga_out8(0x3d5, cr3a, par); | ||
708 | |||
709 | vga_out8(0x3d4, 0x66, par); | ||
710 | vga_out8(0x3d5, cr66, par); | ||
711 | vga_out8(0x3d4, 0x3a, par); | ||
712 | vga_out8(0x3d5, cr3a, par); | ||
713 | |||
714 | /* unlock extended seq regs */ | ||
715 | vga_out8(0x3c4, 0x08, par); | ||
716 | vga_out8(0x3c5, reg->SR08, par); | ||
717 | vga_out8(0x3c5, 0x06, par); | ||
718 | |||
719 | /* now restore all the extended regs we need */ | ||
720 | vga_out8(0x3d4, 0x31, par); | ||
721 | vga_out8(0x3d5, reg->CR31, par); | ||
722 | vga_out8(0x3d4, 0x32, par); | ||
723 | vga_out8(0x3d5, reg->CR32, par); | ||
724 | vga_out8(0x3d4, 0x34, par); | ||
725 | vga_out8(0x3d5, reg->CR34, par); | ||
726 | vga_out8(0x3d4, 0x36, par); | ||
727 | vga_out8(0x3d5,reg->CR36, par); | ||
728 | vga_out8(0x3d4, 0x3a, par); | ||
729 | vga_out8(0x3d5, reg->CR3A, par); | ||
730 | vga_out8(0x3d4, 0x40, par); | ||
731 | vga_out8(0x3d5, reg->CR40, par); | ||
732 | vga_out8(0x3d4, 0x42, par); | ||
733 | vga_out8(0x3d5, reg->CR42, par); | ||
734 | vga_out8(0x3d4, 0x45, par); | ||
735 | vga_out8(0x3d5, reg->CR45, par); | ||
736 | vga_out8(0x3d4, 0x50, par); | ||
737 | vga_out8(0x3d5, reg->CR50, par); | ||
738 | vga_out8(0x3d4, 0x51, par); | ||
739 | vga_out8(0x3d5, reg->CR51, par); | ||
740 | vga_out8(0x3d4, 0x53, par); | ||
741 | vga_out8(0x3d5, reg->CR53, par); | ||
742 | vga_out8(0x3d4, 0x58, par); | ||
743 | vga_out8(0x3d5, reg->CR58, par); | ||
744 | vga_out8(0x3d4, 0x60, par); | ||
745 | vga_out8(0x3d5, reg->CR60, par); | ||
746 | vga_out8(0x3d4, 0x66, par); | ||
747 | vga_out8(0x3d5, reg->CR66, par); | ||
748 | vga_out8(0x3d4, 0x67, par); | ||
749 | vga_out8(0x3d5, reg->CR67, par); | ||
750 | vga_out8(0x3d4, 0x68, par); | ||
751 | vga_out8(0x3d5, reg->CR68, par); | ||
752 | vga_out8(0x3d4, 0x69, par); | ||
753 | vga_out8(0x3d5, reg->CR69, par); | ||
754 | vga_out8(0x3d4, 0x6f, par); | ||
755 | vga_out8(0x3d5, reg->CR6F, par); | ||
756 | |||
757 | vga_out8(0x3d4, 0x33, par); | ||
758 | vga_out8(0x3d5, reg->CR33, par); | ||
759 | vga_out8(0x3d4, 0x86, par); | ||
760 | vga_out8(0x3d5, reg->CR86, par); | ||
761 | vga_out8(0x3d4, 0x88, par); | ||
762 | vga_out8(0x3d5, reg->CR88, par); | ||
763 | vga_out8(0x3d4, 0x90, par); | ||
764 | vga_out8(0x3d5, reg->CR90, par); | ||
765 | vga_out8(0x3d4, 0x91, par); | ||
766 | vga_out8(0x3d5, reg->CR91, par); | ||
767 | vga_out8(0x3d4, 0xb0, par); | ||
768 | vga_out8(0x3d5, reg->CRB0, par); | ||
769 | |||
770 | /* extended mode timing regs */ | ||
771 | vga_out8(0x3d4, 0x3b, par); | ||
772 | vga_out8(0x3d5, reg->CR3B, par); | ||
773 | vga_out8(0x3d4, 0x3c, par); | ||
774 | vga_out8(0x3d5, reg->CR3C, par); | ||
775 | vga_out8(0x3d4, 0x43, par); | ||
776 | vga_out8(0x3d5, reg->CR43, par); | ||
777 | vga_out8(0x3d4, 0x5d, par); | ||
778 | vga_out8(0x3d5, reg->CR5D, par); | ||
779 | vga_out8(0x3d4, 0x5e, par); | ||
780 | vga_out8(0x3d5, reg->CR5E, par); | ||
781 | vga_out8(0x3d4, 0x65, par); | ||
782 | vga_out8(0x3d5, reg->CR65, par); | ||
783 | |||
784 | /* save seq extended regs for DCLK PLL programming */ | ||
785 | vga_out8(0x3c4, 0x0e, par); | ||
786 | vga_out8(0x3c5, reg->SR0E, par); | ||
787 | vga_out8(0x3c4, 0x0f, par); | ||
788 | vga_out8(0x3c5, reg->SR0F, par); | ||
789 | vga_out8(0x3c4, 0x10, par); | ||
790 | vga_out8(0x3c5, reg->SR10, par); | ||
791 | vga_out8(0x3c4, 0x11, par); | ||
792 | vga_out8(0x3c5, reg->SR11, par); | ||
793 | vga_out8(0x3c4, 0x12, par); | ||
794 | vga_out8(0x3c5, reg->SR12, par); | ||
795 | vga_out8(0x3c4, 0x13, par); | ||
796 | vga_out8(0x3c5, reg->SR13, par); | ||
797 | vga_out8(0x3c4, 0x29, par); | ||
798 | vga_out8(0x3c5, reg->SR29, par); | ||
799 | |||
800 | vga_out8(0x3c4, 0x15, par); | ||
801 | vga_out8(0x3c5, reg->SR15, par); | ||
802 | vga_out8(0x3c4, 0x30, par); | ||
803 | vga_out8(0x3c5, reg->SR30, par); | ||
804 | vga_out8(0x3c4, 0x18, par); | ||
805 | vga_out8(0x3c5, reg->SR18, par); | ||
806 | |||
807 | /* Save flat panel expansion regsters. */ | ||
808 | if (par->chip == S3_SAVAGE_MX) { | ||
809 | int i; | ||
810 | |||
811 | for (i = 0; i < 8; i++) { | ||
812 | vga_out8(0x3c4, 0x54+i, par); | ||
813 | vga_out8(0x3c5, reg->SR54[i], par); | ||
814 | } | ||
815 | } | ||
816 | |||
817 | vga_out8(0x3d4, 0x66, par); | ||
818 | cr66 = vga_in8(0x3d5, par); | ||
819 | vga_out8(0x3d5, cr66 | 0x80, par); | ||
820 | vga_out8(0x3d4, 0x3a, par); | ||
821 | cr3a = vga_in8(0x3d5, par); | ||
822 | vga_out8(0x3d5, cr3a | 0x80, par); | ||
823 | |||
824 | /* now save MIU regs */ | ||
825 | if (par->chip != S3_SAVAGE_MX) { | ||
826 | savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par); | ||
827 | savage_out32(MIU_CONTROL_REG, reg->MMPR1, par); | ||
828 | savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par); | ||
829 | savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par); | ||
830 | } | ||
831 | |||
832 | vga_out8(0x3d4, 0x3a, par); | ||
833 | vga_out8(0x3d5, cr3a, par); | ||
834 | vga_out8(0x3d4, 0x66, par); | ||
835 | vga_out8(0x3d5, cr66, par); | ||
836 | } | ||
837 | |||
669 | static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) | 838 | static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) |
670 | { | 839 | { |
671 | var->xres = var->xres_virtual = modedb->xres; | 840 | var->xres = var->xres_virtual = modedb->xres; |
@@ -1327,21 +1496,6 @@ static void savagefb_set_fix(struct fb_info *info) | |||
1327 | 1496 | ||
1328 | } | 1497 | } |
1329 | 1498 | ||
1330 | #if defined(CONFIG_FB_SAVAGE_ACCEL) | ||
1331 | static void savagefb_set_clip(struct fb_info *info) | ||
1332 | { | ||
1333 | struct savagefb_par *par = info->par; | ||
1334 | int cmd; | ||
1335 | |||
1336 | cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; | ||
1337 | par->bci_ptr = 0; | ||
1338 | par->SavageWaitFifo(par,3); | ||
1339 | BCI_SEND(cmd); | ||
1340 | BCI_SEND(BCI_CLIP_TL(0, 0)); | ||
1341 | BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); | ||
1342 | } | ||
1343 | #endif | ||
1344 | |||
1345 | static int savagefb_set_par (struct fb_info *info) | 1499 | static int savagefb_set_par (struct fb_info *info) |
1346 | { | 1500 | { |
1347 | struct savagefb_par *par = info->par; | 1501 | struct savagefb_par *par = info->par; |
@@ -1442,6 +1596,22 @@ static int savagefb_blank(int blank, struct fb_info *info) | |||
1442 | return (blank == FB_BLANK_NORMAL) ? 1 : 0; | 1596 | return (blank == FB_BLANK_NORMAL) ? 1 : 0; |
1443 | } | 1597 | } |
1444 | 1598 | ||
1599 | static void savagefb_save_state(struct fb_info *info) | ||
1600 | { | ||
1601 | struct savagefb_par *par = info->par; | ||
1602 | |||
1603 | savage_get_default_par(par, &par->save); | ||
1604 | } | ||
1605 | |||
1606 | static void savagefb_restore_state(struct fb_info *info) | ||
1607 | { | ||
1608 | struct savagefb_par *par = info->par; | ||
1609 | |||
1610 | savagefb_blank(FB_BLANK_POWERDOWN, info); | ||
1611 | savage_set_default_par(par, &par->save); | ||
1612 | savagefb_blank(FB_BLANK_UNBLANK, info); | ||
1613 | } | ||
1614 | |||
1445 | static struct fb_ops savagefb_ops = { | 1615 | static struct fb_ops savagefb_ops = { |
1446 | .owner = THIS_MODULE, | 1616 | .owner = THIS_MODULE, |
1447 | .fb_check_var = savagefb_check_var, | 1617 | .fb_check_var = savagefb_check_var, |
@@ -1449,6 +1619,8 @@ static struct fb_ops savagefb_ops = { | |||
1449 | .fb_setcolreg = savagefb_setcolreg, | 1619 | .fb_setcolreg = savagefb_setcolreg, |
1450 | .fb_pan_display = savagefb_pan_display, | 1620 | .fb_pan_display = savagefb_pan_display, |
1451 | .fb_blank = savagefb_blank, | 1621 | .fb_blank = savagefb_blank, |
1622 | .fb_save_state = savagefb_save_state, | ||
1623 | .fb_restore_state = savagefb_restore_state, | ||
1452 | #if defined(CONFIG_FB_SAVAGE_ACCEL) | 1624 | #if defined(CONFIG_FB_SAVAGE_ACCEL) |
1453 | .fb_fillrect = savagefb_fillrect, | 1625 | .fb_fillrect = savagefb_fillrect, |
1454 | .fb_copyarea = savagefb_copyarea, | 1626 | .fb_copyarea = savagefb_copyarea, |
@@ -2180,6 +2352,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) | |||
2180 | info->fbops->fb_sync(info); | 2352 | info->fbops->fb_sync(info); |
2181 | 2353 | ||
2182 | savagefb_blank(FB_BLANK_POWERDOWN, info); | 2354 | savagefb_blank(FB_BLANK_POWERDOWN, info); |
2355 | savage_set_default_par(par, &par->save); | ||
2183 | savage_disable_mmio(par); | 2356 | savage_disable_mmio(par); |
2184 | pci_save_state(dev); | 2357 | pci_save_state(dev); |
2185 | pci_disable_device(dev); | 2358 | pci_disable_device(dev); |
@@ -2219,9 +2392,9 @@ static int savagefb_resume (struct pci_dev* dev) | |||
2219 | pci_set_master(dev); | 2392 | pci_set_master(dev); |
2220 | savage_enable_mmio(par); | 2393 | savage_enable_mmio(par); |
2221 | savage_init_hw(par); | 2394 | savage_init_hw(par); |
2222 | savagefb_set_par (info); | 2395 | savagefb_set_par(info); |
2223 | savagefb_blank(FB_BLANK_UNBLANK, info); | ||
2224 | fb_set_suspend (info, 0); | 2396 | fb_set_suspend (info, 0); |
2397 | savagefb_blank(FB_BLANK_UNBLANK, info); | ||
2225 | release_console_sem(); | 2398 | release_console_sem(); |
2226 | 2399 | ||
2227 | return 0; | 2400 | return 0; |