aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/savage/savagefb_driver.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2006-06-26 03:26:24 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:28 -0400
commitf8020dc560fde089becc05de1d0ada1f7f46dc51 (patch)
tree20e0c20df709072838a554215fc608c3b3543244 /drivers/video/savage/savagefb_driver.c
parent2356614b08bf8769790c4f1f55c83d95f802bc51 (diff)
[PATCH] savagefb: Add state save and_restore hooks
Reported by: Rich (Bugzilla Bug 6417) "if savage driver is used in x.org together with savagefb, it results in seriously garbled and distorted screen - coupled with severe slowdowns." This bug is the result of Xorg unable to handle savagefb altering the hardware which results in X failing to start properly and/or failed console switching. Add savagefb_state_save and savagefb_state_restore. These hooks will only save and restore the extended VGA registers. Standard VGA registers will be left alone. This is enough to make savagefb play nicely with the latest Xorg savage driver, and perhaps with savage DRI. (Transient screen artifacts may appear before X loads and during console switches). (Unfortunately, blanking the screen also leaves Xorg in a blanked state, so I have to unblank the screen before Xorg loads. So I doubt if the transient screen artifacts will be completely invisible but hopefully it will only be for a shorter duration (not much).) [akpm@osdl.org: cleanups] Signed-off-by: Antonino Daplas <adaplas@pol.net> Cc: <rich@hq.vsaa.lv> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/savage/savagefb_driver.c')
-rw-r--r--drivers/video/savage/savagefb_driver.c209
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
309static void 309static void
310SavageSetup2DEngine (struct savagefb_par *par) 310SavageSetup2DEngine (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
391static 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
404static void SavageSetup2DEngine (struct savagefb_par *par) {}
405
406#endif
391 407
392static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, 408static 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
685static 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
669static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) 838static 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)
1331static 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
1345static int savagefb_set_par (struct fb_info *info) 1499static 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
1599static 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
1606static 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
1445static struct fb_ops savagefb_ops = { 1615static 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;