comparison drivers/radeon/radeonfb.c @ 1915:31fdf7bb1a8e

A lot of VE related improvements and code cleanup
author nick
date Tue, 18 Sep 2001 16:28:30 +0000
parents 838bfa146fa3
children 7c36fd5e6d22
comparison
equal deleted inserted replaced
1914:838bfa146fa3 1915:31fdf7bb1a8e
9 * 2000-08-03 initial version 0.0.1 9 * 2000-08-03 initial version 0.0.1
10 * 2000-09-10 more bug fixes, public release 0.0.5 10 * 2000-09-10 more bug fixes, public release 0.0.5
11 * 2001-02-19 mode bug fixes, 0.0.7 11 * 2001-02-19 mode bug fixes, 0.0.7
12 * 2001-07-05 fixed scrolling issues, engine initialization, 12 * 2001-07-05 fixed scrolling issues, engine initialization,
13 * and minor mode tweaking, 0.0.9 13 * and minor mode tweaking, 0.0.9
14 * 2001-09-06 console switching fixes, blanking fixes,
15 * 0.1.0
16 * 14 *
17 * 2001-09-07 Radeon VE support 15 * 2001-09-07 Radeon VE support
18 * 2001-09-10 Radeon VE QZ support by Nick Kurshev <nickols_k@mail.ru> 16 * 2001-09-10 Radeon VE QZ support by Nick Kurshev <nickols_k@mail.ru>
19 * (limitations: on dualhead Radeons (VE, M6, M7) 17 * (limitations: on dualhead Radeons (VE, M6, M7)
20 * driver works only on second head (DVI port). 18 * driver works only on second head (DVI port).
24 * importing XFree86 code, which has ATI's support)., 22 * importing XFree86 code, which has ATI's support).,
25 * 0.0.11 23 * 0.0.11
26 * 2001-09-13 merge Ani Joshi radeonfb-0.1.0: 24 * 2001-09-13 merge Ani Joshi radeonfb-0.1.0:
27 * console switching fixes, blanking fixes, 25 * console switching fixes, blanking fixes,
28 * 0.1.0-ve.0 26 * 0.1.0-ve.0
27 * 2001-09-18 Radeon VE, M6 support (by Nick Kurshev <nickols_k@mail.ru>),
28 * Fixed bug of rom bios detection on VE (by NK),
29 * Minor code cleanup (by NK),
30 * Enable CRT port on VE (by NK),
31 * Disable SURFACE_CNTL because mplayer doesn't work
32 * propertly (by NK)
33 * 0.1.0-ve.1
29 * 34 *
30 * Special thanks to ATI DevRel team for their hardware donations. 35 * Special thanks to ATI DevRel team for their hardware donations.
31 * 36 *
32 */ 37 * LIMITATIONS: on dualhead Radeons (VE, M6, M7) driver doesn't work in
33 38 * dual monitor configuration. TVout is not supported too. M7 chips currently
34 39 * are not supported (Need volunteers to test its work). Probably these bugs
35 #define RADEON_VERSION "0.1.0-ve.0" 40 * can be solved by importing XFree86 code, which has ATI's support.
36 41 *
42 * Mini-HOWTO: This driver doesn't accept any options. It only switches your
43 * video card to graphics mode. Standard way to change video modes and other
44 * video attributes is using 'fbset' utility.
45 * Sample:
46 *
47 * #!/bin/sh
48 * fbset -fb /dev/fb0 -xres 640 -yres 480 -depth 32 -vxres 640 -vyres 480 -left 70 -right 50 -upper 70 -lower 70 -laced false -pixclock 39767
49 *
50 */
51
52 #define RADEON_VERSION "0.1.0-ve.1"
37 53
38 #include <linux/config.h> 54 #include <linux/config.h>
39 #include <linux/module.h> 55 #include <linux/module.h>
40 #include <linux/kernel.h> 56 #include <linux/kernel.h>
41 #include <linux/errno.h> 57 #include <linux/errno.h>
76 RADEON_QD, 92 RADEON_QD,
77 RADEON_QE, 93 RADEON_QE,
78 RADEON_QF, 94 RADEON_QF,
79 RADEON_QG, 95 RADEON_QG,
80 RADEON_QY, 96 RADEON_QY,
81 RADEON_QZ 97 RADEON_QZ,
98 RADEON_LY,
99 RADEON_LZ,
100 RADEON_LW
82 }; 101 };
83 102
103 enum radeon_montype
104 {
105 MT_NONE,
106 MT_CRT, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
107 MT_LCD, /* Liquid Crystal Display */
108 MT_DFP, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
109 MT_CTV, /* Composite TV out (not in VE) */
110 MT_STV /* S-Video TV out (probably in VE only) */
111 };
112
113 enum radeon_ddctype
114 {
115 DDC_NONE_DETECTED,
116 DDC_MONID,
117 DDC_DVI,
118 DDC_VGA,
119 DDC_CRT2
120 };
121
122 enum radeon_connectortype
123 {
124 CONNECTOR_NONE,
125 CONNECTOR_PROPRIETARY,
126 CONNECTOR_CRT,
127 CONNECTOR_DVI_I,
128 CONNECTOR_DVI_D
129 };
84 130
85 static struct pci_device_id radeonfb_pci_table[] __devinitdata = { 131 static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
86 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD}, 132 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
87 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE}, 133 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
88 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF}, 134 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
89 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG}, 135 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
90 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY}, 136 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
91 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ}, 137 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
138 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
139 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
140 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
92 { 0, } 141 { 0, }
93 }; 142 };
94 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table); 143 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
95 144
96 145
175 u32 pix_clock; 224 u32 pix_clock;
176 int xres, yres; 225 int xres, yres;
177 int bpp; 226 int bpp;
178 u32 crtc_gen_cntl; 227 u32 crtc_gen_cntl;
179 u32 crtc_ext_cntl; 228 u32 crtc_ext_cntl;
229 #if defined(__BIG_ENDIAN)
180 u32 surface_cntl; 230 u32 surface_cntl;
231 #endif
181 u32 dac_cntl; 232 u32 dac_cntl;
182 u32 dda_config; 233 u32 dda_config;
183 u32 dda_on_off; 234 u32 dda_on_off;
184 u32 ppll_div_3; 235 u32 ppll_div_3;
185 u32 ppll_ref_div; 236 u32 ppll_ref_div;
192 struct radeon_regs state; 243 struct radeon_regs state;
193 struct radeon_regs init_state; 244 struct radeon_regs init_state;
194 245
195 char name[14]; 246 char name[14];
196 char ram_type[12]; 247 char ram_type[12];
248
249 int hasCRTC2;
250 int crtDispType;
251 int dviDispType;
252 int hasTVout;
253 int isM7;
197 254
198 u32 mmio_base_phys; 255 u32 mmio_base_phys;
199 u32 fb_base_phys; 256 u32 fb_base_phys;
200 257
201 u32 mmio_base; 258 u32 mmio_base;
590 module_init(radeonfb_init); 647 module_init(radeonfb_init);
591 module_exit(radeonfb_exit); 648 module_exit(radeonfb_exit);
592 #endif 649 #endif
593 650
594 651
595 MODULE_AUTHOR("Ani Joshi"); 652 MODULE_AUTHOR("Ani Joshi. (Radeon VE extensions by Nick Kurshev)");
596 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset"); 653 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset. Ver: "RADEON_VERSION);
597 654
655 static char * GET_MON_NAME(int type)
656 {
657 char *pret;
658 switch(type)
659 {
660 case MT_NONE: pret = "no"; break;
661 case MT_CRT: pret = "CRT"; break;
662 case MT_DFP: pret = "DFP"; break;
663 case MT_LCD: pret = "LCD"; break;
664 case MT_CTV: pret = "CTV"; break;
665 case MT_STV: pret = "STV"; break;
666 default: pret = "Unknown";
667 }
668 return pret;
669 }
598 670
599 671
600 static int radeonfb_pci_register (struct pci_dev *pdev, 672 static int radeonfb_pci_register (struct pci_dev *pdev,
601 const struct pci_device_id *ent) 673 const struct pci_device_id *ent)
602 { 674 {
671 break; 743 break;
672 case PCI_DEVICE_ID_RADEON_QG: 744 case PCI_DEVICE_ID_RADEON_QG:
673 strcpy(rinfo->name, "Radeon QG "); 745 strcpy(rinfo->name, "Radeon QG ");
674 break; 746 break;
675 case PCI_DEVICE_ID_RADEON_QY: 747 case PCI_DEVICE_ID_RADEON_QY:
676 strcpy(rinfo->name, "Radeon VE QY"); 748 rinfo->hasCRTC2 = 1;
749 strcpy(rinfo->name, "Radeon VE QY ");
677 break; 750 break;
678 case PCI_DEVICE_ID_RADEON_QZ: 751 case PCI_DEVICE_ID_RADEON_QZ:
679 strcpy(rinfo->name, "Radeon VE QZ"); 752 rinfo->hasCRTC2 = 1;
753 strcpy(rinfo->name, "Radeon VE QZ ");
754 break;
755 case PCI_DEVICE_ID_RADEON_LY:
756 rinfo->hasCRTC2 = 1;
757 strcpy(rinfo->name, "Radeon M6 LY ");
758 break;
759 case PCI_DEVICE_ID_RADEON_LZ:
760 rinfo->hasCRTC2 = 1;
761 strcpy(rinfo->name, "Radeon M6 LZ ");
762 break;
763 case PCI_DEVICE_ID_RADEON_LW:
764 /* Note: Only difference between VE,M6 and M7 is initialization CRTC2
765 registers in dual monitor configuration!!! */
766 rinfo->hasCRTC2 = 1;
767 rinfo->isM7 = 1;
768 strcpy(rinfo->name, "Radeon M7 LW ");
680 break; 769 break;
681 default: 770 default:
771 release_mem_region (rinfo->mmio_base_phys,
772 pci_resource_len(pdev, 2));
773 release_mem_region (rinfo->fb_base_phys,
774 pci_resource_len(pdev, 0));
775 kfree (rinfo);
682 return -ENODEV; 776 return -ENODEV;
683 } 777 }
684 778
685 /* framebuffer size */ 779 /* framebuffer size */
686 tmp = INREG(CONFIG_MEMSIZE); 780 tmp = INREG(CONFIG_MEMSIZE);
740 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n", 834 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n",
741 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk); 835 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
742 836
743 RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024)); 837 RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
744 838
839 /*****
840 VE and M6 have both DVI and CRT ports (for M6 DVI port can be switch to
841 DFP port). The DVI port can also be conneted to a CRT with an adapter.
842 Here is the definition of ports for this driver---
843 (1) If both port are connected, DVI port will be treated as the Primary
844 port (uses CRTC1) and CRT port will be treated as the Secondary port
845 (uses CRTC2)
846 (2) If only one port is connected, it will treated as the Primary port
847 (??? uses CRTC1 ???)
848 *****/
849 if(rinfo->hasCRTC2) {
850 /* Using BIOS scratch registers works with for VE/M6,
851 no such registers in regular RADEON!!!*/
852 tmp = INREG(RADEON_BIOS_4_SCRATCH);
853 /*check Primary (DVI/DFP port)*/
854 if(tmp & 0x08) rinfo->dviDispType = MT_DFP;
855 else if(tmp & 0x04) rinfo->dviDispType = MT_LCD;
856 else if(tmp & 0x0200) rinfo->dviDispType = MT_CRT;
857 else if(tmp & 0x10) rinfo->dviDispType = MT_CTV;
858 else if(tmp & 0x20) rinfo->dviDispType = MT_STV;
859 /*check Secondary (CRT port).*/
860 if(tmp & 0x02) rinfo->crtDispType = MT_CRT;
861 else if(tmp & 0x800) rinfo->crtDispType = MT_DFP;
862 else if(tmp & 0x400) rinfo->crtDispType = MT_LCD;
863 else if(tmp & 0x1000) rinfo->crtDispType = MT_CTV;
864 else if(tmp & 0x2000) rinfo->crtDispType = MT_STV;
865 if(rinfo->dviDispType == MT_NONE &&
866 rinfo->crtDispType == MT_NONE) {
867 printk("radeonfb: No monitor detected!!!\n");
868 release_mem_region (rinfo->mmio_base_phys,
869 pci_resource_len(pdev, 2));
870 release_mem_region (rinfo->fb_base_phys,
871 pci_resource_len(pdev, 0));
872 kfree (rinfo);
873 return -ENODEV;
874 }
875 }
876 else {
877 /*Regular Radeon ASIC, only one CRTC, but it could be
878 used for DFP with a DVI output, like AIW board*/
879 rinfo->dviDispType = MT_NONE;
880 tmp = INREG(FP_GEN_CNTL);
881 if(tmp & FP_EN_TMDS) rinfo->crtDispType = MT_DFP;
882 else rinfo->crtDispType = MT_CRT;
883 }
884
885 if(bios_seg) {
886 /*
887 FIXME!!! TVout support currently is incomplete
888 On Radeon VE TVout is recognized as STV monitor on DVI port.
889 */
890 char * bios_ptr = bios_seg + 0x48L;
891 rinfo->hasTVout = readw(bios_ptr+0x32);
892 }
893
745 rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys, 894 rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
746 rinfo->video_ram); 895 rinfo->video_ram);
747 if (!rinfo->fb_base) { 896 if (!rinfo->fb_base) {
748 printk ("radeonfb: cannot map FB\n"); 897 printk ("radeonfb: cannot map FB\n");
749 iounmap ((void*)rinfo->mmio_base); 898 iounmap ((void*)rinfo->mmio_base);
791 if (!noaccel) { 940 if (!noaccel) {
792 /* initialize the engine */ 941 /* initialize the engine */
793 radeon_engine_init (rinfo); 942 radeon_engine_init (rinfo);
794 } 943 }
795 944
796 printk ("radeonfb: ATI %s %d MB\n", rinfo->name, 945 printk ("radeonfb: ATI %s %s %d MB\n",rinfo->name,rinfo->ram_type,
797 (rinfo->video_ram/(1024*1024))); 946 (rinfo->video_ram/(1024*1024)));
947 if(rinfo->hasCRTC2) {
948 printk("radeonfb: DVI port has %s monitor connected\n",GET_MON_NAME(rinfo->dviDispType));
949 printk("radeonfb: CRT port has %s monitor connected\n",GET_MON_NAME(rinfo->crtDispType));
950 }
951 else
952 printk("radeonfb: CRT port has %s monitor connected\n",GET_MON_NAME(rinfo->crtDispType));
953 printk("radeonfb: This card has %sTVout\n",rinfo->hasTVout ? "" : "no ");
798 954
799 return 0; 955 return 0;
800 } 956 }
801 957
802 958
831 #if defined(__i386__) 987 #if defined(__i386__)
832 u32 segstart; 988 u32 segstart;
833 char *rom_base; 989 char *rom_base;
834 char *rom; 990 char *rom;
835 int stage; 991 int stage;
836 int i; 992 int i,j;
837 char aty_rom_sig[] = "761295520"; 993 char aty_rom_sig[] = "761295520";
838 char radeon_sig[] = "RG6"; 994 char *radeon_sig[] = {
995 "RG6",
996 "RADEON"
997 };
839 998
840 for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) { 999 for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
841 stage = 1; 1000 stage = 1;
842 1001
843 rom_base = (char *)ioremap(segstart, 0x1000); 1002 rom_base = (char *)ioremap(segstart, 0x1000);
865 continue; 1024 continue;
866 } 1025 }
867 rom = rom_base; 1026 rom = rom_base;
868 1027
869 for (i = 0; (i < 512) && (stage != 4); i++) { 1028 for (i = 0; (i < 512) && (stage != 4); i++) {
870 if (radeon_sig[0] == *rom) 1029 for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) {
871 if (strncmp(radeon_sig, rom, 1030 if (radeon_sig[j][0] == *rom)
872 strlen(radeon_sig)) == 0) 1031 if (strncmp(radeon_sig[j], rom,
873 stage = 4; 1032 strlen(radeon_sig[j])) == 0) {
1033 stage = 4;
1034 break;
1035 }
1036 }
874 rom++; 1037 rom++;
875 } 1038 }
876 if (stage != 4) { 1039 if (stage != 4) {
877 iounmap(rom_base); 1040 iounmap(rom_base);
878 continue; 1041 continue;
1531 case VESA_POWERDOWN: 1694 case VESA_POWERDOWN:
1532 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | 1695 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
1533 CRTC_HSYNC_DIS); 1696 CRTC_HSYNC_DIS);
1534 break; 1697 break;
1535 } 1698 }
1536 1699 if(blank == VESA_NO_BLANKING && rinfo->hasCRTC2)
1537 OUTREG(CRTC_EXT_CNTL, val); 1700 OUTREGP(CRTC_EXT_CNTL,CRTC_CRT_ON, val);
1701 else OUTREG(CRTC_EXT_CNTL, val);
1538 } 1702 }
1539 1703
1540 1704
1541 1705
1542 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var) 1706 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
1767 hsync_fudge = hsync_adj_tab[format-1]; 1931 hsync_fudge = hsync_adj_tab[format-1];
1768 hsync_start = hSyncStart - 8 + hsync_fudge; 1932 hsync_start = hSyncStart - 8 + hsync_fudge;
1769 1933
1770 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | 1934 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
1771 (format << 8); 1935 (format << 8);
1772 1936 if(rinfo->hasCRTC2)
1773 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; 1937 /* HACKED: !!! Enable CRT port here !!! */
1774 1938 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
1939 else newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
1775 newmode.dac_cntl = INREG(DAC_CNTL) | DAC_MASK_ALL | DAC_VGA_ADR_EN | 1940 newmode.dac_cntl = INREG(DAC_CNTL) | DAC_MASK_ALL | DAC_VGA_ADR_EN |
1776 DAC_8BIT_EN; 1941 DAC_8BIT_EN;
1777 1942
1778 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) | 1943 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) |
1779 (((mode->xres / 8) - 1) << 16)); 1944 (((mode->xres / 8) - 1) << 16));
1787 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | 1952 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
1788 (vsync_wid << 16) | (v_sync_pol << 23)); 1953 (vsync_wid << 16) | (v_sync_pol << 23));
1789 1954
1790 newmode.crtc_pitch = (mode->xres >> 3); 1955 newmode.crtc_pitch = (mode->xres >> 3);
1791 1956
1957 #if defined(__BIG_ENDIAN)
1792 newmode.surface_cntl = SURF_TRANSLATION_DIS; 1958 newmode.surface_cntl = SURF_TRANSLATION_DIS;
1793 #if defined(__BIG_ENDIAN)
1794 switch (mode->bits_per_pixel) { 1959 switch (mode->bits_per_pixel) {
1795 case 16: 1960 case 16:
1796 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP; 1961 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
1797 break; 1962 break;
1798 case 24: 1963 case 24:
1888 (rinfo->ram.rloop << 20)); 2053 (rinfo->ram.rloop << 20));
1889 newmode.dda_on_off = (ron << 16) | roff; 2054 newmode.dda_on_off = (ron << 16) | roff;
1890 2055
1891 /* do it! */ 2056 /* do it! */
1892 radeon_write_mode (rinfo, &newmode); 2057 radeon_write_mode (rinfo, &newmode);
2058 /* XXX absurd hack for X to restore console on VE */
2059 if(rinfo->hasCRTC2 && rinfo->crtDispType == MT_CRT &&
2060 (rinfo->dviDispType == MT_NONE || rinfo->dviDispType == MT_STV)) {
2061 OUTREG(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl);
2062 OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
2063 }
1893 2064
1894 return; 2065 return;
1895 } 2066 }
1896 2067
1897 2068
2069 /*****
2070 When changing mode with Dual-head card (VE/M6), care must
2071 be taken for the special order in setting registers. CRTC2 has
2072 to be set before changing CRTC_EXT register.
2073 Otherwise we may get a blank screen.
2074 *****/
1898 2075
1899 static void radeon_write_mode (struct radeonfb_info *rinfo, 2076 static void radeon_write_mode (struct radeonfb_info *rinfo,
1900 struct radeon_regs *mode) 2077 struct radeon_regs *mode)
1901 { 2078 {
1902 int i; 2079 int i;
1916 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); 2093 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
1917 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); 2094 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
1918 OUTREG(CRTC_OFFSET, 0); 2095 OUTREG(CRTC_OFFSET, 0);
1919 OUTREG(CRTC_OFFSET_CNTL, 0); 2096 OUTREG(CRTC_OFFSET_CNTL, 0);
1920 OUTREG(CRTC_PITCH, mode->crtc_pitch); 2097 OUTREG(CRTC_PITCH, mode->crtc_pitch);
2098 #if defined(__BIG_ENDIAN)
2099 /* XXX this code makes degradation of mplayer quality on Radeon VE */
1921 OUTREG(SURFACE_CNTL, mode->surface_cntl); 2100 OUTREG(SURFACE_CNTL, mode->surface_cntl);
2101 #endif
2102 /* Here we should restore FP registers for LCD & DFP monitors */
1922 2103
1923 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) != 2104 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
1924 PPLL_DIV_SEL_MASK) { 2105 PPLL_DIV_SEL_MASK) {
1925 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff); 2106 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
1926 } 2107 }