aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/sis
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/sis')
-rw-r--r--drivers/video/fbdev/sis/300vtbl.h1072
-rw-r--r--drivers/video/fbdev/sis/310vtbl.h1339
-rw-r--r--drivers/video/fbdev/sis/Makefile7
-rw-r--r--drivers/video/fbdev/sis/init.c3655
-rw-r--r--drivers/video/fbdev/sis/init.h1541
-rw-r--r--drivers/video/fbdev/sis/init301.c11071
-rw-r--r--drivers/video/fbdev/sis/init301.h456
-rw-r--r--drivers/video/fbdev/sis/initdef.h708
-rw-r--r--drivers/video/fbdev/sis/initextlfb.c231
-rw-r--r--drivers/video/fbdev/sis/oem300.h840
-rw-r--r--drivers/video/fbdev/sis/oem310.h430
-rw-r--r--drivers/video/fbdev/sis/sis.h586
-rw-r--r--drivers/video/fbdev/sis/sis_accel.c423
-rw-r--r--drivers/video/fbdev/sis/sis_accel.h400
-rw-r--r--drivers/video/fbdev/sis/sis_main.c6844
-rw-r--r--drivers/video/fbdev/sis/sis_main.h781
-rw-r--r--drivers/video/fbdev/sis/vgatypes.h97
-rw-r--r--drivers/video/fbdev/sis/vstruct.h551
18 files changed, 31032 insertions, 0 deletions
diff --git a/drivers/video/fbdev/sis/300vtbl.h b/drivers/video/fbdev/sis/300vtbl.h
new file mode 100644
index 000000000000..e4b4a2626da4
--- /dev/null
+++ b/drivers/video/fbdev/sis/300vtbl.h
@@ -0,0 +1,1072 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Register settings for SiS 300 series
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const struct SiS_Ext SiS300_EModeIDTable[] =
54{
55 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */
56 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
57 {0x2f,0x021b,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x8 */
58 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1},
59 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x8 */
60 {0x32,0x6a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x8 */
61 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x16 */
62 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x16 */
63 {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x32 */
64 {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x32 */
65 {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x? */
66 {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x8 */
67 {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1}, /* 1280x1024x8 */
68 {0x3c,0x063b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
69 {0x3d,0x067d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
70 {0x40,0x921c,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x15 */
71 {0x41,0x921d,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x16 */
72 {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
73 {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
74 {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x15 */
75 {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x16 */
76 {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
77 {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
78 {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
79 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
80 {0x50,0x921b,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x8 */
81 {0x51,0xb21b,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x8 */
82 {0x52,0x921b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x8 */
83 {0x56,0x921d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x16 */
84 {0x57,0xb21d,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x16 */
85 {0x58,0x921d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x16 */
86 {0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */
87 {0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */
88 {0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */
89 {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
90 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
91 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */
92 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
93 {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
94 {0x66,0x06ff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
95 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
96 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
97 {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
98 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 */
99 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 */
100 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */
101 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */
102 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */
103 {0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x16 */
104 {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x32 */
105 {0x77,0x4a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x32 */
106 {0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x32 */
107 {0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x8 */
108 {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x16 */
109 {0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x8 */
110 {0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x16 */
111 {0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x32 */
112 {0x20,0x4a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1}, /* 1024x600 */
113 {0x21,0x4a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
114 {0x22,0x4a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
115 {0x23,0x4a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1}, /* 1152x768 */
116 {0x24,0x4a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
117 {0x25,0x4a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
118 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1}, /* 1152x864 */
119 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
120 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
121 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1}, /* 848x480 */
122 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1},
123 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1},
124 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1}, /* 856x480 */
125 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1},
126 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1},
127 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1360x768 */
128 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
129 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
130 {0x4f,0x921f,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x32 */
131 {0x53,0x921f,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x32 */
132 {0x54,0xb21f,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x32 */
133 {0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1}, /* 1280x768 */
134 {0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
135 {0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
136 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x8 */
137 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x16 */
138 {0x61,0x6a1f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x32 */
139 {0x67,0x6e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x8 (BARCO) */
140 {0x6f,0x6e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x16 (BARCO) */
141 {0x72,0x6eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x32 (BARCO) */
142 {0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
143};
144
145static const struct SiS_Ext2 SiS300_RefIndex[] =
146{
147 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 00 */
148 {0x0467,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 01 */
149 {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 02 - CRT1CRTC was 0x4f */
150 {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 03 */
151 {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 04 */
152 {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 05 */
153 {0x0047,0x11,0x0e,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 06 - CRT1CRTC was 0x51 */
154 {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 07 */
155 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 08 */
156 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 09 */
157 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0a */
158 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0b */
159 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0c */
160 {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0d */
161 {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0e */
162 {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0f */
163 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0, 0x4a, 0x49}, /* 10 */
164 {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0, 0x00, 0x00}, /* 11 */
165 {0x006f,0x32,0x4a,0x06,0x14,0x32, 720, 576, 0, 0x00, 0x00}, /* 12 */ /* 4a was 03 */
166 {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 13 */
167 {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 14 */
168 {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 15 - CRT1CRTC was 0x97 */
169 {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 16 */
170 {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 17 - CRT1CRTC was 0x59 */
171 {0x0047,0x1a,0x12,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 18 */
172 {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 19 - CRT1CRTC was 0x5b */
173 {0x0387,0x1c,0x0d,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1a - CRT1CRTC was 0x5c */
174 {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1b */
175 {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1c */
176 {0x0007,0x1f,0x18,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1d */
177 {0x0007,0x20,0x19,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1e - CRT1CRTC was 0x60 */
178 {0x0007,0x21,0x1a,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1f */
179 {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 20 */
180 {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 21 - CRT1CRTC was 0x63 */
181 {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 22 */
182 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0, 0x4b, 0x4b}, /* 23 */
183 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0, 0x00, 0x00}, /* 24 */
184 {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0, 0x00, 0x00}, /* 25 */
185 {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0, 0x00, 0x00}, /* 26 */ /* was c077 */
186 {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0, 0x00, 0x00}, /* 27 */
187 {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0, 0x00, 0x00}, /* 28 */
188 {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 29 - 1280x960-60 */
189 {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 2a - 1280x960-85 */
190 {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0, 0x00, 0x00}, /* 2b */
191 {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0, 0x00, 0x00}, /* 2c */ /* VCLK 0x09 */
192 {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2d */
193 {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2e */
194 {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2f */
195 {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 30 */
196 {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 31 */
197 {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 32 */
198 {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 33 */
199 {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 34 */
200 {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 35 */
201 {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 36 1152x864-60Hz */
202 {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 37 1152x864-75Hz */
203 {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 38 1152x864-85Hz */
204 {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 39 848x480-38Hzi */
205 {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 3a 848x480-60Hz */
206 {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3b 856x480-38Hzi */
207 {0xc067,0x42,0x28,0x0c,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3c 856x480-60Hz */
208 {0x0067,0x43,0x3e,0x0d,0x1b,0x48,1360, 768, 0, 0x00, 0x00}, /* 3d 1360x768-60Hz */
209 {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0, 0x00, 0x00}, /* 3e 1280x768-60Hz */
210 {0x006f,0x47,0x4c,0x06,0x15,0x5f, 768, 576, 0, 0x00, 0x00}, /* 3f 768x576 */
211 {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0, 0x00, 0x00}, /* 40 1360x1024-59Hz (BARCO1366 only) */
212 {0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00}
213};
214
215static const struct SiS_VBMode SiS300_VBModeIDTable[] =
216{
217 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
218 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
219 {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
220 {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
221 {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01},
222 {0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
223 {0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
224 {0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
225 {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01},
226 {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
227 {0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
228 {0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
229 {0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
230 {0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
231 {0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
232 {0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
233 {0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00},
234 {0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
235 {0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
236 {0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
237 {0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
238 {0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
239 {0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
240 {0x33,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
241 {0x34,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
242 {0x35,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
243 {0x36,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
244 {0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
245 {0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
246 {0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
247 {0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
248 {0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
249 {0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
250 {0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
251 {0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
252 {0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
253 {0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
254 {0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
255 {0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
256 {0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
257 {0x4f,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
258 {0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
259 {0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
260 {0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
261 {0x53,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
262 {0x54,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
263 {0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
264 {0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
265 {0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
266 {0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
267 {0x5c,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
268 {0x5d,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
269 {0x5e,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
270 {0x5f,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
271 {0x60,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
272 {0x61,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
273 {0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
274 {0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
275 {0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
276 {0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
277 {0x6c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
278 {0x6d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
279 {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
280};
281
282static const struct SiS_CRT1Table SiS300_CRT1Table[] =
283{
284 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
285 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
286 0x00}},
287 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */
288 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
289 0x00}},
290 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */
291 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
292 0x01}},
293 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
294 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
295 0x01}},
296 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
297 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
298 0x00}},
299 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
300 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
301 0x00}},
302 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
303 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
304 0x00}},
305 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
306 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
307 0x00}},
308 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
309 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
310 0x00}},
311 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */
312 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
313 0x00}},
314 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */
315 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
316 0x00}},
317 {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
318 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
319 0x00}},
320 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
321 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
322 0x00}},
323 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
324 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
325 0x01}},
326 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
327 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
328 0x01}},
329 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
330 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
331 0x01}},
332 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
333 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
334 0x01}},
335 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
336 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
337 0x01}},
338 {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0,
339 0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06,
340 0x01}},
341 {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,
342 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
343 0x01}},
344 {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0, /* 0x14 */
345 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
346 0x01}},
347 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
348 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
349 0x00}},
350 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
351 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
352 0x01}},
353 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
354 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
355 0x01}},
356 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
357 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
358 0x01}},
359 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
360 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
361 0x01}},
362 {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5, /* 0x1a */
363 0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
364 0x01}},
365 {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
366 0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02,
367 0x01}},
368 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
369 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
370 0x00}},
371 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
372 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
373 0x01}},
374 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, /* 0x1e */
375 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
376 0x01}},
377 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
378 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
379 0x01}},
380 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
381 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
382 0x00}},
383 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
384 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
385 0x00}},
386 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
387 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
388 0x00}},
389 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
390 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
391 0x00}},
392 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, /* 36: 1600x1200x85Hz */
393 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
394 0x00}},
395 {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f, /* 37: 1920x1440x60Hz */
396 0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01,
397 0x00}},
398 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
399 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
400 0x00}},
401 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */
402 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
403 0x01}},
404 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x28 */
405 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
406 0x01}},
407 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
408 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
409 0x01}},
410 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
411 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
412 0x01}},
413 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
414 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
415 0x01}},
416 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
417 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
418 0x01}},
419 {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
420 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
421 0x01}},
422 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
423 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
424 0x01}},
425 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
426 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
427 0x01}},
428 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
429 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
430 0x01}},
431 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
432 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
433 0x00}},
434 {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 0x32: 720x576, corrected to 60Hz */
435 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
436 0x41}},
437 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
438 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
439 0x01}},
440 {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - corrected */
441 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
442 0x01}},
443 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 */
444 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
445 0x01}}, /* 0x35 */
446 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
447 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
448 0x01}}, /* 0x36 */
449 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
450 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
451 0x01}}, /* 0x37 */
452 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
453 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
454 0x01}}, /* 0x38 */
455 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
456 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
457 0x01}}, /* 0x39 */
458 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
459 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
460 0x01}}, /* 0x3a */
461 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
462 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
463 0x01}}, /* 0x3b */
464 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
465 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
466 0x01}}, /* 0x3c */
467 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
468 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
469 0x01}}, /* 0x3d */
470 {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
471 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
472 0x01}}, /* 0x3e */
473 {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
474 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
475 0x00}}, /* 0x3f */
476 {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
477 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
478 0x00}}, /* 0x40 */
479 {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
480 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
481 0x00}}, /* 0x41 */
482 {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
483 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
484 0x00}}, /* 0x42 */
485 {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
486 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
487 0x01}}, /* 0x43 */
488 {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
489 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
490 0x01}}, /* 0x44 */
491 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
492 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
493 0x01}}, /* 0x45 */
494 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */
495 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
496 0x01}}, /* 0x46 */
497 {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
498 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
499 0x41}}, /* 0x47 */
500 {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */
501 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
502 0x00}}, /* 0x48 */
503 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
504 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
505 0x41}}, /* 0x49 */
506 {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
507 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
508 0x40}}, /* 0x4a */
509 {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
510 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
511 0x00}} /* 0x4b */
512};
513
514static const struct SiS_MCLKData SiS300_MCLKData_630[] =
515{
516 { 0x5a,0x64,0x80, 66},
517 { 0xb3,0x45,0x80, 83},
518 { 0x37,0x61,0x80,100},
519 { 0x37,0x22,0x80,133},
520 { 0x37,0x61,0x80,100},
521 { 0x37,0x61,0x80,100},
522 { 0x37,0x61,0x80,100},
523 { 0x37,0x61,0x80,100}
524};
525
526static const struct SiS_MCLKData SiS300_MCLKData_300[] =
527{
528 { 0x68,0x43,0x80,125},
529 { 0x68,0x43,0x80,125},
530 { 0x68,0x43,0x80,125},
531 { 0x37,0x61,0x80,100},
532 { 0x37,0x61,0x80,100},
533 { 0x37,0x61,0x80,100},
534 { 0x37,0x61,0x80,100},
535 { 0x37,0x61,0x80,100}
536};
537
538static struct SiS_VCLKData SiS300_VCLKData[] =
539{
540 { 0x1b,0xe1, 25}, /* 0x00 */
541 { 0x4e,0xe4, 28}, /* 0x01 */
542 { 0x57,0xe4, 32}, /* 0x02 */
543 { 0xc3,0xc8, 36}, /* 0x03 */
544 { 0x42,0xc3, 40}, /* 0x04 */
545 { 0x5d,0xc4, 45}, /* 0x05 */
546 { 0x52,0x65, 50}, /* 0x06 */
547 { 0x53,0x65, 50}, /* 0x07 */
548 { 0x6d,0x66, 56}, /* 0x08 */
549 { 0x5a,0x64, 65}, /* 0x09 */
550 { 0x46,0x44, 68}, /* 0x0a */
551 { 0x3e,0x43, 75}, /* 0x0b */
552 { 0x6d,0x46, 76}, /* 0x0c */ /* 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */
553 { 0x41,0x43, 79}, /* 0x0d */
554 { 0x31,0x42, 79}, /* 0x0e */
555 { 0x46,0x25, 85}, /* 0x0f */
556 { 0x78,0x29, 87}, /* 0x10 */
557 { 0x62,0x44, 95}, /* 0x11 */
558 { 0x2b,0x22,105}, /* 0x12 */
559 { 0x49,0x24,106}, /* 0x13 */
560 { 0xc3,0x28,108}, /* 0x14 */
561 { 0x3c,0x23,109}, /* 0x15 */
562 { 0xf7,0x2c,132}, /* 0x16 */
563 { 0xd4,0x28,136}, /* 0x17 */
564 { 0x41,0x05,158}, /* 0x18 */
565 { 0x43,0x05,162}, /* 0x19 */
566 { 0xe1,0x0f,175}, /* 0x1a */
567 { 0xfc,0x12,189}, /* 0x1b */
568 { 0xde,0x26,194}, /* 0x1c */
569 { 0x54,0x05,203}, /* 0x1d */
570 { 0x3f,0x03,230}, /* 0x1e */
571 { 0x30,0x02,234}, /* 0x1f */
572 { 0x24,0x01,266}, /* 0x20 */
573 { 0x52,0x2a, 54}, /* 0x21 */ /* 301 TV */
574 { 0x52,0x6a, 27}, /* 0x22 */ /* 301 TV */
575 { 0x62,0x24, 70}, /* 0x23 */ /* 301 TV */
576 { 0x62,0x64, 70}, /* 0x24 */ /* 301 TV */
577 { 0xa8,0x4c, 30}, /* 0x25 */ /* 301 TV */
578 { 0x20,0x26, 33}, /* 0x26 */ /* 301 TV */
579 { 0x31,0xc2, 39}, /* 0x27 */
580 { 0xbf,0xc8, 35}, /* 0x28 */ /* 856x480 */
581 { 0x60,0x36, 30}, /* 0x29 */ /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
582 { 0x40,0x4a, 28}, /* 0x2a */ /* CH-TV */
583 { 0x9f,0x46, 44}, /* 0x2b */ /* CH-TV */
584 { 0x97,0x2c, 26}, /* 0x2c */ /* CH-TV */
585 { 0x44,0xe4, 25}, /* 0x2d */ /* CH-TV */
586 { 0x7e,0x32, 47}, /* 0x2e */ /* CH-TV */
587 { 0x8a,0x24, 31}, /* 0x2f */ /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */
588 { 0x97,0x2c, 26}, /* 0x30 */ /* CH-TV */
589 { 0xce,0x3c, 39}, /* 0x31 */ /* CH-TV */
590 { 0x52,0x4a, 36}, /* 0x32 */ /* CH/PAL 800x600 5/6 */
591 { 0x34,0x61, 95}, /* 0x33 */
592 { 0x78,0x27,108}, /* 0x34 */ /* Replacement for index 0x14 for 630 (?) */
593 { 0x70,0x28, 90}, /* 0x35 */ /* 1152x864@60 */
594 { 0x45,0x6b, 21}, /* 0x36 */ /* Chrontel SuperOverscan */
595 { 0x52,0xe2, 49}, /* 0x37 */ /* 16:9 modes */
596 { 0x2b,0x61, 78}, /* 0x38 */ /* 16:9 modes */
597 { 0x70,0x44,108}, /* 0x39 */ /* 16:9 modes */
598 { 0x54,0x42,135}, /* 0x3a */ /* 16:9 modes */
599 { 0x41,0x22,157}, /* 0x3b */ /* 16:9 modes */
600 { 0x52,0x07,149}, /* 0x3c */ /* 1280x960-85 */
601 { 0x62,0xc6, 34}, /* 0x3d */ /* 848x480-60 */
602 { 0x30,0x23, 88}, /* 0x3e */ /* 1360x768-60 */
603 { 0x70,0x29, 81}, /* 0x3f */ /* 1280x768-60 */
604 { 0x72,0x2a, 76}, /* 0x40 */ /* test for SiS730 --- LIMIT for table (&0x3f) */
605 { 0x15,0x21, 79}, /* 0x41 */ /* test for SiS730 */
606 { 0xa1,0x42,108}, /* 0x42 */ /* 1280x960 LCD */
607 { 0x37,0x61,100}, /* 0x43 */ /* 1280x960 LCD */
608 { 0xe3,0x9a,106}, /* 0x44 */ /* 1360x1024 - special for Barco iQ R300 */
609 { 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */
610 { 0x70,0x29, 81}, /* 0x46 */ /* unused */
611 { 0, 0, 0}, /* 0x47 custom (will be filled out) */
612 { 0xce,0x25,189}, /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */
613 { 0x15,0xe1, 20}, /* 0x49 */ /* 640x400@60 (fake, not actually used) */
614 { 0x5f,0xc6, 33}, /* 0x4a */ /* 720x576@60 */
615 { 0x37,0x5a, 10}, /* 0x4b */ /* 320x200@60 (fake, not actually used) */
616 { 0x2b,0xc2, 35} /* 0x4c */ /* 768@576@60 */
617};
618
619static const unsigned char SiS300_SR15[4 * 8] =
620{
621 0x01,0x09,0xa3,0x00,
622 0x43,0x43,0x43,0x00,
623 0x1e,0x1e,0x1e,0x00,
624 0x2a,0x2a,0x2a,0x00,
625 0x06,0x06,0x06,0x00,
626 0x00,0x00,0x00,0x00,
627 0x00,0x00,0x00,0x00,
628 0x00,0x00,0x00,0x00
629};
630
631static const struct SiS_PanelDelayTbl SiS300_PanelDelayTbl[] =
632{
633 {{0x05,0xaa}},
634 {{0x05,0x14}},
635 {{0x05,0x36}},
636 {{0x05,0x14}},
637 {{0x05,0x14}},
638 {{0x05,0x14}},
639 {{0x05,0x90}},
640 {{0x05,0x90}},
641 {{0x05,0x14}},
642 {{0x05,0x14}},
643 {{0x05,0x14}},
644 {{0x05,0x14}},
645 {{0x20,0x80}},
646 {{0x05,0x14}},
647 {{0x05,0x40}},
648 {{0x05,0x60}}
649};
650
651/**************************************************************/
652/* SIS VIDEO BRIDGE ----------------------------------------- */
653/**************************************************************/
654
655static const struct SiS_LCDData SiS300_St2LCD1024x768Data[] =
656{
657 { 62, 25, 800, 546,1344, 806},
658 { 32, 15, 930, 546,1344, 806},
659 { 32, 15, 930, 546,1344, 806},
660 { 104, 45, 945, 496,1344, 806},
661 { 62, 25, 800, 546,1344, 806},
662 { 31, 18,1008, 624,1344, 806},
663 { 1, 1,1344, 806,1344, 806}
664};
665
666static const struct SiS_LCDData SiS300_ExtLCD1024x768Data[] =
667{
668 { 12, 5, 896, 512,1344, 806},
669 { 12, 5, 896, 510,1344, 806},
670 { 32, 15,1008, 505,1344, 806},
671 { 32, 15,1008, 514,1344, 806},
672 { 12, 5, 896, 500,1344, 806},
673 { 42, 25,1024, 625,1344, 806},
674 { 1, 1,1344, 806,1344, 806},
675 { 12, 5, 896, 500,1344, 806},
676 { 42, 25,1024, 625,1344, 806},
677 { 1, 1,1344, 806,1344, 806},
678 { 12, 5, 896, 500,1344, 806},
679 { 42, 25,1024, 625,1344, 806},
680 { 1, 1,1344, 806,1344, 806}
681};
682
683static const struct SiS_LCDData SiS300_St2LCD1280x1024Data[] =
684{
685 { 22, 5, 800, 510,1650,1088},
686 { 22, 5, 800, 510,1650,1088},
687 { 176, 45, 900, 510,1650,1088},
688 { 176, 45, 900, 510,1650,1088},
689 { 22, 5, 800, 510,1650,1088},
690 { 13, 5,1024, 675,1560,1152},
691 { 16, 9,1266, 804,1688,1072},
692 { 1, 1,1688,1066,1688,1066}
693};
694
695static const struct SiS_LCDData SiS300_ExtLCD1280x1024Data[] =
696{
697 { 211, 60,1024, 501,1688,1066},
698 { 211, 60,1024, 508,1688,1066},
699 { 211, 60,1024, 501,1688,1066},
700 { 211, 60,1024, 508,1688,1066},
701 { 211, 60,1024, 500,1688,1066},
702 { 211, 75,1024, 625,1688,1066},
703 { 211, 120,1280, 798,1688,1066},
704 { 1, 1,1688,1066,1688,1066}
705};
706
707static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_1[] =
708{ /* VESA Timing */
709 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
710 {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
711 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
712 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
713 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
714 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
715 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
716};
717
718static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_2[] =
719{ /* Non-VESA */
720 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
721 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
722 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
723 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
724 {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
725 {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
726 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
727};
728
729static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_3[] =
730{
731 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
732};
733
734/**************************************************************/
735/* LVDS/Chrontel -------------------------------------------- */
736/**************************************************************/
737
738/* Custom data for Barco iQ R series */
739static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_1[]=
740{
741 { 832, 438,1331, 806},
742 { 832, 388,1331, 806},
743 { 832, 438,1331, 806},
744 { 832, 388,1331, 806},
745 { 832, 518,1331, 806},
746 {1050, 638,1344, 806},
747 {1344, 806,1344, 806},
748 {1688,1066,1688,1066},
749 {1688,1066,1688,1066} /* 1360x1024 */
750};
751
752/* Custom data for Barco iQ R series */
753static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_2[]=
754{
755 {1344, 806,1344, 806},
756 {1344, 806,1344, 806},
757 {1344, 806,1344, 806},
758 {1344, 806,1344, 806},
759 {1344, 806,1344, 806},
760 {1344, 806,1344, 806},
761 {1344, 806,1344, 806},
762 {1688,1066,1688,1066},
763 {1688,1066,1688,1066} /* 1360x1024 */
764};
765
766/* Custom data for Barco iQ G series */
767static const struct SiS_LVDSData SiS300_LVDSBARCO1024Data_1[]=
768{
769 { 832, 438,1331, 806},
770 { 832, 409,1331, 806},
771 { 832, 438,1331, 806},
772 { 832, 409,1331, 806},
773 { 832, 518,1331, 806}, /* 640x480 */
774 {1050, 638,1344, 806}, /* 800x600 */
775 {1344, 806,1344, 806}, /* 1024x768 */
776};
777
778/* Custom data for 848x480 and 856x480 parallel LVDS panels */
779static const struct SiS_LVDSData SiS300_LVDS848x480Data_1[]=
780{
781 { 0, 0, 0, 0},
782 { 0, 0, 0, 0},
783 { 0, 0, 0, 0},
784 { 0, 0, 0, 0},
785 {1088, 525,1088, 525}, /* 640x480 TODO */
786 {1088, 525,1088, 525}, /* 800x600 TODO */
787 {1088, 525,1088, 525}, /* 1024x768 TODO */
788 { 0, 0, 0, 0},
789 { 0, 0, 0, 0},
790 { 0, 0, 0, 0},
791 { 0, 0, 0, 0},
792 {1088, 525,1088, 525}, /* 848x480 */
793 {1088, 525,1088, 525}, /* 856x480 */
794 {1088, 525,1088, 525} /* 1360x768 TODO */
795};
796
797/* Custom data for 848x480 parallel panel */
798static const struct SiS_LVDSData SiS300_LVDS848x480Data_2[]=
799{
800 { 0, 0, 0, 0},
801 { 0, 0, 0, 0},
802 { 0, 0, 0, 0},
803 { 0, 0, 0, 0},
804 {1088, 525,1088, 525}, /* 640x480 */
805 {1088, 525,1088, 525}, /* 800x600 */
806 {1088, 525,1088, 525}, /* 1024x768 */
807 { 0, 0, 0, 0},
808 { 0, 0, 0, 0},
809 { 0, 0, 0, 0},
810 { 0, 0, 0, 0},
811 {1088, 525,1088, 525}, /* 848x480 */
812 {1088, 525,1088, 525}, /* 856x480 */
813 {1088, 525,1088, 525} /* 1360x768 TODO */
814};
815
816static const struct SiS_LVDSData SiS300_CHTVUPALData[] =
817{
818 {1008, 625,1008, 625},
819 {1008, 625,1008, 625},
820 {1008, 625,1008, 625},
821 {1008, 625,1008, 625},
822 { 840, 750, 840, 750},
823 { 936, 836, 936, 836}
824};
825
826static const struct SiS_LVDSData SiS300_CHTVOPALData[] =
827{
828 {1008, 625,1008, 625},
829 {1008, 625,1008, 625},
830 {1008, 625,1008, 625},
831 {1008, 625,1008, 625},
832 { 840, 625, 840, 625},
833 { 960, 750, 960, 750}
834};
835
836static const struct SiS_LVDSData SiS300_CHTVSOPALData[] =
837{
838 {1008, 625,1008, 625},
839 {1008, 625,1008, 625},
840 {1008, 625,1008, 625},
841 {1008, 625,1008, 625},
842 { 840, 500, 840, 500},
843 { 944, 625, 944, 625}
844};
845
846/* Custom des data for Barco iQ R200/300/400 (BIOS 2.00.07) */
847static const struct SiS_LVDSDes SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
848{
849 {1330, 798}, /* 320x200 */
850 {1330, 794},
851 {1330, 798},
852 {1330, 794},
853 {1330, 0}, /* 640x480 / 320x240 */
854 {1343, 0}, /* 800x600 / 400x300 */
855 { 0, 805}, /* 1024x768 / 512x384 */
856 {1688,1066}, /* 1280x1024 */
857 { 0, 0} /* 1360x1024 */
858};
859
860static const struct SiS_LVDSDes SiS300_PanelType04_2a[] =
861{
862 {1152, 622},
863 {1152, 597},
864 {1152, 622},
865 {1152, 597},
866 {1152, 662},
867 {1232, 722},
868 { 0, 805},
869 {1688,1066},
870 { 0, 0}
871};
872
873/* Custom des data for Barco iQ G200/300/400 (BIOS 2.00.07) */
874static const struct SiS_LVDSDes SiS300_PanelType04_1b[] = /* 1024x768 */
875{
876 {1330, 798}, /* 320x200 */
877 {1330, 794},
878 {1330, 798},
879 {1330, 794},
880 {1330, 0}, /* 640x480 / 320x240 */
881 {1343, 0}, /* 800x600 / 400x300 */
882 { 0, 805} /* 1024x768 / 512x384 */
883};
884
885static const struct SiS_LVDSDes SiS300_PanelType04_2b[] =
886{
887 {1152, 622},
888 {1152, 597},
889 {1152, 622},
890 {1152, 597},
891 {1152, 662},
892 {1232, 722},
893 { 0, 805}
894};
895
896/* CRT1 CRTC for slave modes */
897
898static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UNTSC[] =
899{
900 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
901 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
902 0x00 }},
903 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
904 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
905 0x00 }},
906 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
907 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
908 0x00 }},
909 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
910 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
911 0x00 }},
912 {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
913 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
914 0x00 }},
915 {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
916 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
917 0x01 }}
918};
919
920static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1ONTSC[] =
921{
922 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
923 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
924 0x00 }},
925 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
926 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
927 0x00 }},
928 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
929 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
930 0x00 }},
931 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
932 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
933 0x00 }},
934 {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
935 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
936 0x00 }},
937 {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
938 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
939 0x01 }}
940};
941
942static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UPAL[] =
943{
944 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
945 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
946 0x00 }},
947 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
948 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
949 0x00 }},
950 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
951 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
952 0x00 }},
953 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
954 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
955 0x00 }},
956 {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
957 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
958 0x00 }},
959 {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
960 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
961 0x01 }}
962};
963
964static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1OPAL[] =
965{
966 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
967 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
968 0x00 }},
969 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
970 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
971 0x00 }},
972 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
973 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
974 0x00 }},
975 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
976 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
977 0x00 }},
978 {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
979 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
980 0x00 }},
981 {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
982 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
983 0x01 }}
984};
985
986static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1SOPAL[] =
987{
988 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
989 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
990 0x00 }},
991 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
992 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
993 0x00 }},
994 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
995 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
996 0x00 }},
997 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
998 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
999 0x00 }},
1000 {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba, /* TODO */
1001 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
1002 0x00 }},
1003 {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0, /* TODO */
1004 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
1005 0x01 }}
1006};
1007
1008static const struct SiS_CHTVRegData SiS300_CHTVReg_UNTSC[] =
1009{
1010 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1011 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1012 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1013 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1014 {{0x6a,0x6a,0x00,0x2d,0xfa,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 17: 640x480 NTSC 7/8 */
1015 {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
1016};
1017
1018static const struct SiS_CHTVRegData SiS300_CHTVReg_ONTSC[] =
1019{
1020 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1021 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1022 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1023 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1024 {{0x69,0x6a,0x00,0x1e,0xfd,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 16: 640x480 NTSC 1/1 */
1025 {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
1026};
1027
1028static const struct SiS_CHTVRegData SiS300_CHTVReg_UPAL[] =
1029{
1030 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1031 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1032 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1033 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1034 {{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */
1035 {{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 21: 800x600 PAL 3/4 */
1036
1037};
1038
1039static const struct SiS_CHTVRegData SiS300_CHTVReg_OPAL[] =
1040{
1041 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1042 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1043 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1044 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1045 {{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */
1046 {{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 20: 800x600 PAL 5/6 */
1047
1048};
1049
1050static const struct SiS_CHTVRegData SiS300_CHTVReg_SOPAL[] =
1051{
1052 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1053 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1054 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1055 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1056 {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 13: 640x480 PAL 5/4 */
1057 {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 19: 800x600 PAL 1/1 */
1058};
1059
1060static const unsigned char SiS300_CHTVVCLKUNTSC[] = { 0x29,0x29,0x29,0x29,0x2a,0x2e };
1061
1062static const unsigned char SiS300_CHTVVCLKONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
1063
1064static const unsigned char SiS300_CHTVVCLKSONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
1065
1066static const unsigned char SiS300_CHTVVCLKUPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x2f,0x31 };
1067
1068static const unsigned char SiS300_CHTVVCLKOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x30,0x32 };
1069
1070static const unsigned char SiS300_CHTVVCLKSOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x36,0x29 };
1071
1072
diff --git a/drivers/video/fbdev/sis/310vtbl.h b/drivers/video/fbdev/sis/310vtbl.h
new file mode 100644
index 000000000000..54fcbbf4ef63
--- /dev/null
+++ b/drivers/video/fbdev/sis/310vtbl.h
@@ -0,0 +1,1339 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Register settings for SiS 315/330/340 series
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const struct SiS_Ext SiS310_EModeIDTable[] =
54{
55 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
56 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
57 {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
58 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
59 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
60 {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
61 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
62 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
63 {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
64 {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
65 {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x? */
66 {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
67 {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x8 */
68 {0x3c,0x0e3b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x8 */
69 {0x3d,0x0e7d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x16 */
70 {0x40,0x9a1c,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x15 */
71 {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x16 */
72 {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2},
73 {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
74 {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3},
75 {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
76 {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13, 4},
77 {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
78 {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8},
79 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
80 {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */
81 {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */
82 {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
83 {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
84 {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
85 {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
86 {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */
87 {0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */
88 {0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
89 {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x32 */
90 {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0},
91 {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
92 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
93 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
94 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
95 {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x32 */
96 {0x66,0x0eff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x32 */
97 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x8 */
98 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x16 */
99 {0x6b,0x07ff,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x32 */
100 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x8 */
101 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x16 */
102 {0x6e,0x07ff,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x32 */
103 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x8 */
104 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x8 */
105 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x16 */
106 {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x16 */
107 {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x32 */
108 {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x32 */
109 {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x32 */
110 {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x8 */
111 {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x16 */
112 {0x7c,0x0e3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x8 */
113 {0x7d,0x0e7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x16 */
114 {0x7e,0x0eff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x32 */
115 {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
116 {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
117 {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
118 {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x8 */
119 {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x16 */
120 {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x32*/
121 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1}, /* 1152x864 */
122 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
123 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
124 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 848x480 */
125 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
126 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
127 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 856x480 */
128 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
129 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
130 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1}, /* 1360x768 */
131 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
132 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
133 {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
134 {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
135 {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
136 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1}, /* 768x576 */
137 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
138 {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
139 {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7}, /* 1280x800 */
140 {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
141 {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
142 {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9}, /* 1680x1050 */
143 {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
144 {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
145 {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1}, /* 1920x1080(i) */
146 {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
147 {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
148 {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1}, /* 960x540 */
149 {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
150 {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
151 {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1}, /* 960x600 */
152 {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
153 {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
154 {0x1a,0x0e3b,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8}, /* 1280x854 */
155 {0x1b,0x0e7d,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
156 {0x1c,0x0eff,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
157 {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
158};
159
160static const struct SiS_Ext2 SiS310_RefIndex[] =
161{
162 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x0 */
163 {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1 */
164 {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2 */
165 {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3 */
166 {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4 */
167 {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x5 */
168 {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x6 */
169 {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x7 */
170 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x8 */
171 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x9 */
172 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xa */
173 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xb */
174 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xc */
175 {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xd */
176 {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xe */
177 {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xf */
178 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00}, /* 0x10 */
179 {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x11 */
180 {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x12 (6f was 03) */
181 {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x13 */
182 {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x14 */
183 {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x15 */
184 {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x16 */
185 {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x17 */
186 {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x18 */
187 {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x19 */
188 {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1a */
189 {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1b */
190 {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1c */
191 {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1d */
192 {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1e */
193 {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1f */
194 {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x20 */
195 {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x21 */
196 {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x22 */
197 {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x23 */
198 {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x24 */
199 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30, 0x56, 0x4e, 0x00, 0x00, 0x00, 0x00}, /* 0x25 */
200 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x26 */
201 {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x27 */
202 {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x28 */
203 {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x29 */
204 {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2a */
205 {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2b */
206 {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2c */
207 {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2d */
208 {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2e */
209 {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2f */
210 {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x30 */
211 {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x31 */
212 {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x32 */
213 {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x33 */
214 {0x2077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x32, 0x40, 0x5e, 0x73}, /* 0x34 */
215 {0x2047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x33, 0x07, 0xff, 0xff}, /* 0x35 */
216 {0x2047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x34, 0x0a, 0xff, 0xff}, /* 0x36 */
217 {0x2077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x35, 0x0b, 0x5f, 0x74}, /* 0x37 */
218 {0x2047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x36, 0x11, 0xff, 0xff}, /* 0x38 */
219 {0x2047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x37, 0x16, 0xff, 0xff}, /* 0x39 */
220 {0x3137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x38, 0x19, 0x60, 0x75}, /* 0x3a */
221 {0x3107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x39, 0x1e, 0xff, 0xff}, /* 0x3b */
222 {0x3307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x3a, 0x20, 0xff, 0xff}, /* 0x3c */
223 {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3d */
224 {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3e */
225 {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3f */ /* FSTN 320x240 */
226 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x58, 0x19, 0x42, 0x5b}, /* 0x40 */ /* 0x5b was 0x12 */
227 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x59, 0x1e, 0xff, 0xff}, /* 0x41 */
228 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x5a, 0x20, 0xff, 0xff}, /* 0x42 */
229 {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x43 */
230 {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x44 1400x1050-75Hz */
231 {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x45 1152x864-60Hz */
232 {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x46 1152x864-75Hz */
233 {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x47 1152x864-85Hz */
234 {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x48 848x480-38Hzi */
235 {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x49 848x480-60Hz */
236 {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4a 856x480-38Hzi */
237 {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4b 856x480-60Hz */
238 {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4c 1360x768-60Hz */
239 {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4d 768x576-56Hz */
240 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5b, 0x19, 0x4f, 0x5c}, /* 0x4e 1280x800-60Hz */
241 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5c, 0x1e, 0xff, 0xff}, /* 0x4f 1280x800-75Hz */
242 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5d, 0x20, 0xff, 0xff}, /* 0x50 1280x800-85Hz */
243 {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x51 1680x1050-60Hz */
244 {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x52 1920x1080 60Hzi */
245 {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x53 960x540 60Hz */
246 {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x54 960x600 60Hz */
247 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x62, 0x19, 0x61, 0x76}, /* 0x55 1280x854-60Hz */
248 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x63, 0x1e, 0xff, 0xff}, /* 0x56 1280x854-75Hz */
249 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x64, 0x20, 0xff, 0xff}, /* 0x57 1280x854-85Hz */
250 {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
251};
252
253static const struct SiS_CRT1Table SiS310_CRT1Table[] =
254{
255 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
256 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
257 0x00}}, /* 0x0 */
258 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
259 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
260 0x00}}, /* 0x1 */
261 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
262 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
263 0x01}}, /* 0x2 */
264 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
265 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
266 0x01}}, /* 0x3 */
267 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
268 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
269 0x00}}, /* 0x4 */
270 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* corrected 640x480-60 */
271 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
272 0x00}}, /* 0x5 */
273 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* corrected 640x480-72 */
274 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
275 0x00}}, /* 0x6 */
276 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
277 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
278 0x00}}, /* 0x7 */
279 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
280 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
281 0x00}}, /* 0x8 */
282 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
283 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
284 0x61}}, /* 0x9 */
285 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
286 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
287 0x61}}, /* 0xa */
288 {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
289 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
290 0x61}}, /* 0xb */
291 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
292 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
293 0x00}}, /* 0xc */
294 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
295 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
296 0x01}}, /* 0xd */
297 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
298 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
299 0x01}}, /* 0xe */
300 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
301 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
302 0x01}}, /* 0xf */
303 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
304 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
305 0x01}}, /* 0x10 */
306 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
307 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
308 0x01}}, /* 0x11 */
309 {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
310 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
311 0x61}}, /* 0x12 */
312 {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
313 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
314 0x61}}, /* 0x13 */
315 {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
316 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
317 0x61}}, /* 0x14 */
318 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
319 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
320 0x00}}, /* 0x15 */
321 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
322 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
323 0x01}}, /* 0x16 */
324 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
325 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
326 0x01}}, /* 0x17 */
327 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
328 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
329 0x01}}, /* 0x18 */
330 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
331 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
332 0x01}}, /* 0x19 */
333 {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
334 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
335 0x62}}, /* 0x1a */
336 {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
337 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
338 0x62}}, /* 0x1b */
339 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
340 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
341 0x00}}, /* 0x1c */
342 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
343 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
344 0x01}}, /* 0x1d */
345 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
346 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
347 0x01}}, /* 0x1e */
348 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
349 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
350 0x01}}, /* 0x1f */
351 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
352 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
353 0x00}}, /* 0x20 */
354 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
355 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
356 0x00}}, /* 0x21 */
357 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
358 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
359 0x00}}, /* 0x22 */
360 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
361 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
362 0x00}}, /* 0x23 */
363 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
364 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
365 0x00}}, /* 0x24 */
366 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
367 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
368 0x00}}, /* 0x25 */
369 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
370 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
371 0x00}}, /* 0x26 */
372 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
373 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
374 0x00}}, /* 0x27 */
375 {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
376 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
377 0x63}}, /* 0x28 */
378 {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
379 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
380 0x63}}, /* 0x29 */
381 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
382 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
383 0x00}}, /* 0x2a */
384 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
385 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
386 0x00}}, /* 0x2b */
387 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
388 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
389 0x00}}, /* 0x2c */
390 {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
391 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
392 0x44}}, /* 0x2d */
393 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
394 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
395 0x44}}, /* 0x2e */
396 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
397 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
398 0x44}}, /* 0x2f */
399 {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
400 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
401 0x44}}, /* 0x30 */
402 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
403 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
404 0x00}}, /* 0x31 */
405 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
406 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
407 0x01}}, /* 0x32 */
408 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
409 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
410 0x01}}, /* 0x33 */
411 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
412 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
413 0x01}}, /* 0x34 */
414 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
415 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
416 0x01}}, /* 0x35 */
417 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
418 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
419 0x01}}, /* 0x36 */
420 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
421 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
422 0x01}}, /* 0x37 */
423 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
424 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
425 0x01}}, /* 0x38 */
426 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
427 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
428 0x01}}, /* 0x39 */
429 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
430 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
431 0x01}}, /* 0x3a */
432 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
433 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
434 0x01}}, /* 0x3b */
435 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
436 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
437 0x00}}, /* 0x3c */
438 {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 720x576, corrected to 60Hz */
439 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
440 0x41}}, /* 0x3d */
441 {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
442 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
443 0x00}}, /* 0x3e */
444 {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
445 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
446 0x00}}, /* 0x3f */
447 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
448 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
449 0x01}}, /* 0x40 */
450 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
451 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
452 0x01}}, /* 0x41 */
453 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
454 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
455 0x01}}, /* 0x42 */
456 {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
457 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
458 0x00}}, /* 0x43 */
459 {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
460 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
461 0x01}}, /* 0x44 */
462 {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
463 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
464 0x00}}, /* 0x45 */
465 {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
466 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
467 0x00}}, /* 0x46 */
468 {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
469 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
470 0x00}}, /* 0x47 */
471 {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
472 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
473 0x00}}, /* 0x48 */
474 {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
475 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
476 0x01}}, /* 0x49 */
477 {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
478 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
479 0x01}}, /* 0x4a */
480 {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* 1400x1050-75 */
481 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
482 0x00}}, /* 0x4b */
483 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
484 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
485 0x01}}, /* 0x4c */
486 {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
487 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
488 0x41}}, /* 0x4d */
489 {{0x5f,0x27,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* FSTN 320x240 (working) */
490 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
491 0x00}}, /* 0x4e */
492 {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
493 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
494 0x21}}, /* 0x4f */
495 {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, /* 1680x1050-60 */
496 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
497 0x20}}, /* 0x50 */
498 {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, /* 1920x1080-60i */
499 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
500 0x61}}, /* 0x51 */
501 {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
502 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
503 0x41}}, /* 0x52 */
504 {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, /* 960x600-60 */
505 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
506 0x01}}, /* 0x53 */
507 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
508 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
509 0x41}}, /* 0x54 */
510 {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
511 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
512 0x40}}, /* 0x55 */
513 {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
514 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
515 0x00}}, /* 0x56 */
516 {{0xd7,0xc7,0xc7,0x9b,0xd1,0x15,0xd1,0x10, /* 1600x1200 for LCDA */
517 0xb2,0x86,0xaf,0xb0,0xd2,0x2f,0x00,0x03,
518 0x00}}, /* 0x57 */
519 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 60 Hz */
520 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
521 0x01}}, /* 0x58 */
522 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 75 Hz */
523 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
524 0x01}}, /* 0x59 */
525 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xdc, /* 1280x768 (1280x1024) 85 Hz */
526 0x95,0x89,0xff,0x94,0x2f,0x21,0x00,0x07,
527 0x01}}, /* 0x5a */
528 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x800 (1280x1024) 60 Hz */
529 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
530 0x01}}, /* 0x5b */
531 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x800 (1280x1024) 75 Hz */
532 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
533 0x01}}, /* 0x5c */
534 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x800 (1280x1024) 85 Hz */
535 0xa5,0x89,0x1f,0xa4,0x2f,0x01,0x00,0x07,
536 0x01}}, /* 0x5d */
537 {{0x7f,0x63,0x63,0x83,0x6d,0x1d,0x0b,0x3e, /* 800x480 (wide) 60 Hz */
538 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x06,
539 0x00}}, /* 0x5e */
540 {{0xa0,0x7f,0x7f,0x84,0x85,0x97,0x52,0xf0, /* 1024x576 (wide) 60 Hz */
541 0x41,0x85,0x3f,0x40,0x53,0x00,0x00,0x02,
542 0x01}}, /* 0x5f */
543 {{0xc9,0x9f,0x9f,0x8d,0xb0,0x15,0xec,0xf0, /* 1280x720 (wide) 60 Hz */
544 0xd4,0x89,0xcf,0xd3,0xed,0x20,0x00,0x07,
545 0x01}}, /* 0x60 */
546 {{0xcb,0x9f,0x9f,0x8f,0xa5,0x13,0x5b,0xff, /* 1280x854-60 wide */
547 0x56,0x89,0x55,0x55,0x5c,0x30,0x00,0x07,
548 0x01}}, /* 0x61 */
549 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x854 (1280x1024) 60 Hz */
550 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
551 0x41}}, /* 0x62 */
552 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x854 (1280x1024) 75 Hz */
553 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
554 0x41}}, /* 0x63 */
555 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x854 (1280x1024) 85 Hz */
556 0xc0,0x84,0x55,0xbf,0x2f,0x01,0x00,0x07,
557 0x41}} /* 0x64 */
558};
559
560static const struct SiS_MCLKData SiS310_MCLKData_0_315[] =
561{
562 { 0x3b,0x22,0x01,143},
563 { 0x5c,0x23,0x01,166},
564 { 0x5c,0x23,0x01,166},
565 { 0x5c,0x23,0x01,166},
566 { 0x5c,0x23,0x01,166},
567 { 0x5c,0x23,0x01,166},
568 { 0x5c,0x23,0x01,166},
569 { 0x5c,0x23,0x01,166}
570};
571
572static const struct SiS_MCLKData SiS310_MCLKData_0_650[] =
573{
574 { 0x5a,0x64,0x82, 66},
575 { 0xb3,0x45,0x82, 83},
576 { 0x37,0x61,0x82,100},
577 { 0x37,0x22,0x82,133},
578 { 0x37,0x61,0x82,100},
579 { 0x37,0x22,0x82,133},
580 { 0x37,0x22,0x82,133},
581 { 0x37,0x22,0x82,133}
582};
583
584static const struct SiS_MCLKData SiS310_MCLKData_0_330[] =
585{
586 { 0x5c,0x23,0x01,166},
587 { 0x5c,0x23,0x01,166},
588 { 0x7c,0x08,0x01,200},
589 { 0x79,0x06,0x01,250},
590 { 0x7c,0x08,0x01,200},
591 { 0x7c,0x08,0x01,200},
592 { 0x7c,0x08,0x01,200},
593 { 0x79,0x06,0x01,250}
594};
595
596static const struct SiS_MCLKData SiS310_MCLKData_0_660[] =
597{
598 { 0x5c,0x23,0x82,166},
599 { 0x5c,0x23,0x82,166},
600 { 0x37,0x21,0x82,200},
601 { 0x37,0x22,0x82,133},
602 { 0x29,0x21,0x82,150},
603 { 0x5c,0x23,0x82,166},
604 { 0x65,0x23,0x82,183},
605 { 0x37,0x21,0x82,200}
606};
607
608static const struct SiS_MCLKData SiS310_MCLKData_0_760[] =
609{
610 { 0x37,0x22,0x82,133},
611 { 0x5c,0x23,0x82,166},
612 { 0x65,0x23,0x82,183},
613 { 0x7c,0x08,0x82,200},
614 { 0x29,0x21,0x82,150},
615 { 0x5c,0x23,0x82,166},
616 { 0x65,0x23,0x82,183},
617 { 0x37,0x21,0x82,200}
618};
619
620static const struct SiS_MCLKData SiS310_MCLKData_0_761[] =
621{
622 { 0x37,0x22,0x82,133}, /* Preliminary */
623 { 0x5c,0x23,0x82,166},
624 { 0x65,0x23,0x82,183},
625 { 0x7c,0x08,0x82,200},
626 { 0x29,0x21,0x82,150},
627 { 0x5c,0x23,0x82,166},
628 { 0x65,0x23,0x82,183},
629 { 0x37,0x21,0x82,200}
630};
631
632static const struct SiS_MCLKData SiS310_MCLKData_0_340[] =
633{
634 { 0x79,0x06,0x01,250},
635 { 0x7c,0x08,0x01,200},
636 { 0x7c,0x08,0x80,200},
637 { 0x79,0x06,0x80,250},
638 { 0x29,0x01,0x81,300},
639 { 0x29,0x01,0x81,300},
640 { 0x29,0x01,0x81,300},
641 { 0x29,0x01,0x81,300}
642};
643
644static const struct SiS_MCLKData SiS310_MCLKData_1[] = /* ECLK */
645{
646 { 0x29,0x21,0x82,150},
647 { 0x5c,0x23,0x82,166},
648 { 0x65,0x23,0x82,183},
649 { 0x37,0x21,0x82,200},
650 { 0x37,0x22,0x82,133},
651 { 0x37,0x22,0x82,133},
652 { 0x37,0x22,0x82,133},
653 { 0x37,0x22,0x82,133}
654};
655
656static const struct SiS_MCLKData SiS310_MCLKData_1_340[] =
657{
658 { 0x7c,0x08,0x01,200},
659 { 0x7c,0x08,0x01,200},
660 { 0x7c,0x08,0x80,200},
661 { 0x79,0x06,0x80,250},
662 { 0x29,0x01,0x81,300},
663 { 0x29,0x01,0x81,300},
664 { 0x29,0x01,0x81,300},
665 { 0x29,0x01,0x81,300}
666};
667
668static struct SiS_VCLKData SiS310_VCLKData[] =
669{
670 { 0x1b,0xe1, 25}, /* 0x00 */
671 { 0x4e,0xe4, 28}, /* 0x01 */
672 { 0x57,0xe4, 31}, /* 0x02 */
673 { 0xc3,0xc8, 36}, /* 0x03 */
674 { 0x42,0xe2, 40}, /* 0x04 */
675 { 0xfe,0xcd, 43}, /* 0x05 */
676 { 0x5d,0xc4, 44}, /* 0x06 */
677 { 0x52,0xe2, 49}, /* 0x07 */
678 { 0x53,0xe2, 50}, /* 0x08 */
679 { 0x74,0x67, 52}, /* 0x09 */
680 { 0x6d,0x66, 56}, /* 0x0a */
681 { 0x5a,0x64, 65}, /* 0x0b */ /* was 6c c3 - WRONG */
682 { 0x46,0x44, 67}, /* 0x0c */
683 { 0xb1,0x46, 68}, /* 0x0d */
684 { 0xd3,0x4a, 72}, /* 0x0e */
685 { 0x29,0x61, 75}, /* 0x0f */
686 { 0x6e,0x46, 76}, /* 0x10 */
687 { 0x2b,0x61, 78}, /* 0x11 */
688 { 0x31,0x42, 79}, /* 0x12 */
689 { 0xab,0x44, 83}, /* 0x13 */
690 { 0x46,0x25, 84}, /* 0x14 */
691 { 0x78,0x29, 86}, /* 0x15 */
692 { 0x62,0x44, 94}, /* 0x16 */
693 { 0x2b,0x41,104}, /* 0x17 */
694 { 0x3a,0x23,105}, /* 0x18 */
695 { 0x70,0x44,108}, /* 0x19 */
696 { 0x3c,0x23,109}, /* 0x1a */
697 { 0x5e,0x43,113}, /* 0x1b */
698 { 0xbc,0x44,116}, /* 0x1c */
699 { 0xe0,0x46,132}, /* 0x1d */
700 { 0x54,0x42,135}, /* 0x1e */
701 { 0xea,0x2a,139}, /* 0x1f */
702 { 0x41,0x22,157}, /* 0x20 */
703 { 0x70,0x24,162}, /* 0x21 */
704 { 0x30,0x21,175}, /* 0x22 */
705 { 0x4e,0x22,189}, /* 0x23 */
706 { 0xde,0x26,194}, /* 0x24 */
707 { 0x62,0x06,202}, /* 0x25 */
708 { 0x3f,0x03,229}, /* 0x26 */
709 { 0xb8,0x06,234}, /* 0x27 */
710 { 0x34,0x02,253}, /* 0x28 */
711 { 0x58,0x04,255}, /* 0x29 */
712 { 0x24,0x01,265}, /* 0x2a */
713 { 0x9b,0x02,267}, /* 0x2b */
714 { 0x70,0x05,270}, /* 0x2c */
715 { 0x25,0x01,272}, /* 0x2d */
716 { 0x9c,0x02,277}, /* 0x2e */
717 { 0x27,0x01,286}, /* 0x2f */
718 { 0x3c,0x02,291}, /* 0x30 */
719 { 0xef,0x0a,292}, /* 0x31 */
720 { 0xf6,0x0a,310}, /* 0x32 */
721 { 0x95,0x01,315}, /* 0x33 */
722 { 0xf0,0x09,324}, /* 0x34 */
723 { 0xfe,0x0a,331}, /* 0x35 */
724 { 0xf3,0x09,332}, /* 0x36 */
725 { 0xea,0x08,340}, /* 0x37 */
726 { 0xe8,0x07,376}, /* 0x38 */
727 { 0xde,0x06,389}, /* 0x39 */
728 { 0x52,0x2a, 54}, /* 0x3a 301 TV */
729 { 0x52,0x6a, 27}, /* 0x3b 301 TV */
730 { 0x62,0x24, 70}, /* 0x3c 301 TV */
731 { 0x62,0x64, 70}, /* 0x3d 301 TV */
732 { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
733 { 0x20,0x26, 33}, /* 0x3f 301 TV */
734 { 0x31,0xc2, 39}, /* 0x40 */
735 { 0x60,0x36, 30}, /* 0x41 Chrontel */
736 { 0x40,0x4a, 28}, /* 0x42 Chrontel */
737 { 0x9f,0x46, 44}, /* 0x43 Chrontel */
738 { 0x97,0x2c, 26}, /* 0x44 */
739 { 0x44,0xe4, 25}, /* 0x45 Chrontel */
740 { 0x7e,0x32, 47}, /* 0x46 Chrontel */
741 { 0x8a,0x24, 31}, /* 0x47 Chrontel */
742 { 0x97,0x2c, 26}, /* 0x48 Chrontel */
743 { 0xce,0x3c, 39}, /* 0x49 */
744 { 0x52,0x4a, 36}, /* 0x4a Chrontel */
745 { 0x34,0x61, 95}, /* 0x4b */
746 { 0x78,0x27,108}, /* 0x4c - was 102 */
747 { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
748 { 0x41,0x4e, 21}, /* 0x4e */
749 { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
750 { 0x19,0x42, 42}, /* 0x50 */
751 { 0x54,0x46, 58}, /* 0x51 Chrontel */
752 { 0x25,0x42, 61}, /* 0x52 */
753 { 0x44,0x44, 66}, /* 0x53 Chrontel */
754 { 0x3a,0x62, 70}, /* 0x54 Chrontel */
755 { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
756 { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
757 { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
758 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
759 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
760 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
761 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
762 { 0x45,0x25, 83}, /* 0x5c 1280x800 */
763 { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
764 { 0x70,0x24,162}, /* 0x5e 1600x1200 */
765 { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
766 { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
767 { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
768 { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
769 { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
770 { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
771 { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
772 { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
773 { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
774 { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
775 { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
776 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
777 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
778 { 0x45,0x25, 83}, /* 0x6c 1280x800 */
779 { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
780 { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
781 { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
782 { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
783 { 0x2b,0xc2, 35}, /* 0x71 768x576@60 */
784 { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
785 { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
786 { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
787 { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
788 { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (wide) */
789};
790
791static struct SiS_VBVCLKData SiS310_VBVCLKData[] =
792{
793 { 0x1b,0xe1, 25}, /* 0x00 */
794 { 0x4e,0xe4, 28}, /* 0x01 */
795 { 0x57,0xe4, 31}, /* 0x02 */
796 { 0xc3,0xc8, 36}, /* 0x03 */
797 { 0x42,0x47, 40}, /* 0x04 */
798 { 0xfe,0xcd, 43}, /* 0x05 */
799 { 0x5d,0xc4, 44}, /* 0x06 */
800 { 0x52,0x47, 49}, /* 0x07 */
801 { 0x53,0x47, 50}, /* 0x08 */
802 { 0x74,0x67, 52}, /* 0x09 */
803 { 0x6d,0x66, 56}, /* 0x0a */
804 { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301: 35,62 */
805 { 0x46,0x44, 67}, /* 0x0c */
806 { 0xb1,0x46, 68}, /* 0x0d */
807 { 0xd3,0x4a, 72}, /* 0x0e */
808 { 0x29,0x61, 75}, /* 0x0f */
809 { 0x6d,0x46, 75}, /* 0x10 */
810 { 0x41,0x43, 78}, /* 0x11 */
811 { 0x31,0x42, 79}, /* 0x12 */
812 { 0xab,0x44, 83}, /* 0x13 */
813 { 0x46,0x25, 84}, /* 0x14 */
814 { 0x78,0x29, 86}, /* 0x15 */
815 { 0x62,0x44, 94}, /* 0x16 */
816 { 0x2b,0x22,104}, /* 0x17 */
817 { 0x49,0x24,105}, /* 0x18 */
818 { 0xf8,0x2f,108}, /* 0x19 */ /* 1400x1050 LCD */
819 { 0x3c,0x23,109}, /* 0x1a */
820 { 0x5e,0x43,113}, /* 0x1b */
821 { 0xbc,0x44,116}, /* 0x1c */
822 { 0xe0,0x46,132}, /* 0x1d */
823 { 0xe2,0x46,135}, /* 0x1e */ /* 1280x1024-75, better clock for VGA2 */
824 { 0xe5,0x46,139}, /* 0x1f */ /* 1024x768-120, better clock for VGA2 */
825 { 0x15,0x01,157}, /* 0x20 */ /* 1280x1024-85, better clock for VGA2 */
826 { 0x70,0x09,162}, /* 0x21 */ /* 1600x1200-60, better clock for VGA2 */
827 { 0x30,0x21,175}, /* 0x22 */
828 { 0x4e,0x22,189}, /* 0x23 */
829 { 0xde,0x26,194}, /* 0x24 */
830 { 0x70,0x07,202}, /* 0x25 */
831 { 0x3f,0x03,229}, /* 0x26 */
832 { 0xb8,0x06,234}, /* 0x27 */
833 { 0x34,0x02,253}, /* 0x28 */
834 { 0x58,0x04,255}, /* 0x29 */
835 { 0x24,0x01,265}, /* 0x2a */
836 { 0x9b,0x02,267}, /* 0x2b */
837 { 0x70,0x05,270}, /* 0x2c */
838 { 0x25,0x01,272}, /* 0x2d */
839 { 0x9c,0x02,277}, /* 0x2e */
840 { 0x27,0x01,286}, /* 0x2f */
841 { 0x3c,0x02,291}, /* 0x30 */
842 { 0xef,0x0a,292}, /* 0x31 */
843 { 0xf6,0x0a,310}, /* 0x32 */
844 { 0x95,0x01,315}, /* 0x33 */
845 { 0xf0,0x09,324}, /* 0x34 */
846 { 0xfe,0x0a,331}, /* 0x35 */
847 { 0xf3,0x09,332}, /* 0x36 */
848 { 0xea,0x08,340}, /* 0x37 */
849 { 0xe8,0x07,376}, /* 0x38 */
850 { 0xde,0x06,389}, /* 0x39 */
851 { 0x52,0x2a, 54}, /* 0x3a 301 TV - start */
852 { 0x52,0x6a, 27}, /* 0x3b 301 TV */
853 { 0x62,0x24, 70}, /* 0x3c 301 TV */
854 { 0x62,0x64, 70}, /* 0x3d 301 TV */
855 { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
856 { 0x20,0x26, 33}, /* 0x3f 301 TV */
857 { 0x31,0xc2, 39}, /* 0x40 */
858 { 0x2e,0x48, 25}, /* 0x41 Replacement for LCD on 315 for index 0 */
859 { 0x24,0x46, 25}, /* 0x42 Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
860 { 0x26,0x64, 28}, /* 0x43 Replacement for LCD on 315 for index 1 */
861 { 0x37,0x64, 40}, /* 0x44 Replacement for LCD on 315 for index 4 */
862 { 0xa1,0x42,108}, /* 0x45 1280x960 LCD */
863 { 0x37,0x61,100}, /* 0x46 1280x960 LCD */
864 { 0x78,0x27,108}, /* 0x47 */
865 { 0x97,0x2c, 26}, /* 0x48 UNUSED */
866 { 0xce,0x3c, 39}, /* 0x49 UNUSED */
867 { 0x52,0x4a, 36}, /* 0x4a UNUSED */
868 { 0x34,0x61, 95}, /* 0x4b UNUSED */
869 { 0x78,0x27,108}, /* 0x4c UNUSED */
870 { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
871 { 0x41,0x4e, 21}, /* 0x4e */
872 { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
873 { 0x19,0x42, 42}, /* 0x50 UNUSED */
874 { 0x54,0x46, 58}, /* 0x51 UNUSED */
875 { 0x25,0x42, 61}, /* 0x52 UNUSED */
876 { 0x44,0x44, 66}, /* 0x53 UNUSED */
877 { 0x3a,0x62, 70}, /* 0x54 UNUSED */
878 { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
879 { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP, UNUSED */
880 { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
881 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
882 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
883 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
884 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
885 { 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
886 { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
887 { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
888 { 0x52,0x27, 75}, /* 0x5f 1280x720 (TMDS + HDTV) (correct) */
889 { 0xc8,0x48, 77}, /* 0x60 1280x768_2 (SiS LVDS) */
890 { 0x31,0x42, 79}, /* 0x61 1280x768_3 (SiS LVDS) - temp */
891 { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
892 { 0x9c,0x62, 69}, /* 0x63 1280x720 (SiS LVDS) */
893 { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
894 { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
895 { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
896 { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
897 { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
898 { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
899 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
900 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
901 { 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
902 { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
903 { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
904 { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
905 { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
906 { 0x2b,0xc2, 35}, /* 0x71 768@576@60 */
907 { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
908 { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
909 { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
910 { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
911 { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (SiS LVDS) LCD */
912};
913
914static const unsigned char SiS310_SR15[4 * 8] =
915{
916 0x00,0x04,0x60,0x60,
917 0x0f,0x0f,0x0f,0x0f,
918 0xba,0xba,0xba,0xba,
919 0xa9,0xa9,0xac,0xac,
920 0xa0,0xa0,0xa0,0xa8,
921 0x00,0x00,0x02,0x02,
922 0x30,0x30,0x40,0x40,
923 0x00,0xa5,0xfb,0xf6
924};
925
926static const struct SiS_PanelDelayTbl SiS310_PanelDelayTbl[] =
927{
928 {{0x10,0x40}},
929 {{0x10,0x40}},
930 {{0x10,0x40}},
931 {{0x10,0x40}},
932 {{0x10,0x40}},
933 {{0x10,0x40}},
934 {{0x10,0x40}},
935 {{0x10,0x40}},
936 {{0x10,0x40}},
937 {{0x10,0x40}},
938 {{0x10,0x40}},
939 {{0x10,0x40}},
940 {{0x10,0x40}},
941 {{0x10,0x40}},
942 {{0x10,0x40}},
943 {{0x10,0x40}}
944};
945
946static const struct SiS_PanelDelayTbl SiS310_PanelDelayTblLVDS[] =
947{
948 {{0x28,0xc8}},
949 {{0x28,0xc8}},
950 {{0x28,0xc8}},
951 {{0x28,0xc8}},
952 {{0x28,0xc8}},
953 {{0x28,0xc8}},
954 {{0x28,0xc8}},
955 {{0x28,0xc8}},
956 {{0x28,0xc8}},
957 {{0x28,0xc8}},
958 {{0x28,0xc8}},
959 {{0x28,0xc8}},
960 {{0x28,0xc8}},
961 {{0x28,0xc8}},
962 {{0x28,0xc8}},
963 {{0x28,0xc8}}
964};
965
966/**************************************************************/
967/* SIS VIDEO BRIDGE ----------------------------------------- */
968/**************************************************************/
969
970static const struct SiS_LCDData SiS310_St2LCD1024x768Data[] =
971{
972 { 62, 25, 800, 546,1344, 806},
973 { 32, 15, 930, 546,1344, 806},
974 { 62, 25, 800, 546,1344, 806},
975 { 104, 45, 945, 496,1344, 806},
976 { 62, 25, 800, 546,1344, 806},
977 { 31, 18,1008, 624,1344, 806},
978 { 1, 1,1344, 806,1344, 806}
979};
980
981static const struct SiS_LCDData SiS310_ExtLCD1024x768Data[] =
982{
983 { 42, 25,1536, 419,1344, 806},
984 { 48, 25,1536, 369,1344, 806},
985 { 42, 25,1536, 419,1344, 806},
986 { 48, 25,1536, 369,1344, 806},
987 { 12, 5, 896, 500,1344, 806},
988 { 42, 25,1024, 625,1344, 806},
989 { 1, 1,1344, 806,1344, 806}
990};
991
992static const struct SiS_LCDData SiS310_St2LCD1280x1024Data[] =
993{
994 { 22, 5, 800, 510,1650,1088},
995 { 22, 5, 800, 510,1650,1088},
996 { 176, 45, 900, 510,1650,1088},
997 { 176, 45, 900, 510,1650,1088},
998 { 22, 5, 800, 510,1650,1088},
999 { 13, 5,1024, 675,1560,1152},
1000 { 16, 9,1266, 804,1688,1072},
1001 { 1, 1,1688,1066,1688,1066}
1002};
1003
1004static const struct SiS_LCDData SiS310_ExtLCD1280x1024Data[] =
1005{
1006 { 211, 60,1024, 501,1688,1066},
1007 { 211, 60,1024, 508,1688,1066},
1008 { 211, 60,1024, 501,1688,1066},
1009 { 211, 60,1024, 508,1688,1066},
1010 { 211, 60,1024, 500,1688,1066},
1011 { 211, 75,1024, 625,1688,1066},
1012 { 211, 120,1280, 798,1688,1066},
1013 { 1, 1,1688,1066,1688,1066}
1014};
1015
1016static const struct SiS_Part2PortTbl SiS310_CRT2Part2_1024x768_1[] =
1017{
1018 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1019 {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1020 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1021 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
1022 {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1023 {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1024 {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
1025};
1026
1027/**************************************************************/
1028/* LVDS, CHRONTEL ------------------------------------------- */
1029/**************************************************************/
1030
1031static const struct SiS_LVDSData SiS310_CHTVUPALData[] =
1032{
1033 {1008, 625,1008, 625},
1034 {1008, 625,1008, 625},
1035 {1008, 625,1008, 625},
1036 {1008, 625,1008, 625},
1037 { 840, 625, 840, 625},
1038 { 960, 750, 960, 750},
1039 {1400,1000,1400,1000}
1040};
1041
1042static const struct SiS_LVDSData SiS310_CHTVOPALData[] =
1043{
1044 {1008, 625,1008, 625},
1045 {1008, 625,1008, 625},
1046 {1008, 625,1008, 625},
1047 {1008, 625,1008, 625},
1048 { 840, 625, 840, 625},
1049 { 944, 625, 944, 625},
1050 {1400, 875,1400, 875}
1051};
1052
1053static const struct SiS_LVDSData SiS310_CHTVUPALMData[] =
1054{
1055 { 840, 600, 840, 600},
1056 { 840, 600, 840, 600},
1057 { 840, 600, 840, 600},
1058 { 840, 600, 840, 600},
1059 { 784, 600, 784, 600},
1060 {1064, 750,1064, 750},
1061 {1160, 945,1160, 945}
1062};
1063
1064static const struct SiS_LVDSData SiS310_CHTVOPALMData[] =
1065{
1066 { 840, 525, 840, 525},
1067 { 840, 525, 840, 525},
1068 { 840, 525, 840, 525},
1069 { 840, 525, 840, 525},
1070 { 784, 525, 784, 525},
1071 {1040, 700,1040, 700},
1072 {1160, 840,1160, 840}
1073};
1074
1075static const struct SiS_LVDSData SiS310_CHTVUPALNData[] =
1076{
1077 {1008, 625,1008, 625},
1078 {1008, 625,1008, 625},
1079 {1008, 625,1008, 625},
1080 {1008, 625,1008, 625},
1081 { 840, 625, 840, 625},
1082 { 960, 750, 960, 750},
1083 {1400,1000,1400,1000}
1084};
1085
1086static const struct SiS_LVDSData SiS310_CHTVOPALNData[] =
1087{
1088 {1008, 625,1008, 625},
1089 {1008, 625,1008, 625},
1090 {1008, 625,1008, 625},
1091 {1008, 625,1008, 625},
1092 { 840, 625, 840, 625},
1093 { 944, 625, 944, 625},
1094 {1400, 875,1400, 875}
1095};
1096
1097static const struct SiS_LVDSData SiS310_CHTVSOPALData[] = /* (super overscan - no effect on 7019) */
1098{
1099 {1008, 625,1008, 625},
1100 {1008, 625,1008, 625},
1101 {1008, 625,1008, 625},
1102 {1008, 625,1008, 625},
1103 { 840, 625, 840, 625},
1104 { 944, 625, 944, 625},
1105 {1400, 875,1400, 875}
1106};
1107
1108/* CRT1 CRTC for Chrontel TV slave modes */
1109
1110static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UNTSC[] =
1111{
1112 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1113 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
1114 0x00 }},
1115 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1116 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
1117 0x00 }},
1118 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1119 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
1120 0x00 }},
1121 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1122 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
1123 0x00 }},
1124 {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
1125 0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
1126 0x00 }},
1127 {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
1128 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
1129 0x01 }},
1130 {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
1131 0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
1132 0x01}}
1133};
1134
1135static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1ONTSC[] =
1136{
1137 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
1138 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
1139 0x00 }},
1140 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
1141 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
1142 0x00 }},
1143 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
1144 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
1145 0x00 }},
1146 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
1147 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
1148 0x00 }},
1149 {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
1150 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
1151 0x00 }},
1152 {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
1153 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
1154 0x01 }},
1155 {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
1156 0x15,0x88,0xff,0x47,0x70,0x00,0x02,
1157 0x01 }}
1158};
1159
1160static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UPAL[] =
1161{
1162 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1163 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
1164 0x00 }},
1165 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1166 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1167 0x00 }},
1168 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1169 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
1170 0x00 }},
1171 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1172 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1173 0x00 }},
1174 {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
1175 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
1176 0x00 }},
1177 {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
1178 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
1179 0x01 }},
1180 {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
1181 0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
1182 0x01}}
1183};
1184
1185static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1OPAL[] =
1186{
1187 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1188 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1189 0x00 }},
1190 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1191 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1192 0x00 }},
1193 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1194 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1195 0x00 }},
1196 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1197 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1198 0x00 }},
1199 {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
1200 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
1201 0x00 }},
1202 {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
1203 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
1204 0x01 }},
1205 {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
1206 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
1207 0x01 }}
1208};
1209
1210static const struct SiS_CHTVRegData SiS310_CHTVReg_UNTSC[] =
1211{
1212 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1213 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1214 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1215 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1216 {{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
1217 {{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
1218 {{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
1219}; /* WRONG: 0x02: should be 0xfx, because if CIVEnable is clear, this should be set;
1220 0x07: Blacklevel: NTSC/PAL-M: Should be 131 (0x83), and not 0x50/0x5a
1221 PAL/PAL-N: 110 (0x6e)
1222 NTSC-J: 102 (0x66)
1223 0x0c-0x0f: CIV is not default as in datasheet
1224 MISSING: 0x21: Should set D1 to ZERO (for NTSC, PAL-M) or ONE (PAL, NTSC-J)
1225 Most of this is wrong in all NTSC and PAL register arrays. But I won't correct
1226 it as long as it works. For NTSC-J, the blacklevel is corrected in init301.c;
1227 for PAL-M and PAL-N all above is corrected.
1228 */
1229
1230static const struct SiS_CHTVRegData SiS310_CHTVReg_ONTSC[] =
1231{
1232 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1233 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1234 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1235 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1236 {{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
1237 {{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
1238 {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
1239};
1240
1241static const struct SiS_CHTVRegData SiS310_CHTVReg_UPAL[] =
1242{
1243 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1244 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1245 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1246 {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1247 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
1248 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
1249 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
1250};
1251
1252static const struct SiS_CHTVRegData SiS310_CHTVReg_OPAL[] =
1253{
1254 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1255 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1256 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1257 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1258 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
1259 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
1260 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
1261};
1262
1263static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALM[] =
1264{
1265 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1266 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1267 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1268 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1269 {{0x72,0x77,0xfb,0x6e,0x84,0x2e,0x02,0x83,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
1270 {{0xd7,0x77,0xf7,0xc8,0x84,0x3b,0x02,0x83,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
1271 {{0xf6,0x77,0xfb,0x66,0x87,0x32,0x01,0x83,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
1272#if 0 /* Correct blacklevel and CFRB */
1273 {{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
1274 {{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
1275 {{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
1276#endif
1277};
1278
1279static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALM[] =
1280{
1281 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1282 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1283 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1284 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
1285 {{0x71,0x77,0xfb,0x6e,0x84,0x1e,0x00,0x83,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
1286 {{0xd6,0x77,0xf7,0xb6,0x83,0x2c,0x02,0x83,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
1287 {{0xf5,0x77,0xfb,0x66,0x8c,0x21,0x02,0x83,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
1288#if 0 /* Correct blacklevel and CFRB */
1289 {{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
1290 {{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
1291 {{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
1292#endif
1293};
1294
1295static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALN[] =
1296{
1297 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1298 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1299 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1300 {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1301 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1302 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1303 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
1304#if 0 /* Correct blacklevel, CIV and CFRB */
1305 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
1306 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
1307 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
1308#endif
1309};
1310
1311static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALN[] =
1312{
1313 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1314 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1315 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1316 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1317 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1318 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
1319 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
1320#if 0 /* Correct blacklevel, CIV and CFRB */
1321 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
1322 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
1323 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
1324#endif
1325};
1326
1327static const unsigned char SiS310_CHTVVCLKUNTSC[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
1328static const unsigned char SiS310_CHTVVCLKONTSC[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
1329
1330static const unsigned char SiS310_CHTVVCLKUPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
1331static const unsigned char SiS310_CHTVVCLKOPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
1332
1333static const unsigned char SiS310_CHTVVCLKUPALM[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
1334static const unsigned char SiS310_CHTVVCLKOPALM[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
1335
1336static const unsigned char SiS310_CHTVVCLKUPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
1337static const unsigned char SiS310_CHTVVCLKOPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
1338
1339
diff --git a/drivers/video/fbdev/sis/Makefile b/drivers/video/fbdev/sis/Makefile
new file mode 100644
index 000000000000..f7c0046e5b1d
--- /dev/null
+++ b/drivers/video/fbdev/sis/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the SiS framebuffer device driver
3#
4
5obj-$(CONFIG_FB_SIS) += sisfb.o
6
7sisfb-objs := sis_main.o sis_accel.o init.o init301.o initextlfb.o
diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c
new file mode 100644
index 000000000000..bd40f5ecd901
--- /dev/null
+++ b/drivers/video/fbdev/sis/init.c
@@ -0,0 +1,3655 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Mode initializing code (CRT1 section) for
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7 * XGI Volari V3XT/V5/V8, Z7
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9 *
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11 *
12 * If distributed as part of the Linux kernel, the following license terms
13 * apply:
14 *
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
19 * *
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
24 * *
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28 *
29 * Otherwise, the following license terms apply:
30 *
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
33 * * are met:
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
41 * *
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 *
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 *
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56 * Used by permission.
57 */
58
59#include "init.h"
60
61#ifdef CONFIG_FB_SIS_300
62#include "300vtbl.h"
63#endif
64
65#ifdef CONFIG_FB_SIS_315
66#include "310vtbl.h"
67#endif
68
69#if defined(ALLOC_PRAGMA)
70#pragma alloc_text(PAGE,SiSSetMode)
71#endif
72
73/*********************************************/
74/* POINTER INITIALIZATION */
75/*********************************************/
76
77#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
78static void
79InitCommonPointer(struct SiS_Private *SiS_Pr)
80{
81 SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable;
82 SiS_Pr->SiS_StResInfo = SiS_StResInfo;
83 SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
84 SiS_Pr->SiS_StandTable = SiS_StandTable;
85
86 SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
87 SiS_Pr->SiS_PALTiming = SiS_PALTiming;
88 SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
89 SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing;
90
91 SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming;
92 SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
93 SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
94#if 0
95 SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
96 SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
97#endif
98
99 SiS_Pr->SiS_StPALData = SiS_StPALData;
100 SiS_Pr->SiS_ExtPALData = SiS_ExtPALData;
101 SiS_Pr->SiS_StNTSCData = SiS_StNTSCData;
102 SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
103 SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData;
104 SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
105 SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
106 SiS_Pr->SiS_St525iData = SiS_StNTSCData;
107 SiS_Pr->SiS_St525pData = SiS_St525pData;
108 SiS_Pr->SiS_St750pData = SiS_St750pData;
109 SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
110 SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
111 SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
112
113 SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
114 SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
115
116 SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data;
117 SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data;
118 SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
119 SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
120 SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data;
121 SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data;
122 SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
123 SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
124 SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
125 SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data;
126 SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data;
127 SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
128 SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
129
130 SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1;
131 SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2;
132 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
133 SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
134 SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
135 SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
136
137 SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1;
138 SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2;
139 SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H;
140 SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3;
141 SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H;
142 SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
143 SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
144#if 0
145 SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
146 SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
147 SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
148 SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
149#endif
150
151 SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
152 SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
153
154 SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
155 SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
156}
157#endif
158
159#ifdef CONFIG_FB_SIS_300
160static void
161InitTo300Pointer(struct SiS_Private *SiS_Pr)
162{
163 InitCommonPointer(SiS_Pr);
164
165 SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
166 SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
167 SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
168 SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
169 if(SiS_Pr->ChipType == SIS_300) {
170 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
171 } else {
172 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
173 }
174 SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
175 SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData;
176
177 SiS_Pr->SiS_SR15 = SiS300_SR15;
178
179 SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
180 SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
181
182 SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data;
183 SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data;
184 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data;
185 SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
186
187 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
188 SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
189 SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
190
191 SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
192 SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
193 SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */
194 SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */
195 SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData; /* not supported on 300 series */
196 SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */
197 SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
198
199 SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1;
200 SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2;
201 SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
202 SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
203 SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
204
205 SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
206 SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
207 SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
208 SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
209
210 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
211 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
212 SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL;
213 SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL;
214 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
215 SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
216 SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
217 SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL;
218 SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL;
219 SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC; /* not supported on 300 series */
220 SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC; /* not supported on 300 series */
221 SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL; /* not supported on 300 series */
222 SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL; /* not supported on 300 series */
223 SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
224 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
225 SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
226 SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
227 SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
228 SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */
229 SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */
230 SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */
231 SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */
232 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
233}
234#endif
235
236#ifdef CONFIG_FB_SIS_315
237static void
238InitTo310Pointer(struct SiS_Private *SiS_Pr)
239{
240 InitCommonPointer(SiS_Pr);
241
242 SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
243 SiS_Pr->SiS_RefIndex = SiS310_RefIndex;
244 SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
245 if(SiS_Pr->ChipType >= SIS_340) {
246 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 + XGI */
247 } else if(SiS_Pr->ChipType >= SIS_761) {
248 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */
249 } else if(SiS_Pr->ChipType >= SIS_760) {
250 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */
251 } else if(SiS_Pr->ChipType >= SIS_661) {
252 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */
253 } else if(SiS_Pr->ChipType == SIS_330) {
254 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */
255 } else if(SiS_Pr->ChipType > SIS_315PRO) {
256 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */
257 } else {
258 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */
259 }
260 if(SiS_Pr->ChipType >= SIS_340) {
261 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
262 } else {
263 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
264 }
265 SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
266 SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
267
268 SiS_Pr->SiS_SR15 = SiS310_SR15;
269
270 SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
271 SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
272
273 SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data;
274 SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data;
275 SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data;
276 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data;
277
278 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
279
280 SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
281 SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
282 SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
283 SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
284 SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
285 SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
286 SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
287
288 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
289 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
290 SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
291 SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
292 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
293
294 SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
295 SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
296 SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL;
297 SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL;
298 SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
299 SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
300 SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
301 SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
302 SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
303
304 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
305 SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
306 SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
307 SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
308 SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
309 SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
310 SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
311 SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
312 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
313}
314#endif
315
316bool
317SiSInitPtr(struct SiS_Private *SiS_Pr)
318{
319 if(SiS_Pr->ChipType < SIS_315H) {
320#ifdef CONFIG_FB_SIS_300
321 InitTo300Pointer(SiS_Pr);
322#else
323 return false;
324#endif
325 } else {
326#ifdef CONFIG_FB_SIS_315
327 InitTo310Pointer(SiS_Pr);
328#else
329 return false;
330#endif
331 }
332 return true;
333}
334
335/*********************************************/
336/* HELPER: Get ModeID */
337/*********************************************/
338
339static
340unsigned short
341SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
342 int Depth, bool FSTN, int LCDwidth, int LCDheight)
343{
344 unsigned short ModeIndex = 0;
345
346 switch(HDisplay)
347 {
348 case 320:
349 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
350 else if(VDisplay == 240) {
351 if((VBFlags & CRT2_LCD) && (FSTN))
352 ModeIndex = ModeIndex_320x240_FSTN[Depth];
353 else
354 ModeIndex = ModeIndex_320x240[Depth];
355 }
356 break;
357 case 400:
358 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
359 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
360 }
361 break;
362 case 512:
363 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
364 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
365 }
366 break;
367 case 640:
368 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
369 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
370 break;
371 case 720:
372 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
373 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
374 break;
375 case 768:
376 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
377 break;
378 case 800:
379 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
380 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
381 break;
382 case 848:
383 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
384 break;
385 case 856:
386 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
387 break;
388 case 960:
389 if(VGAEngine == SIS_315_VGA) {
390 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
391 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
392 }
393 break;
394 case 1024:
395 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
396 else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
397 else if(VGAEngine == SIS_300_VGA) {
398 if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
399 }
400 break;
401 case 1152:
402 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
403 if(VGAEngine == SIS_300_VGA) {
404 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
405 }
406 break;
407 case 1280:
408 switch(VDisplay) {
409 case 720:
410 ModeIndex = ModeIndex_1280x720[Depth];
411 break;
412 case 768:
413 if(VGAEngine == SIS_300_VGA) {
414 ModeIndex = ModeIndex_300_1280x768[Depth];
415 } else {
416 ModeIndex = ModeIndex_310_1280x768[Depth];
417 }
418 break;
419 case 800:
420 if(VGAEngine == SIS_315_VGA) {
421 ModeIndex = ModeIndex_1280x800[Depth];
422 }
423 break;
424 case 854:
425 if(VGAEngine == SIS_315_VGA) {
426 ModeIndex = ModeIndex_1280x854[Depth];
427 }
428 break;
429 case 960:
430 ModeIndex = ModeIndex_1280x960[Depth];
431 break;
432 case 1024:
433 ModeIndex = ModeIndex_1280x1024[Depth];
434 break;
435 }
436 break;
437 case 1360:
438 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
439 if(VGAEngine == SIS_300_VGA) {
440 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
441 }
442 break;
443 case 1400:
444 if(VGAEngine == SIS_315_VGA) {
445 if(VDisplay == 1050) {
446 ModeIndex = ModeIndex_1400x1050[Depth];
447 }
448 }
449 break;
450 case 1600:
451 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
452 break;
453 case 1680:
454 if(VGAEngine == SIS_315_VGA) {
455 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
456 }
457 break;
458 case 1920:
459 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
460 else if(VGAEngine == SIS_315_VGA) {
461 if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
462 }
463 break;
464 case 2048:
465 if(VDisplay == 1536) {
466 if(VGAEngine == SIS_300_VGA) {
467 ModeIndex = ModeIndex_300_2048x1536[Depth];
468 } else {
469 ModeIndex = ModeIndex_310_2048x1536[Depth];
470 }
471 }
472 break;
473 }
474
475 return ModeIndex;
476}
477
478unsigned short
479SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
480 int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
481 unsigned int VBFlags2)
482{
483 unsigned short ModeIndex = 0;
484
485 if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
486
487 switch(HDisplay)
488 {
489 case 320:
490 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
491 if(VDisplay == 200) {
492 if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
493 } else if(VDisplay == 240) {
494 if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
495 else if(VGAEngine == SIS_315_VGA) {
496 ModeIndex = ModeIndex_320x240_FSTN[Depth];
497 }
498 }
499 }
500 break;
501 case 400:
502 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
503 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
504 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
505 }
506 }
507 break;
508 case 512:
509 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
510 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
511 if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
512 if(VDisplay == 384) {
513 ModeIndex = ModeIndex_512x384[Depth];
514 }
515 }
516 }
517 }
518 break;
519 case 640:
520 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
521 else if(VDisplay == 400) {
522 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
523 ModeIndex = ModeIndex_640x400[Depth];
524 }
525 break;
526 case 800:
527 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
528 break;
529 case 848:
530 if(CustomT == CUT_PANEL848) {
531 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
532 }
533 break;
534 case 856:
535 if(CustomT == CUT_PANEL856) {
536 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
537 }
538 break;
539 case 1024:
540 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
541 else if(VGAEngine == SIS_300_VGA) {
542 if((VDisplay == 600) && (LCDheight == 600)) {
543 ModeIndex = ModeIndex_1024x600[Depth];
544 }
545 }
546 break;
547 case 1152:
548 if(VGAEngine == SIS_300_VGA) {
549 if((VDisplay == 768) && (LCDheight == 768)) {
550 ModeIndex = ModeIndex_1152x768[Depth];
551 }
552 }
553 break;
554 case 1280:
555 if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
556 else if(VGAEngine == SIS_315_VGA) {
557 if((VDisplay == 768) && (LCDheight == 768)) {
558 ModeIndex = ModeIndex_310_1280x768[Depth];
559 }
560 }
561 break;
562 case 1360:
563 if(VGAEngine == SIS_300_VGA) {
564 if(CustomT == CUT_BARCO1366) {
565 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
566 }
567 }
568 if(CustomT == CUT_PANEL848) {
569 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
570 }
571 break;
572 case 1400:
573 if(VGAEngine == SIS_315_VGA) {
574 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
575 }
576 break;
577 case 1600:
578 if(VGAEngine == SIS_315_VGA) {
579 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
580 }
581 break;
582 }
583
584 } else if(VBFlags2 & VB2_SISBRIDGE) {
585
586 switch(HDisplay)
587 {
588 case 320:
589 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
590 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
591 break;
592 case 400:
593 if(LCDwidth >= 800 && LCDheight >= 600) {
594 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
595 }
596 break;
597 case 512:
598 if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
599 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
600 }
601 break;
602 case 640:
603 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
604 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
605 break;
606 case 720:
607 if(VGAEngine == SIS_315_VGA) {
608 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
609 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
610 }
611 break;
612 case 768:
613 if(VGAEngine == SIS_315_VGA) {
614 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
615 }
616 break;
617 case 800:
618 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
619 if(VGAEngine == SIS_315_VGA) {
620 if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
621 }
622 break;
623 case 848:
624 if(VGAEngine == SIS_315_VGA) {
625 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
626 }
627 break;
628 case 856:
629 if(VGAEngine == SIS_315_VGA) {
630 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
631 }
632 break;
633 case 960:
634 if(VGAEngine == SIS_315_VGA) {
635 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
636 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
637 }
638 break;
639 case 1024:
640 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
641 if(VGAEngine == SIS_315_VGA) {
642 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
643 }
644 break;
645 case 1152:
646 if(VGAEngine == SIS_315_VGA) {
647 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
648 }
649 break;
650 case 1280:
651 switch(VDisplay) {
652 case 720:
653 ModeIndex = ModeIndex_1280x720[Depth];
654 break;
655 case 768:
656 if(VGAEngine == SIS_300_VGA) {
657 ModeIndex = ModeIndex_300_1280x768[Depth];
658 } else {
659 ModeIndex = ModeIndex_310_1280x768[Depth];
660 }
661 break;
662 case 800:
663 if(VGAEngine == SIS_315_VGA) {
664 ModeIndex = ModeIndex_1280x800[Depth];
665 }
666 break;
667 case 854:
668 if(VGAEngine == SIS_315_VGA) {
669 ModeIndex = ModeIndex_1280x854[Depth];
670 }
671 break;
672 case 960:
673 ModeIndex = ModeIndex_1280x960[Depth];
674 break;
675 case 1024:
676 ModeIndex = ModeIndex_1280x1024[Depth];
677 break;
678 }
679 break;
680 case 1360:
681 if(VGAEngine == SIS_315_VGA) { /* OVER1280 only? */
682 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
683 }
684 break;
685 case 1400:
686 if(VGAEngine == SIS_315_VGA) {
687 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
688 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
689 }
690 }
691 break;
692 case 1600:
693 if(VGAEngine == SIS_315_VGA) {
694 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
695 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
696 }
697 }
698 break;
699#ifndef VB_FORBID_CRT2LCD_OVER_1600
700 case 1680:
701 if(VGAEngine == SIS_315_VGA) {
702 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
703 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
704 }
705 }
706 break;
707 case 1920:
708 if(VGAEngine == SIS_315_VGA) {
709 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
710 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
711 }
712 }
713 break;
714 case 2048:
715 if(VGAEngine == SIS_315_VGA) {
716 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
717 if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
718 }
719 }
720 break;
721#endif
722 }
723 }
724
725 return ModeIndex;
726}
727
728unsigned short
729SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
730 unsigned int VBFlags2)
731{
732 unsigned short ModeIndex = 0;
733
734 if(VBFlags2 & VB2_CHRONTEL) {
735
736 switch(HDisplay)
737 {
738 case 512:
739 if(VGAEngine == SIS_315_VGA) {
740 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
741 }
742 break;
743 case 640:
744 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
745 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
746 break;
747 case 800:
748 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
749 break;
750 case 1024:
751 if(VGAEngine == SIS_315_VGA) {
752 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
753 }
754 break;
755 }
756
757 } else if(VBFlags2 & VB2_SISTVBRIDGE) {
758
759 switch(HDisplay)
760 {
761 case 320:
762 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
763 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
764 break;
765 case 400:
766 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
767 break;
768 case 512:
769 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
770 (VBFlags & TV_HIVISION) ||
771 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
772 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
773 }
774 break;
775 case 640:
776 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
777 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
778 break;
779 case 720:
780 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
781 if(VDisplay == 480) {
782 ModeIndex = ModeIndex_720x480[Depth];
783 } else if(VDisplay == 576) {
784 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
785 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
786 ModeIndex = ModeIndex_720x576[Depth];
787 }
788 }
789 break;
790 case 768:
791 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
792 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
793 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
794 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
795 }
796 }
797 break;
798 case 800:
799 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
800 else if(VDisplay == 480) {
801 if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
802 ModeIndex = ModeIndex_800x480[Depth];
803 }
804 }
805 break;
806 case 960:
807 if(VGAEngine == SIS_315_VGA) {
808 if(VDisplay == 600) {
809 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
810 ModeIndex = ModeIndex_960x600[Depth];
811 }
812 }
813 }
814 break;
815 case 1024:
816 if(VDisplay == 768) {
817 if(VBFlags2 & VB2_30xBLV) {
818 ModeIndex = ModeIndex_1024x768[Depth];
819 }
820 } else if(VDisplay == 576) {
821 if( (VBFlags & TV_HIVISION) ||
822 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
823 ((VBFlags2 & VB2_30xBLV) &&
824 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
825 ModeIndex = ModeIndex_1024x576[Depth];
826 }
827 }
828 break;
829 case 1280:
830 if(VDisplay == 720) {
831 if((VBFlags & TV_HIVISION) ||
832 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
833 ModeIndex = ModeIndex_1280x720[Depth];
834 }
835 } else if(VDisplay == 1024) {
836 if((VBFlags & TV_HIVISION) ||
837 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
838 ModeIndex = ModeIndex_1280x1024[Depth];
839 }
840 }
841 break;
842 }
843 }
844 return ModeIndex;
845}
846
847unsigned short
848SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
849 unsigned int VBFlags2)
850{
851 if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
852
853 if(HDisplay >= 1920) return 0;
854
855 switch(HDisplay)
856 {
857 case 1600:
858 if(VDisplay == 1200) {
859 if(VGAEngine != SIS_315_VGA) return 0;
860 if(!(VBFlags2 & VB2_30xB)) return 0;
861 }
862 break;
863 case 1680:
864 if(VDisplay == 1050) {
865 if(VGAEngine != SIS_315_VGA) return 0;
866 if(!(VBFlags2 & VB2_30xB)) return 0;
867 }
868 break;
869 }
870
871 return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
872}
873
874
875/*********************************************/
876/* HELPER: SetReg, GetReg */
877/*********************************************/
878
879void
880SiS_SetReg(SISIOADDRESS port, u8 index, u8 data)
881{
882 outb(index, port);
883 outb(data, port + 1);
884}
885
886void
887SiS_SetRegByte(SISIOADDRESS port, u8 data)
888{
889 outb(data, port);
890}
891
892void
893SiS_SetRegShort(SISIOADDRESS port, u16 data)
894{
895 outw(data, port);
896}
897
898void
899SiS_SetRegLong(SISIOADDRESS port, u32 data)
900{
901 outl(data, port);
902}
903
904u8
905SiS_GetReg(SISIOADDRESS port, u8 index)
906{
907 outb(index, port);
908 return inb(port + 1);
909}
910
911u8
912SiS_GetRegByte(SISIOADDRESS port)
913{
914 return inb(port);
915}
916
917u16
918SiS_GetRegShort(SISIOADDRESS port)
919{
920 return inw(port);
921}
922
923u32
924SiS_GetRegLong(SISIOADDRESS port)
925{
926 return inl(port);
927}
928
929void
930SiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR)
931{
932 u8 temp;
933
934 temp = SiS_GetReg(Port, Index);
935 temp = (temp & (DataAND)) | DataOR;
936 SiS_SetReg(Port, Index, temp);
937}
938
939void
940SiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND)
941{
942 u8 temp;
943
944 temp = SiS_GetReg(Port, Index);
945 temp &= DataAND;
946 SiS_SetReg(Port, Index, temp);
947}
948
949void
950SiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR)
951{
952 u8 temp;
953
954 temp = SiS_GetReg(Port, Index);
955 temp |= DataOR;
956 SiS_SetReg(Port, Index, temp);
957}
958
959/*********************************************/
960/* HELPER: DisplayOn, DisplayOff */
961/*********************************************/
962
963void
964SiS_DisplayOn(struct SiS_Private *SiS_Pr)
965{
966 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
967}
968
969void
970SiS_DisplayOff(struct SiS_Private *SiS_Pr)
971{
972 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
973}
974
975
976/*********************************************/
977/* HELPER: Init Port Addresses */
978/*********************************************/
979
980void
981SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
982{
983 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
984 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
985 SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
986 SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
987 SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
988 SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
989 SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
990 SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
991 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
992 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
993 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
994 SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
995 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
996 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
997 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
998 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
999 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
1000 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
1001 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
1002 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;
1003 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
1004 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
1005}
1006
1007/*********************************************/
1008/* HELPER: GetSysFlags */
1009/*********************************************/
1010
1011static void
1012SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
1013{
1014 unsigned char cr5f, temp1, temp2;
1015
1016 /* 661 and newer: NEVER write non-zero to SR11[7:4] */
1017 /* (SR11 is used for DDC and in enable/disablebridge) */
1018 SiS_Pr->SiS_SensibleSR11 = false;
1019 SiS_Pr->SiS_MyCR63 = 0x63;
1020 if(SiS_Pr->ChipType >= SIS_330) {
1021 SiS_Pr->SiS_MyCR63 = 0x53;
1022 if(SiS_Pr->ChipType >= SIS_661) {
1023 SiS_Pr->SiS_SensibleSR11 = true;
1024 }
1025 }
1026
1027 /* You should use the macros, not these flags directly */
1028
1029 SiS_Pr->SiS_SysFlags = 0;
1030 if(SiS_Pr->ChipType == SIS_650) {
1031 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1032 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1033 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1034 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1035 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1036 if((!temp1) || (temp2)) {
1037 switch(cr5f) {
1038 case 0x80:
1039 case 0x90:
1040 case 0xc0:
1041 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1042 break;
1043 case 0xa0:
1044 case 0xb0:
1045 case 0xe0:
1046 SiS_Pr->SiS_SysFlags |= SF_Is651;
1047 break;
1048 }
1049 } else {
1050 switch(cr5f) {
1051 case 0x90:
1052 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1053 switch(temp1) {
1054 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1055 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1056 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1057 }
1058 break;
1059 case 0xb0:
1060 SiS_Pr->SiS_SysFlags |= SF_Is652;
1061 break;
1062 default:
1063 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1064 break;
1065 }
1066 }
1067 }
1068
1069 if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
1070 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
1071 SiS_Pr->SiS_SysFlags |= SF_760LFB;
1072 }
1073 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
1074 SiS_Pr->SiS_SysFlags |= SF_760UMA;
1075 }
1076 }
1077}
1078
1079/*********************************************/
1080/* HELPER: Init PCI & Engines */
1081/*********************************************/
1082
1083static void
1084SiSInitPCIetc(struct SiS_Private *SiS_Pr)
1085{
1086 switch(SiS_Pr->ChipType) {
1087#ifdef CONFIG_FB_SIS_300
1088 case SIS_300:
1089 case SIS_540:
1090 case SIS_630:
1091 case SIS_730:
1092 /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1093 * - RELOCATED VGA IO ENABLED (0x20)
1094 * - MMIO ENABLED (0x01)
1095 * Leave other bits untouched.
1096 */
1097 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1098 /* - Enable 2D (0x40)
1099 * - Enable 3D (0x02)
1100 * - Enable 3D Vertex command fetch (0x10) ?
1101 * - Enable 3D command parser (0x08) ?
1102 */
1103 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1104 break;
1105#endif
1106#ifdef CONFIG_FB_SIS_315
1107 case SIS_315H:
1108 case SIS_315:
1109 case SIS_315PRO:
1110 case SIS_650:
1111 case SIS_740:
1112 case SIS_330:
1113 case SIS_661:
1114 case SIS_741:
1115 case SIS_660:
1116 case SIS_760:
1117 case SIS_761:
1118 case SIS_340:
1119 case XGI_40:
1120 /* See above */
1121 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1122 /* - Enable 3D G/L transformation engine (0x80)
1123 * - Enable 2D (0x40)
1124 * - Enable 3D vertex command fetch (0x10)
1125 * - Enable 3D command parser (0x08)
1126 * - Enable 3D (0x02)
1127 */
1128 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1129 break;
1130 case XGI_20:
1131 case SIS_550:
1132 /* See above */
1133 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1134 /* No 3D engine ! */
1135 /* - Enable 2D (0x40)
1136 * - disable 3D
1137 */
1138 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
1139 break;
1140#endif
1141 default:
1142 break;
1143 }
1144}
1145
1146/*********************************************/
1147/* HELPER: SetLVDSetc */
1148/*********************************************/
1149
1150static
1151void
1152SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
1153{
1154 unsigned short temp;
1155
1156 SiS_Pr->SiS_IF_DEF_LVDS = 0;
1157 SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1158 SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1159 SiS_Pr->SiS_IF_DEF_CONEX = 0;
1160
1161 SiS_Pr->SiS_ChrontelInit = 0;
1162
1163 if(SiS_Pr->ChipType == XGI_20) return;
1164
1165 /* Check for SiS30x first */
1166 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1167 if((temp == 1) || (temp == 2)) return;
1168
1169 switch(SiS_Pr->ChipType) {
1170#ifdef CONFIG_FB_SIS_300
1171 case SIS_540:
1172 case SIS_630:
1173 case SIS_730:
1174 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1175 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1176 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1177 if((temp == 4) || (temp == 5)) {
1178 /* Save power status (and error check) - UNUSED */
1179 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1180 SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1181 }
1182 break;
1183#endif
1184#ifdef CONFIG_FB_SIS_315
1185 case SIS_550:
1186 case SIS_650:
1187 case SIS_740:
1188 case SIS_330:
1189 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1190 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1191 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1192 break;
1193 case SIS_661:
1194 case SIS_741:
1195 case SIS_660:
1196 case SIS_760:
1197 case SIS_761:
1198 case SIS_340:
1199 case XGI_20:
1200 case XGI_40:
1201 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
1202 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1203 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1204 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
1205 break;
1206#endif
1207 default:
1208 break;
1209 }
1210}
1211
1212/*********************************************/
1213/* HELPER: Enable DSTN/FSTN */
1214/*********************************************/
1215
1216void
1217SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
1218{
1219 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1220}
1221
1222void
1223SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
1224{
1225 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1226}
1227
1228/*********************************************/
1229/* HELPER: Get modeflag */
1230/*********************************************/
1231
1232unsigned short
1233SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1234 unsigned short ModeIdIndex)
1235{
1236 if(SiS_Pr->UseCustomMode) {
1237 return SiS_Pr->CModeFlag;
1238 } else if(ModeNo <= 0x13) {
1239 return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1240 } else {
1241 return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1242 }
1243}
1244
1245/*********************************************/
1246/* HELPER: Determine ROM usage */
1247/*********************************************/
1248
1249bool
1250SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
1251{
1252 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1253 unsigned short romversoffs, romvmaj = 1, romvmin = 0;
1254
1255 if(SiS_Pr->ChipType >= XGI_20) {
1256 /* XGI ROMs don't qualify */
1257 return false;
1258 } else if(SiS_Pr->ChipType >= SIS_761) {
1259 /* I very much assume 761, 340 and newer will use new layout */
1260 return true;
1261 } else if(SiS_Pr->ChipType >= SIS_661) {
1262 if((ROMAddr[0x1a] == 'N') &&
1263 (ROMAddr[0x1b] == 'e') &&
1264 (ROMAddr[0x1c] == 'w') &&
1265 (ROMAddr[0x1d] == 'V')) {
1266 return true;
1267 }
1268 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
1269 if(romversoffs) {
1270 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
1271 romvmaj = ROMAddr[romversoffs] - '0';
1272 romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
1273 }
1274 }
1275 if((romvmaj != 0) || (romvmin >= 92)) {
1276 return true;
1277 }
1278 } else if(IS_SIS650740) {
1279 if((ROMAddr[0x1a] == 'N') &&
1280 (ROMAddr[0x1b] == 'e') &&
1281 (ROMAddr[0x1c] == 'w') &&
1282 (ROMAddr[0x1d] == 'V')) {
1283 return true;
1284 }
1285 }
1286 return false;
1287}
1288
1289static void
1290SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
1291{
1292 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1293 unsigned short romptr = 0;
1294
1295 SiS_Pr->SiS_UseROM = false;
1296 SiS_Pr->SiS_ROMNew = false;
1297 SiS_Pr->SiS_PWDOffset = 0;
1298
1299 if(SiS_Pr->ChipType >= XGI_20) return;
1300
1301 if((ROMAddr) && (SiS_Pr->UseROM)) {
1302 if(SiS_Pr->ChipType == SIS_300) {
1303 /* 300: We check if the code starts below 0x220 by
1304 * checking the jmp instruction at the beginning
1305 * of the BIOS image.
1306 */
1307 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1308 SiS_Pr->SiS_UseROM = true;
1309 } else if(SiS_Pr->ChipType < SIS_315H) {
1310 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
1311 * the others do as well
1312 */
1313 SiS_Pr->SiS_UseROM = true;
1314 } else {
1315 /* 315/330 series stick to the standard(s) */
1316 SiS_Pr->SiS_UseROM = true;
1317 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
1318 SiS_Pr->SiS_EMIOffset = 14;
1319 SiS_Pr->SiS_PWDOffset = 17;
1320 SiS_Pr->SiS661LCD2TableSize = 36;
1321 /* Find out about LCD data table entry size */
1322 if((romptr = SISGETROMW(0x0102))) {
1323 if(ROMAddr[romptr + (32 * 16)] == 0xff)
1324 SiS_Pr->SiS661LCD2TableSize = 32;
1325 else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1326 SiS_Pr->SiS661LCD2TableSize = 34;
1327 else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */
1328 SiS_Pr->SiS661LCD2TableSize = 36;
1329 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */
1330 (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */
1331 SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */
1332 SiS_Pr->SiS_EMIOffset = 16;
1333 SiS_Pr->SiS_PWDOffset = 19;
1334 }
1335 }
1336 }
1337 }
1338 }
1339}
1340
1341/*********************************************/
1342/* HELPER: SET SEGMENT REGISTERS */
1343/*********************************************/
1344
1345static void
1346SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
1347{
1348 unsigned short temp;
1349
1350 value &= 0x00ff;
1351 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
1352 temp |= (value >> 4);
1353 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1354 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
1355 temp |= (value & 0x0f);
1356 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1357}
1358
1359static void
1360SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
1361{
1362 unsigned short temp;
1363
1364 value &= 0x00ff;
1365 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
1366 temp |= (value & 0xf0);
1367 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1368 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
1369 temp |= (value << 4);
1370 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1371}
1372
1373static void
1374SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
1375{
1376 SiS_SetSegRegLower(SiS_Pr, value);
1377 SiS_SetSegRegUpper(SiS_Pr, value);
1378}
1379
1380static void
1381SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
1382{
1383 SiS_SetSegmentReg(SiS_Pr, 0);
1384}
1385
1386static void
1387SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
1388{
1389 unsigned short temp = value >> 8;
1390
1391 temp &= 0x07;
1392 temp |= (temp << 4);
1393 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
1394 SiS_SetSegmentReg(SiS_Pr, value);
1395}
1396
1397static void
1398SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
1399{
1400 SiS_SetSegmentRegOver(SiS_Pr, 0);
1401}
1402
1403static void
1404SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
1405{
1406 if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
1407 SiS_ResetSegmentReg(SiS_Pr);
1408 SiS_ResetSegmentRegOver(SiS_Pr);
1409 }
1410}
1411
1412/*********************************************/
1413/* HELPER: GetVBType */
1414/*********************************************/
1415
1416static
1417void
1418SiS_GetVBType(struct SiS_Private *SiS_Pr)
1419{
1420 unsigned short flag = 0, rev = 0, nolcd = 0;
1421 unsigned short p4_0f, p4_25, p4_27;
1422
1423 SiS_Pr->SiS_VBType = 0;
1424
1425 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1426 return;
1427
1428 if(SiS_Pr->ChipType == XGI_20)
1429 return;
1430
1431 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1432
1433 if(flag > 3)
1434 return;
1435
1436 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1437
1438 if(flag >= 2) {
1439 SiS_Pr->SiS_VBType = VB_SIS302B;
1440 } else if(flag == 1) {
1441 if(rev >= 0xC0) {
1442 SiS_Pr->SiS_VBType = VB_SIS301C;
1443 } else if(rev >= 0xB0) {
1444 SiS_Pr->SiS_VBType = VB_SIS301B;
1445 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
1446 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1447 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1448 } else {
1449 SiS_Pr->SiS_VBType = VB_SIS301;
1450 }
1451 }
1452 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1453 if(rev >= 0xE0) {
1454 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1455 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1456 else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
1457 } else if(rev >= 0xD0) {
1458 SiS_Pr->SiS_VBType = VB_SIS301LV;
1459 }
1460 }
1461 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
1462 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1463 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1464 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1465 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1466 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1467 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1468 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1469 SiS_Pr->SiS_VBType |= VB_UMC;
1470 }
1471 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1472 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1473 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1474 }
1475}
1476
1477/*********************************************/
1478/* HELPER: Check RAM size */
1479/*********************************************/
1480
1481static bool
1482SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1483 unsigned short ModeIdIndex)
1484{
1485 unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
1486 unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1487 unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
1488
1489 if(!AdapterMemSize) return true;
1490
1491 if(AdapterMemSize < memorysize) return false;
1492 return true;
1493}
1494
1495/*********************************************/
1496/* HELPER: Get DRAM type */
1497/*********************************************/
1498
1499#ifdef CONFIG_FB_SIS_315
1500static unsigned char
1501SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1502{
1503 unsigned char data;
1504
1505 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1506 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1507 } else {
1508 if(SiS_Pr->ChipType >= XGI_20) {
1509 /* Do I need this? SR17 seems to be zero anyway... */
1510 data = 0;
1511 } else if(SiS_Pr->ChipType >= SIS_340) {
1512 /* TODO */
1513 data = 0;
1514 } if(SiS_Pr->ChipType >= SIS_661) {
1515 if(SiS_Pr->SiS_ROMNew) {
1516 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1517 } else {
1518 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1519 }
1520 } else if(IS_SIS550650740) {
1521 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1522 } else { /* 315, 330 */
1523 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1524 if(SiS_Pr->ChipType == SIS_330) {
1525 if(data > 1) {
1526 switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
1527 case 0x00: data = 1; break;
1528 case 0x10: data = 3; break;
1529 case 0x20: data = 3; break;
1530 case 0x30: data = 2; break;
1531 }
1532 } else {
1533 data = 0;
1534 }
1535 }
1536 }
1537 }
1538
1539 return data;
1540}
1541
1542static unsigned short
1543SiS_GetMCLK(struct SiS_Private *SiS_Pr)
1544{
1545 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1546 unsigned short index;
1547
1548 index = SiS_Get310DRAMType(SiS_Pr);
1549 if(SiS_Pr->ChipType >= SIS_661) {
1550 if(SiS_Pr->SiS_ROMNew) {
1551 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
1552 }
1553 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1554 } else if(index >= 4) {
1555 return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
1556 } else {
1557 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1558 }
1559}
1560#endif
1561
1562/*********************************************/
1563/* HELPER: ClearBuffer */
1564/*********************************************/
1565
1566static void
1567SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1568{
1569 unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
1570 unsigned int memsize = SiS_Pr->VideoMemorySize;
1571 unsigned short SISIOMEMTYPE *pBuffer;
1572 int i;
1573
1574 if(!memaddr || !memsize) return;
1575
1576 if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1577 if(ModeNo > 0x13) {
1578 memset_io(memaddr, 0, memsize);
1579 } else {
1580 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1581 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
1582 }
1583 } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
1584 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1585 for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
1586 } else {
1587 memset_io(memaddr, 0, 0x8000);
1588 }
1589}
1590
1591/*********************************************/
1592/* HELPER: SearchModeID */
1593/*********************************************/
1594
1595bool
1596SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1597 unsigned short *ModeIdIndex)
1598{
1599 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
1600
1601 if((*ModeNo) <= 0x13) {
1602
1603 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1604
1605 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1606 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
1607 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
1608 }
1609
1610 if((*ModeNo) == 0x07) {
1611 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1612 /* else 350 lines */
1613 }
1614 if((*ModeNo) <= 0x03) {
1615 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1616 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1617 /* else 350 lines */
1618 }
1619 /* else 200 lines */
1620
1621 } else {
1622
1623 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1624 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
1625 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
1626 }
1627
1628 }
1629 return true;
1630}
1631
1632/*********************************************/
1633/* HELPER: GetModePtr */
1634/*********************************************/
1635
1636unsigned short
1637SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1638{
1639 unsigned short index;
1640
1641 if(ModeNo <= 0x13) {
1642 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
1643 } else {
1644 if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
1645 else index = 0x0F;
1646 }
1647 return index;
1648}
1649
1650/*********************************************/
1651/* HELPERS: Get some indices */
1652/*********************************************/
1653
1654unsigned short
1655SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1656{
1657 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1658 if(UseWide == 1) {
1659 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
1660 } else {
1661 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
1662 }
1663 } else {
1664 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
1665 }
1666}
1667
1668unsigned short
1669SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1670{
1671 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1672 if(UseWide == 1) {
1673 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
1674 } else {
1675 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
1676 }
1677 } else {
1678 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
1679 }
1680}
1681
1682/*********************************************/
1683/* HELPER: LowModeTests */
1684/*********************************************/
1685
1686static bool
1687SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1688{
1689 unsigned short temp, temp1, temp2;
1690
1691 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
1692 return true;
1693 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
1694 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
1695 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1696 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
1697 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1698 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
1699 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
1700 if((SiS_Pr->ChipType >= SIS_315H) ||
1701 (SiS_Pr->ChipType == SIS_300)) {
1702 if(temp2 == 0x55) return false;
1703 else return true;
1704 } else {
1705 if(temp2 != 0x55) return true;
1706 else {
1707 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
1708 return false;
1709 }
1710 }
1711}
1712
1713static void
1714SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1715{
1716 if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
1717 SiS_Pr->SiS_SetFlag |= LowModeTests;
1718 }
1719}
1720
1721/*********************************************/
1722/* HELPER: OPEN/CLOSE CRT1 CRTC */
1723/*********************************************/
1724
1725static void
1726SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
1727{
1728 if(IS_SIS650) {
1729 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1730 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
1731 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1732 } else if(IS_SIS661741660760) {
1733 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
1734 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1735 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1736 if(!SiS_Pr->SiS_ROMNew) {
1737 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1738 }
1739 }
1740}
1741
1742static void
1743SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
1744{
1745#if 0 /* This locks some CRTC registers. We don't want that. */
1746 unsigned short temp1 = 0, temp2 = 0;
1747
1748 if(IS_SIS661741660760) {
1749 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1750 temp1 = 0xa0; temp2 = 0x08;
1751 }
1752 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
1753 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
1754 }
1755#endif
1756}
1757
1758static void
1759SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
1760{
1761 /* Enable CRT1 gating */
1762 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
1763#if 0
1764 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
1765 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
1766 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
1767 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
1768 }
1769 }
1770#endif
1771}
1772
1773/*********************************************/
1774/* HELPER: GetColorDepth */
1775/*********************************************/
1776
1777unsigned short
1778SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1779 unsigned short ModeIdIndex)
1780{
1781 static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
1782 unsigned short modeflag;
1783 short index;
1784
1785 /* Do NOT check UseCustomMode, will skrew up FIFO */
1786 if(ModeNo == 0xfe) {
1787 modeflag = SiS_Pr->CModeFlag;
1788 } else if(ModeNo <= 0x13) {
1789 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1790 } else {
1791 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1792 }
1793
1794 index = (modeflag & ModeTypeMask) - ModeEGA;
1795 if(index < 0) index = 0;
1796 return ColorDepth[index];
1797}
1798
1799/*********************************************/
1800/* HELPER: GetOffset */
1801/*********************************************/
1802
1803unsigned short
1804SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1805 unsigned short ModeIdIndex, unsigned short RRTI)
1806{
1807 unsigned short xres, temp, colordepth, infoflag;
1808
1809 if(SiS_Pr->UseCustomMode) {
1810 infoflag = SiS_Pr->CInfoFlag;
1811 xres = SiS_Pr->CHDisplay;
1812 } else {
1813 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
1814 xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
1815 }
1816
1817 colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
1818
1819 temp = xres / 16;
1820 if(infoflag & InterlaceMode) temp <<= 1;
1821 temp *= colordepth;
1822 if(xres % 16) temp += (colordepth >> 1);
1823
1824 return temp;
1825}
1826
1827/*********************************************/
1828/* SEQ */
1829/*********************************************/
1830
1831static void
1832SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1833{
1834 unsigned char SRdata;
1835 int i;
1836
1837 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
1838
1839 /* or "display off" */
1840 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
1841
1842 /* determine whether to force x8 dotclock */
1843 if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
1844
1845 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1846 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01;
1847 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
1848
1849 }
1850
1851 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
1852
1853 for(i = 2; i <= 4; i++) {
1854 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
1855 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
1856 }
1857}
1858
1859/*********************************************/
1860/* MISC */
1861/*********************************************/
1862
1863static void
1864SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1865{
1866 unsigned char Miscdata;
1867
1868 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
1869
1870 if(SiS_Pr->ChipType < SIS_661) {
1871 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1873 Miscdata |= 0x0C;
1874 }
1875 }
1876 }
1877
1878 SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
1879}
1880
1881/*********************************************/
1882/* CRTC */
1883/*********************************************/
1884
1885static void
1886SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1887{
1888 unsigned char CRTCdata;
1889 unsigned short i;
1890
1891 /* Unlock CRTC */
1892 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
1893
1894 for(i = 0; i <= 0x18; i++) {
1895 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1896 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1897 }
1898
1899 if(SiS_Pr->ChipType >= SIS_661) {
1900 SiS_OpenCRTC(SiS_Pr);
1901 for(i = 0x13; i <= 0x14; i++) {
1902 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1903 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1904 }
1905 } else if( ( (SiS_Pr->ChipType == SIS_630) ||
1906 (SiS_Pr->ChipType == SIS_730) ) &&
1907 (SiS_Pr->ChipRevision >= 0x30) ) {
1908 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1909 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1910 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
1911 }
1912 }
1913 }
1914}
1915
1916/*********************************************/
1917/* ATT */
1918/*********************************************/
1919
1920static void
1921SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1922{
1923 unsigned char ARdata;
1924 unsigned short i;
1925
1926 for(i = 0; i <= 0x13; i++) {
1927 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
1928
1929 if(i == 0x13) {
1930 /* Pixel shift. If screen on LCD or TV is shifted left or right,
1931 * this might be the cause.
1932 */
1933 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
1935 }
1936 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1937 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1938 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
1939 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1940 }
1941 }
1942 }
1943 if(SiS_Pr->ChipType >= SIS_661) {
1944 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
1945 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1946 }
1947 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1948 if(SiS_Pr->ChipType >= SIS_315H) {
1949 if(IS_SIS550650740660) {
1950 /* 315, 330 don't do this */
1951 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
1952 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1953 } else {
1954 ARdata = 0;
1955 }
1956 }
1957 } else {
1958 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1959 }
1960 }
1961 }
1962 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
1963 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */
1964 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */
1965 }
1966
1967 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
1968 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */
1969 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */
1970
1971 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1972 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
1973 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1974}
1975
1976/*********************************************/
1977/* GRC */
1978/*********************************************/
1979
1980static void
1981SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1982{
1983 unsigned char GRdata;
1984 unsigned short i;
1985
1986 for(i = 0; i <= 0x08; i++) {
1987 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
1988 SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
1989 }
1990
1991 if(SiS_Pr->SiS_ModeType > ModeVGA) {
1992 /* 256 color disable */
1993 SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
1994 }
1995}
1996
1997/*********************************************/
1998/* CLEAR EXTENDED REGISTERS */
1999/*********************************************/
2000
2001static void
2002SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
2003{
2004 unsigned short i;
2005
2006 for(i = 0x0A; i <= 0x0E; i++) {
2007 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
2008 }
2009
2010 if(SiS_Pr->ChipType >= SIS_315H) {
2011 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2012 if(ModeNo <= 0x13) {
2013 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
2014 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
2015 }
2016 }
2017 }
2018}
2019
2020/*********************************************/
2021/* RESET VCLK */
2022/*********************************************/
2023
2024static void
2025SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
2026{
2027 if(SiS_Pr->ChipType >= SIS_315H) {
2028 if(SiS_Pr->ChipType < SIS_661) {
2029 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
2030 }
2031 } else {
2032 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
2033 (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
2034 return;
2035 }
2036 }
2037
2038 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
2039 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
2040 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
2041 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2042 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2043 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
2044 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
2045 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2046}
2047
2048/*********************************************/
2049/* SYNC */
2050/*********************************************/
2051
2052static void
2053SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
2054{
2055 unsigned short sync;
2056
2057 if(SiS_Pr->UseCustomMode) {
2058 sync = SiS_Pr->CInfoFlag >> 8;
2059 } else {
2060 sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
2061 }
2062
2063 sync &= 0xC0;
2064 sync |= 0x2f;
2065 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
2066}
2067
2068/*********************************************/
2069/* CRTC/2 */
2070/*********************************************/
2071
2072static void
2073SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2074 unsigned short ModeIdIndex, unsigned short RRTI)
2075{
2076 unsigned short temp, i, j, modeflag;
2077 unsigned char *crt1data = NULL;
2078
2079 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2080
2081 if(SiS_Pr->UseCustomMode) {
2082
2083 crt1data = &SiS_Pr->CCRT1CRTC[0];
2084
2085 } else {
2086
2087 temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
2088
2089 /* Alternate for 1600x1200 LCDA */
2090 if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
2091
2092 crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
2093
2094 }
2095
2096 /* unlock cr0-7 */
2097 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
2098
2099 for(i = 0, j = 0; i <= 7; i++, j++) {
2100 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2101 }
2102 for(j = 0x10; i <= 10; i++, j++) {
2103 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2104 }
2105 for(j = 0x15; i <= 12; i++, j++) {
2106 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2107 }
2108 for(j = 0x0A; i <= 15; i++, j++) {
2109 SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
2110 }
2111
2112 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
2113
2114 temp = (crt1data[16] & 0x01) << 5;
2115 if(modeflag & DoubleScanMode) temp |= 0x80;
2116 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2117
2118 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2119 SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2120 }
2121
2122#ifdef CONFIG_FB_SIS_315
2123 if(SiS_Pr->ChipType == XGI_20) {
2124 SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
2125 if(!(temp = crt1data[5] & 0x1f)) {
2126 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
2127 }
2128 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
2129 temp = (crt1data[16] >> 5) + 3;
2130 if(temp > 7) temp -= 7;
2131 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
2132 }
2133#endif
2134}
2135
2136/*********************************************/
2137/* OFFSET & PITCH */
2138/*********************************************/
2139/* (partly overruled by SetPitch() in XF86) */
2140/*********************************************/
2141
2142static void
2143SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2144 unsigned short ModeIdIndex, unsigned short RRTI)
2145{
2146 unsigned short temp, DisplayUnit, infoflag;
2147
2148 if(SiS_Pr->UseCustomMode) {
2149 infoflag = SiS_Pr->CInfoFlag;
2150 } else {
2151 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2152 }
2153
2154 DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2155
2156 temp = (DisplayUnit >> 8) & 0x0f;
2157 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2158
2159 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
2160
2161 if(infoflag & InterlaceMode) DisplayUnit >>= 1;
2162
2163 DisplayUnit <<= 5;
2164 temp = (DisplayUnit >> 8) + 1;
2165 if(DisplayUnit & 0xff) temp++;
2166 if(SiS_Pr->ChipType == XGI_20) {
2167 if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
2168 }
2169 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
2170}
2171
2172/*********************************************/
2173/* VCLK */
2174/*********************************************/
2175
2176static void
2177SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2178 unsigned short ModeIdIndex, unsigned short RRTI)
2179{
2180 unsigned short index = 0, clka, clkb;
2181
2182 if(SiS_Pr->UseCustomMode) {
2183 clka = SiS_Pr->CSR2B;
2184 clkb = SiS_Pr->CSR2C;
2185 } else {
2186 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2187 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
2188 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2189 /* Alternate for 1600x1200 LCDA */
2190 if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
2191 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
2192 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
2193 } else {
2194 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
2195 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
2196 }
2197 }
2198
2199 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
2200
2201 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
2202 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2203
2204 if(SiS_Pr->ChipType >= SIS_315H) {
2205#ifdef CONFIG_FB_SIS_315
2206 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
2207 if(SiS_Pr->ChipType == XGI_20) {
2208 unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2209 if(mf & HalfDCLK) {
2210 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
2211 clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
2212 clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
2213 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2214 }
2215 }
2216#endif
2217 } else {
2218 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2219 }
2220}
2221
2222/*********************************************/
2223/* FIFO */
2224/*********************************************/
2225
2226#ifdef CONFIG_FB_SIS_300
2227void
2228SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
2229 unsigned short *idx2)
2230{
2231 unsigned short temp1, temp2;
2232 static const unsigned char ThTiming[8] = {
2233 1, 2, 2, 3, 0, 1, 1, 2
2234 };
2235
2236 temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
2237 (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
2238 (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
2239 (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
2240 (*idx1) <<= 1;
2241}
2242
2243static unsigned short
2244SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
2245{
2246 static const unsigned char ThLowA[8 * 3] = {
2247 61, 3,52, 5,68, 7,100,11,
2248 43, 3,42, 5,54, 7, 78,11,
2249 34, 3,37, 5,47, 7, 67,11
2250 };
2251
2252 return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
2253}
2254
2255unsigned short
2256SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
2257{
2258 static const unsigned char ThLowB[8 * 3] = {
2259 81, 4,72, 6,88, 8,120,12,
2260 55, 4,54, 6,66, 8, 90,12,
2261 42, 4,45, 6,55, 8, 75,12
2262 };
2263
2264 return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
2265}
2266
2267static unsigned short
2268SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
2269 unsigned short colordepth, unsigned short key)
2270{
2271 unsigned short idx1, idx2;
2272 unsigned int longtemp = VCLK * colordepth;
2273
2274 SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
2275
2276 if(key == 0) {
2277 longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
2278 } else {
2279 longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
2280 }
2281 idx1 = longtemp % (MCLK * 16);
2282 longtemp /= (MCLK * 16);
2283 if(idx1) longtemp++;
2284 return (unsigned short)longtemp;
2285}
2286
2287static unsigned short
2288SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
2289 unsigned short colordepth, unsigned short MCLK)
2290{
2291 unsigned short temp1, temp2;
2292
2293 temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
2294 temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
2295 if(temp1 < 4) temp1 = 4;
2296 temp1 -= 4;
2297 if(temp2 < temp1) temp2 = temp1;
2298 return temp2;
2299}
2300
2301static void
2302SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2303 unsigned short RefreshRateTableIndex)
2304{
2305 unsigned short ThresholdLow = 0;
2306 unsigned short temp, index, VCLK, MCLK, colorth;
2307 static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
2308
2309 if(ModeNo > 0x13) {
2310
2311 /* Get VCLK */
2312 if(SiS_Pr->UseCustomMode) {
2313 VCLK = SiS_Pr->CSRClock;
2314 } else {
2315 index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2316 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2317 }
2318
2319 /* Get half colordepth */
2320 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2321
2322 /* Get MCLK */
2323 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
2324 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
2325
2326 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
2327 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
2328
2329 do {
2330 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
2331 if(ThresholdLow < 0x13) break;
2332 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2333 ThresholdLow = 0x13;
2334 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
2335 if(!temp) break;
2336 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
2337 } while(0);
2338
2339 } else ThresholdLow = 2;
2340
2341 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2342 temp = (ThresholdLow << 4) | 0x0f;
2343 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2344
2345 temp = (ThresholdLow & 0x10) << 1;
2346 if(ModeNo > 0x13) temp |= 0x40;
2347 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2348
2349 /* What is this? */
2350 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2351
2352 /* Write CRT/CPU threshold high */
2353 temp = ThresholdLow + 3;
2354 if(temp > 0x0f) temp = 0x0f;
2355 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2356}
2357
2358unsigned short
2359SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
2360{
2361 static const unsigned char LatencyFactor[] = {
2362 97, 88, 86, 79, 77, 0, /* 64 bit BQ=2 */
2363 0, 87, 85, 78, 76, 54, /* 64 bit BQ=1 */
2364 97, 88, 86, 79, 77, 0, /* 128 bit BQ=2 */
2365 0, 79, 77, 70, 68, 48, /* 128 bit BQ=1 */
2366 80, 72, 69, 63, 61, 0, /* 64 bit BQ=2 */
2367 0, 70, 68, 61, 59, 37, /* 64 bit BQ=1 */
2368 86, 77, 75, 68, 66, 0, /* 128 bit BQ=2 */
2369 0, 68, 66, 59, 57, 37 /* 128 bit BQ=1 */
2370 };
2371 static const unsigned char LatencyFactor730[] = {
2372 69, 63, 61,
2373 86, 79, 77,
2374 103, 96, 94,
2375 120,113,111,
2376 137,130,128
2377 };
2378
2379 if(SiS_Pr->ChipType == SIS_730) {
2380 return (unsigned short)LatencyFactor730[index];
2381 } else {
2382 return (unsigned short)LatencyFactor[index];
2383 }
2384}
2385
2386static unsigned short
2387SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
2388{
2389 unsigned short index;
2390
2391 if(SiS_Pr->ChipType == SIS_730) {
2392 index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
2393 } else {
2394 index = (key & 0xe0) >> 5;
2395 if(key & 0x10) index += 6;
2396 if(!(key & 0x01)) index += 24;
2397 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
2398 }
2399 return SiS_GetLatencyFactor630(SiS_Pr, index);
2400}
2401
2402static void
2403SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2404 unsigned short RefreshRateTableIndex)
2405{
2406 unsigned short ThresholdLow = 0;
2407 unsigned short i, data, VCLK, MCLK16, colorth = 0;
2408 unsigned int templ, datal;
2409 const unsigned char *queuedata = NULL;
2410 static const unsigned char FQBQData[21] = {
2411 0x01,0x21,0x41,0x61,0x81,
2412 0x31,0x51,0x71,0x91,0xb1,
2413 0x00,0x20,0x40,0x60,0x80,
2414 0x30,0x50,0x70,0x90,0xb0,
2415 0xff
2416 };
2417 static const unsigned char FQBQData730[16] = {
2418 0x34,0x74,0xb4,
2419 0x23,0x63,0xa3,
2420 0x12,0x52,0x92,
2421 0x01,0x41,0x81,
2422 0x00,0x40,0x80,
2423 0xff
2424 };
2425 static const unsigned short colortharray[6] = {
2426 1, 1, 2, 2, 3, 4
2427 };
2428
2429 i = 0;
2430
2431 if(ModeNo > 0x13) {
2432
2433 /* Get VCLK */
2434 if(SiS_Pr->UseCustomMode) {
2435 VCLK = SiS_Pr->CSRClock;
2436 } else {
2437 data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2438 VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
2439 }
2440
2441 /* Get MCLK * 16 */
2442 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
2443 MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
2444
2445 /* Get half colordepth */
2446 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2447
2448 if(SiS_Pr->ChipType == SIS_730) {
2449 queuedata = &FQBQData730[0];
2450 } else {
2451 queuedata = &FQBQData[0];
2452 }
2453
2454 do {
2455 templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
2456
2457 datal = templ % MCLK16;
2458 templ = (templ / MCLK16) + 1;
2459 if(datal) templ++;
2460
2461 if(templ > 0x13) {
2462 if(queuedata[i + 1] == 0xFF) {
2463 ThresholdLow = 0x13;
2464 break;
2465 }
2466 i++;
2467 } else {
2468 ThresholdLow = templ;
2469 break;
2470 }
2471 } while(queuedata[i] != 0xFF);
2472
2473 } else {
2474
2475 if(SiS_Pr->ChipType != SIS_730) i = 9;
2476 ThresholdLow = 0x02;
2477
2478 }
2479
2480 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2481 data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
2482 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
2483
2484 data = (ThresholdLow & 0x10) << 1;
2485 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
2486
2487 /* What is this? */
2488 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2489
2490 /* Write CRT/CPU threshold high (gap = 3) */
2491 data = ThresholdLow + 3;
2492 if(data > 0x0f) data = 0x0f;
2493 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
2494
2495 /* Write foreground and background queue */
2496 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
2497
2498 if(SiS_Pr->ChipType == SIS_730) {
2499
2500 templ &= 0xfffff9ff;
2501 templ |= ((queuedata[i] & 0xc0) << 3);
2502
2503 } else {
2504
2505 templ &= 0xf0ffffff;
2506 if( (ModeNo <= 0x13) &&
2507 (SiS_Pr->ChipType == SIS_630) &&
2508 (SiS_Pr->ChipRevision >= 0x30) ) {
2509 templ |= 0x0b000000;
2510 } else {
2511 templ |= ((queuedata[i] & 0xf0) << 20);
2512 }
2513
2514 }
2515
2516 sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
2517 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
2518
2519 /* GUI grant timer (PCI config 0xA3) */
2520 if(SiS_Pr->ChipType == SIS_730) {
2521
2522 templ &= 0x00ffffff;
2523 datal = queuedata[i] << 8;
2524 templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
2525
2526 } else {
2527
2528 templ &= 0xf0ffffff;
2529 templ |= ((queuedata[i] & 0x0f) << 24);
2530
2531 }
2532
2533 sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
2534}
2535#endif /* CONFIG_FB_SIS_300 */
2536
2537#ifdef CONFIG_FB_SIS_315
2538static void
2539SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2540{
2541 unsigned short modeflag;
2542
2543 /* disable auto-threshold */
2544 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
2545
2546 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2547
2548 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
2549 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
2550 if(ModeNo > 0x13) {
2551 if(SiS_Pr->ChipType >= XGI_20) {
2552 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2553 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2554 } else if(SiS_Pr->ChipType >= SIS_661) {
2555 if(!(modeflag & HalfDCLK)) {
2556 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2557 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2558 }
2559 } else {
2560 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
2561 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2562 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2563 }
2564 }
2565 }
2566}
2567#endif
2568
2569/*********************************************/
2570/* MODE REGISTERS */
2571/*********************************************/
2572
2573static void
2574SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2575 unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
2576{
2577 unsigned short data = 0, VCLK = 0, index = 0;
2578
2579 if(ModeNo > 0x13) {
2580 if(SiS_Pr->UseCustomMode) {
2581 VCLK = SiS_Pr->CSRClock;
2582 } else {
2583 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2584 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2585 }
2586 }
2587
2588 if(SiS_Pr->ChipType < SIS_315H) {
2589#ifdef CONFIG_FB_SIS_300
2590 if(VCLK > 150) data |= 0x80;
2591 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
2592
2593 data = 0x00;
2594 if(VCLK >= 150) data |= 0x08;
2595 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
2596#endif
2597 } else if(SiS_Pr->ChipType < XGI_20) {
2598#ifdef CONFIG_FB_SIS_315
2599 if(VCLK >= 166) data |= 0x0c;
2600 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2601
2602 if(VCLK >= 166) {
2603 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
2604 }
2605#endif
2606 } else {
2607#ifdef CONFIG_FB_SIS_315
2608 if(VCLK >= 200) data |= 0x0c;
2609 if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
2610 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2611 if(SiS_Pr->ChipType != XGI_20) {
2612 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
2613 if(VCLK < 200) data |= 0x10;
2614 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
2615 }
2616#endif
2617 }
2618
2619 /* DAC speed */
2620 if(SiS_Pr->ChipType >= SIS_661) {
2621
2622 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
2623
2624 } else {
2625
2626 data = 0x03;
2627 if(VCLK >= 260) data = 0x00;
2628 else if(VCLK >= 160) data = 0x01;
2629 else if(VCLK >= 135) data = 0x02;
2630
2631 if(SiS_Pr->ChipType == SIS_540) {
2632 /* Was == 203 or < 234 which made no sense */
2633 if (VCLK < 234) data = 0x02;
2634 }
2635
2636 if(SiS_Pr->ChipType < SIS_315H) {
2637 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
2638 } else {
2639 if(SiS_Pr->ChipType > SIS_315PRO) {
2640 if(ModeNo > 0x13) data &= 0xfc;
2641 }
2642 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
2643 }
2644
2645 }
2646}
2647
2648static void
2649SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2650 unsigned short ModeIdIndex, unsigned short RRTI)
2651{
2652 unsigned short data, infoflag = 0, modeflag, resindex;
2653#ifdef CONFIG_FB_SIS_315
2654 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2655 unsigned short data2, data3;
2656#endif
2657
2658 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2659
2660 if(SiS_Pr->UseCustomMode) {
2661 infoflag = SiS_Pr->CInfoFlag;
2662 } else {
2663 resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
2664 if(ModeNo > 0x13) {
2665 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2666 }
2667 }
2668
2669 /* Disable DPMS */
2670 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
2671
2672 data = 0;
2673 if(ModeNo > 0x13) {
2674 if(SiS_Pr->SiS_ModeType > ModeEGA) {
2675 data |= 0x02;
2676 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
2677 }
2678 if(infoflag & InterlaceMode) data |= 0x20;
2679 }
2680 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
2681
2682 if(SiS_Pr->ChipType != SIS_300) {
2683 data = 0;
2684 if(infoflag & InterlaceMode) {
2685 /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
2686 int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
2687 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
2688 int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
2689 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
2690 data = hrs - (hto >> 1) + 3;
2691 }
2692 SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
2693 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
2694 }
2695
2696 if(modeflag & HalfDCLK) {
2697 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
2698 }
2699
2700 data = 0;
2701 if(modeflag & LineCompareOff) data = 0x08;
2702 if(SiS_Pr->ChipType == SIS_300) {
2703 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
2704 } else {
2705 if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
2706 if(SiS_Pr->SiS_ModeType == ModeEGA) {
2707 if(ModeNo > 0x13) {
2708 data |= 0x40;
2709 }
2710 }
2711 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
2712 }
2713
2714#ifdef CONFIG_FB_SIS_315
2715 if(SiS_Pr->ChipType >= SIS_315H) {
2716 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
2717 }
2718
2719 if(SiS_Pr->ChipType == SIS_315PRO) {
2720
2721 data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
2722 if(SiS_Pr->SiS_ModeType == ModeText) {
2723 data &= 0xc7;
2724 } else {
2725 data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
2726 if(infoflag & InterlaceMode) data2 >>= 1;
2727 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
2728 if(data3) data2 /= data3;
2729 if(data2 >= 0x50) {
2730 data &= 0x0f;
2731 data |= 0x50;
2732 }
2733 }
2734 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
2735
2736 } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
2737
2738 data = SiS_Get310DRAMType(SiS_Pr);
2739 if(SiS_Pr->ChipType == SIS_330) {
2740 data = SiS_Pr->SiS_SR15[(2 * 4) + data];
2741 } else {
2742 if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
2743 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
2744 else data = 0xba;
2745 }
2746 if(SiS_Pr->SiS_ModeType <= ModeEGA) {
2747 data &= 0xc7;
2748 } else {
2749 if(SiS_Pr->UseCustomMode) {
2750 data2 = SiS_Pr->CSRClock;
2751 } else {
2752 data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2753 data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
2754 }
2755
2756 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
2757 if(data3) data2 *= data3;
2758
2759 data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
2760
2761 if(SiS_Pr->ChipType == SIS_330) {
2762 if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
2763 if (data2 >= 0x19c) data = 0xba;
2764 else if(data2 >= 0x140) data = 0x7a;
2765 else if(data2 >= 0x101) data = 0x3a;
2766 else if(data2 >= 0xf5) data = 0x32;
2767 else if(data2 >= 0xe2) data = 0x2a;
2768 else if(data2 >= 0xc4) data = 0x22;
2769 else if(data2 >= 0xac) data = 0x1a;
2770 else if(data2 >= 0x9e) data = 0x12;
2771 else if(data2 >= 0x8e) data = 0x0a;
2772 else data = 0x02;
2773 } else {
2774 if(data2 >= 0x127) data = 0xba;
2775 else data = 0x7a;
2776 }
2777 } else { /* 76x+LFB */
2778 if (data2 >= 0x190) data = 0xba;
2779 else if(data2 >= 0xff) data = 0x7a;
2780 else if(data2 >= 0xd3) data = 0x3a;
2781 else if(data2 >= 0xa9) data = 0x1a;
2782 else if(data2 >= 0x93) data = 0x0a;
2783 else data = 0x02;
2784 }
2785 }
2786 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
2787
2788 }
2789 /* XGI: Nothing. */
2790 /* TODO: Check SiS340 */
2791#endif
2792
2793 data = 0x60;
2794 if(SiS_Pr->SiS_ModeType != ModeText) {
2795 data ^= 0x60;
2796 if(SiS_Pr->SiS_ModeType != ModeEGA) {
2797 data ^= 0xA0;
2798 }
2799 }
2800 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
2801
2802 SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
2803
2804#ifdef CONFIG_FB_SIS_315
2805 if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
2806 (SiS_Pr->ChipType == XGI_40)) {
2807 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
2808 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
2809 } else {
2810 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
2811 }
2812 } else if(SiS_Pr->ChipType == XGI_20) {
2813 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
2814 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
2815 } else {
2816 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
2817 }
2818 SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
2819 }
2820#endif
2821}
2822
2823#ifdef CONFIG_FB_SIS_315
2824static void
2825SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
2826{
2827#if 0
2828 /* TODO: Find out about IOAddress2 */
2829 SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
2830 SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
2831 SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
2832 int i;
2833
2834 if((SiS_Pr->ChipRevision != 0) ||
2835 (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
2836 return;
2837
2838 for(i = 0; i <= 4; i++) { /* SR00 - SR04 */
2839 SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
2840 }
2841 for(i = 0; i <= 8; i++) { /* GR00 - GR08 */
2842 SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
2843 }
2844 SiS_SetReg(P2_3c4,0x05,0x86);
2845 SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06)); /* SR06 */
2846 SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21)); /* SR21 */
2847 SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc)); /* MISC */
2848 SiS_SetReg(P2_3c4,0x05,0x00);
2849#endif
2850}
2851#endif
2852
2853/*********************************************/
2854/* LOAD DAC */
2855/*********************************************/
2856
2857static void
2858SiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
2859 unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
2860{
2861 unsigned short d1, d2, d3;
2862
2863 switch(dl) {
2864 case 0: d1 = dh; d2 = ah; d3 = al; break;
2865 case 1: d1 = ah; d2 = al; d3 = dh; break;
2866 default: d1 = al; d2 = dh; d3 = ah;
2867 }
2868 SiS_SetRegByte(DACData, (d1 << shiftflag));
2869 SiS_SetRegByte(DACData, (d2 << shiftflag));
2870 SiS_SetRegByte(DACData, (d3 << shiftflag));
2871}
2872
2873void
2874SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2875{
2876 unsigned short data, data2, time, i, j, k, m, n, o;
2877 unsigned short si, di, bx, sf;
2878 SISIOADDRESS DACAddr, DACData;
2879 const unsigned char *table = NULL;
2880
2881 data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
2882
2883 j = time = 64;
2884 if(data == 0x00) table = SiS_MDA_DAC;
2885 else if(data == 0x08) table = SiS_CGA_DAC;
2886 else if(data == 0x10) table = SiS_EGA_DAC;
2887 else if(data == 0x18) {
2888 j = 16;
2889 time = 256;
2890 table = SiS_VGA_DAC;
2891 }
2892
2893 if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
2894 (SiS_Pr->SiS_VBType & VB_NoLCD) ) ||
2895 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */
2896 (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
2897 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
2898 DACAddr = SiS_Pr->SiS_P3c8;
2899 DACData = SiS_Pr->SiS_P3c9;
2900 sf = 0;
2901 } else {
2902 DACAddr = SiS_Pr->SiS_Part5Port;
2903 DACData = SiS_Pr->SiS_Part5Port + 1;
2904 sf = 2;
2905 }
2906
2907 SiS_SetRegByte(DACAddr,0x00);
2908
2909 for(i = 0; i < j; i++) {
2910 data = table[i];
2911 for(k = 0; k < 3; k++) {
2912 data2 = 0;
2913 if(data & 0x01) data2 += 0x2A;
2914 if(data & 0x02) data2 += 0x15;
2915 SiS_SetRegByte(DACData, (data2 << sf));
2916 data >>= 2;
2917 }
2918 }
2919
2920 if(time == 256) {
2921 for(i = 16; i < 32; i++) {
2922 data = table[i] << sf;
2923 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
2924 }
2925 si = 32;
2926 for(m = 0; m < 9; m++) {
2927 di = si;
2928 bx = si + 4;
2929 for(n = 0; n < 3; n++) {
2930 for(o = 0; o < 5; o++) {
2931 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
2932 si++;
2933 }
2934 si -= 2;
2935 for(o = 0; o < 3; o++) {
2936 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
2937 si--;
2938 }
2939 } /* for n < 3 */
2940 si += 5;
2941 } /* for m < 9 */
2942 }
2943}
2944
2945/*********************************************/
2946/* SET CRT1 REGISTER GROUP */
2947/*********************************************/
2948
2949static void
2950SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2951{
2952 unsigned short StandTableIndex, RefreshRateTableIndex;
2953
2954 SiS_Pr->SiS_CRT1Mode = ModeNo;
2955
2956 StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
2957
2958 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
2959 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
2960 SiS_DisableBridge(SiS_Pr);
2961 }
2962 }
2963
2964 SiS_ResetSegmentRegisters(SiS_Pr);
2965
2966 SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
2967 SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
2968 SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
2969 SiS_SetATTRegs(SiS_Pr, StandTableIndex);
2970 SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
2971 SiS_ClearExt1Regs(SiS_Pr, ModeNo);
2972 SiS_ResetCRT1VCLK(SiS_Pr);
2973
2974 SiS_Pr->SiS_SelectCRT2Rate = 0;
2975 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
2976
2977 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
2978 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2979 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2980 }
2981 }
2982
2983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2984 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2985 }
2986
2987 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
2988
2989 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2990 SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
2991 }
2992
2993 if(RefreshRateTableIndex != 0xFFFF) {
2994 SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
2995 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2996 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2997 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2998 }
2999
3000 switch(SiS_Pr->ChipType) {
3001#ifdef CONFIG_FB_SIS_300
3002 case SIS_300:
3003 SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
3004 break;
3005 case SIS_540:
3006 case SIS_630:
3007 case SIS_730:
3008 SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
3009 break;
3010#endif
3011 default:
3012#ifdef CONFIG_FB_SIS_315
3013 if(SiS_Pr->ChipType == XGI_20) {
3014 unsigned char sr2b = 0, sr2c = 0;
3015 switch(ModeNo) {
3016 case 0x00:
3017 case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
3018 case 0x04:
3019 case 0x05:
3020 case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
3021 }
3022 if(sr2b) {
3023 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
3024 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
3025 SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
3026 }
3027 }
3028 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
3029#endif
3030 break;
3031 }
3032
3033 SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3034
3035#ifdef CONFIG_FB_SIS_315
3036 if(SiS_Pr->ChipType == XGI_40) {
3037 SiS_SetupDualChip(SiS_Pr);
3038 }
3039#endif
3040
3041 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
3042
3043 if(SiS_Pr->SiS_flag_clearbuffer) {
3044 SiS_ClearBuffer(SiS_Pr, ModeNo);
3045 }
3046
3047 if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
3048 SiS_WaitRetrace1(SiS_Pr);
3049 SiS_DisplayOn(SiS_Pr);
3050 }
3051}
3052
3053/*********************************************/
3054/* HELPER: VIDEO BRIDGE PROG CLK */
3055/*********************************************/
3056
3057static void
3058SiS_InitVB(struct SiS_Private *SiS_Pr)
3059{
3060 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3061
3062 SiS_Pr->Init_P4_0E = 0;
3063 if(SiS_Pr->SiS_ROMNew) {
3064 SiS_Pr->Init_P4_0E = ROMAddr[0x82];
3065 } else if(SiS_Pr->ChipType >= XGI_40) {
3066 if(SiS_Pr->SiS_XGIROM) {
3067 SiS_Pr->Init_P4_0E = ROMAddr[0x80];
3068 }
3069 }
3070}
3071
3072static void
3073SiS_ResetVB(struct SiS_Private *SiS_Pr)
3074{
3075#ifdef CONFIG_FB_SIS_315
3076 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3077 unsigned short temp;
3078
3079 /* VB programming clock */
3080 if(SiS_Pr->SiS_UseROM) {
3081 if(SiS_Pr->ChipType < SIS_330) {
3082 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
3083 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3084 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3085 } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
3086 temp = ROMAddr[0x7e] | 0x40;
3087 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3088 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3089 }
3090 } else if(SiS_Pr->ChipType >= XGI_40) {
3091 temp = 0x40;
3092 if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
3093 /* Can we do this on any chipset? */
3094 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3095 }
3096#endif
3097}
3098
3099/*********************************************/
3100/* HELPER: SET VIDEO/CAPTURE REGISTERS */
3101/*********************************************/
3102
3103static void
3104SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
3105{
3106 /* SiS65x and XGI set up some sort of "lock mode" for text
3107 * which locks CRT2 in some way to CRT1 timing. Disable
3108 * this here.
3109 */
3110#ifdef CONFIG_FB_SIS_315
3111 if((IS_SIS651) || (IS_SISM650) ||
3112 SiS_Pr->ChipType == SIS_340 ||
3113 SiS_Pr->ChipType == XGI_40) {
3114 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */
3115 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
3116 SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */
3117 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
3118 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
3119 }
3120 /* !!! This does not support modes < 0x13 !!! */
3121#endif
3122}
3123
3124/*********************************************/
3125/* HELPER: SET AGP TIMING FOR SiS760 */
3126/*********************************************/
3127
3128static void
3129SiS_Handle760(struct SiS_Private *SiS_Pr)
3130{
3131#ifdef CONFIG_FB_SIS_315
3132 unsigned int somebase;
3133 unsigned char temp1, temp2, temp3;
3134
3135 if( (SiS_Pr->ChipType != SIS_760) ||
3136 ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
3137 (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) ||
3138 (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
3139 return;
3140
3141 somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
3142 somebase &= 0xffff;
3143
3144 if(somebase == 0) return;
3145
3146 temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
3147
3148 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3149 temp1 = 0x21;
3150 temp2 = 0x03;
3151 temp3 |= 0x08;
3152 } else {
3153 temp1 = 0x25;
3154 temp2 = 0x0b;
3155 }
3156
3157 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
3158 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
3159
3160 SiS_SetRegByte((somebase + 0x85), temp3);
3161#endif
3162}
3163
3164/*********************************************/
3165/* SiSSetMode() */
3166/*********************************************/
3167
3168bool
3169SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
3170{
3171 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3172 unsigned short RealModeNo, ModeIdIndex;
3173 unsigned char backupreg = 0;
3174 unsigned short KeepLockReg;
3175
3176 SiS_Pr->UseCustomMode = false;
3177 SiS_Pr->CRT1UsesCustomMode = false;
3178
3179 SiS_Pr->SiS_flag_clearbuffer = 0;
3180
3181 if(SiS_Pr->UseCustomMode) {
3182 ModeNo = 0xfe;
3183 } else {
3184 if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
3185 ModeNo &= 0x7f;
3186 }
3187
3188 /* Don't use FSTN mode for CRT1 */
3189 RealModeNo = ModeNo;
3190 if(ModeNo == 0x5b) ModeNo = 0x56;
3191
3192 SiSInitPtr(SiS_Pr);
3193 SiSRegInit(SiS_Pr, BaseAddr);
3194 SiS_GetSysFlags(SiS_Pr);
3195
3196 SiS_Pr->SiS_VGAINFO = 0x11;
3197
3198 KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
3199 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3200
3201 SiSInitPCIetc(SiS_Pr);
3202 SiSSetLVDSetc(SiS_Pr);
3203 SiSDetermineROMUsage(SiS_Pr);
3204
3205 SiS_UnLockCRT2(SiS_Pr);
3206
3207 if(!SiS_Pr->UseCustomMode) {
3208 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
3209 } else {
3210 ModeIdIndex = 0;
3211 }
3212
3213 SiS_GetVBType(SiS_Pr);
3214
3215 /* Init/restore some VB registers */
3216 SiS_InitVB(SiS_Pr);
3217 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3218 if(SiS_Pr->ChipType >= SIS_315H) {
3219 SiS_ResetVB(SiS_Pr);
3220 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3221 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3222 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3223 } else {
3224 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3225 }
3226 }
3227
3228 /* Get VB information (connectors, connected devices) */
3229 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
3230 SiS_SetYPbPr(SiS_Pr);
3231 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3232 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3233 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3234
3235 /* Check memory size (kernel framebuffer driver only) */
3236 if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
3237 return false;
3238 }
3239
3240 SiS_OpenCRTC(SiS_Pr);
3241
3242 if(SiS_Pr->UseCustomMode) {
3243 SiS_Pr->CRT1UsesCustomMode = true;
3244 SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
3245 SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
3246 } else {
3247 SiS_Pr->CRT1UsesCustomMode = false;
3248 }
3249
3250 /* Set mode on CRT1 */
3251 if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
3252 (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
3253 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
3254 }
3255
3256 /* Set mode on CRT2 */
3257 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
3258 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3259 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3260 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3261 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3262 SiS_SetCRT2Group(SiS_Pr, RealModeNo);
3263 }
3264 }
3265
3266 SiS_HandleCRT1(SiS_Pr);
3267
3268 SiS_StrangeStuff(SiS_Pr);
3269
3270 SiS_DisplayOn(SiS_Pr);
3271 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3272
3273#ifdef CONFIG_FB_SIS_315
3274 if(SiS_Pr->ChipType >= SIS_315H) {
3275 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3276 if(!(SiS_IsDualEdge(SiS_Pr))) {
3277 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3278 }
3279 }
3280 }
3281#endif
3282
3283 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3284 if(SiS_Pr->ChipType >= SIS_315H) {
3285#ifdef CONFIG_FB_SIS_315
3286 if(!SiS_Pr->SiS_ROMNew) {
3287 if(SiS_IsVAMode(SiS_Pr)) {
3288 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3289 } else {
3290 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
3291 }
3292 }
3293
3294 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3295
3296 if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
3297 if((ModeNo == 0x03) || (ModeNo == 0x10)) {
3298 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
3299 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
3300 }
3301 }
3302
3303 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3304 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3305 }
3306#endif
3307 } else if((SiS_Pr->ChipType == SIS_630) ||
3308 (SiS_Pr->ChipType == SIS_730)) {
3309 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3310 }
3311 }
3312
3313 SiS_CloseCRTC(SiS_Pr);
3314
3315 SiS_Handle760(SiS_Pr);
3316
3317 /* We never lock registers in XF86 */
3318 if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
3319
3320 return true;
3321}
3322
3323#ifndef GETBITSTR
3324#define GENBITSMASK(mask) GENMASK(1?mask,0?mask)
3325#define GETBITS(var,mask) (((var) & GENBITSMASK(mask)) >> (0?mask))
3326#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
3327#endif
3328
3329void
3330SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
3331{
3332 int x = 1; /* Fix sync */
3333
3334 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
3335 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
3336 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
3337 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
3338 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
3339 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
3340 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
3341
3342 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
3343 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
3344 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
3345 | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
3346 | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
3347 | 0x10
3348 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
3349 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
3350 | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
3351
3352 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
3353
3354 if(depth != 8) {
3355 if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */
3356 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
3357 }
3358
3359 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF; /* CR10 */
3360 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80; /* CR11 */
3361 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
3362 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
3363 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
3364
3365 SiS_Pr->CCRT1CRTC[13] = /* SRA */
3366 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
3367 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
3368 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
3369 GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
3370 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
3371 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
3372
3373 SiS_Pr->CCRT1CRTC[14] = /* SRB */
3374 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
3375 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
3376 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
3377 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
3378
3379
3380 SiS_Pr->CCRT1CRTC[15] = /* SRC */
3381 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
3382 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
3383}
3384
3385void
3386SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3387 unsigned short ModeIdIndex)
3388{
3389 unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
3390 unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
3391 int i, j;
3392
3393 /* 1:1 data: use data set by setcrt1crtc() */
3394 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
3395
3396 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
3397
3398 if(modeflag & HalfDCLK) VGAHDE >>= 1;
3399
3400 SiS_Pr->CHDisplay = VGAHDE;
3401 SiS_Pr->CHBlankStart = VGAHDE;
3402
3403 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
3404 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
3405
3406 if(SiS_Pr->ChipType < SIS_315H) {
3407#ifdef CONFIG_FB_SIS_300
3408 tempbx = SiS_Pr->SiS_VGAHT;
3409 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3410 tempbx = SiS_Pr->PanelHT;
3411 }
3412 if(modeflag & HalfDCLK) tempbx >>= 1;
3413 remaining = tempbx % 8;
3414#endif
3415 } else {
3416#ifdef CONFIG_FB_SIS_315
3417 /* OK for LCDA, LVDS */
3418 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
3419 tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
3420 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3421 tempax = SiS_Pr->PanelXRes;
3422 }
3423 tempbx += tempax;
3424 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
3425#endif
3426 }
3427 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
3428
3429 if(SiS_Pr->ChipType < SIS_315H) {
3430#ifdef CONFIG_FB_SIS_300
3431 if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
3432 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
3433 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
3434 if(modeflag & HalfDCLK) {
3435 SiS_Pr->CHSyncStart >>= 1;
3436 SiS_Pr->CHSyncEnd >>= 1;
3437 }
3438 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3439 tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
3440 tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
3441 if(modeflag & HalfDCLK) {
3442 tempax >>= 1;
3443 tempbx >>= 1;
3444 }
3445 SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
3446 tempax = SiS_Pr->PanelHRE + 7;
3447 if(modeflag & HalfDCLK) tempax >>= 1;
3448 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
3449 } else {
3450 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
3451 if(modeflag & HalfDCLK) {
3452 SiS_Pr->CHSyncStart >>= 1;
3453 tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
3454 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
3455 } else {
3456 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
3457 SiS_Pr->CHSyncStart += 8;
3458 }
3459 }
3460#endif
3461 } else {
3462#ifdef CONFIG_FB_SIS_315
3463 tempax = VGAHDE;
3464 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3465 tempbx = SiS_Pr->PanelXRes;
3466 if(modeflag & HalfDCLK) tempbx >>= 1;
3467 tempax += ((tempbx - tempax) >> 1);
3468 }
3469 tempax += SiS_Pr->PanelHRS;
3470 SiS_Pr->CHSyncStart = tempax;
3471 tempax += SiS_Pr->PanelHRE;
3472 SiS_Pr->CHSyncEnd = tempax;
3473#endif
3474 }
3475
3476 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
3477 tempax = SiS_Pr->SiS_VGAVDE;
3478 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3479 tempax = SiS_Pr->PanelYRes;
3480 } else if(SiS_Pr->ChipType < SIS_315H) {
3481#ifdef CONFIG_FB_SIS_300
3482 /* Stupid hack for 640x400/320x200 */
3483 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3484 if((tempax + tempbx) == 438) tempbx += 16;
3485 } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
3486 (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
3487 tempax = 0;
3488 tempbx = SiS_Pr->SiS_VGAVT;
3489 }
3490#endif
3491 }
3492 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
3493
3494 tempax = SiS_Pr->SiS_VGAVDE;
3495 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3496 tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
3497 }
3498 tempax += SiS_Pr->PanelVRS;
3499 SiS_Pr->CVSyncStart = tempax;
3500 tempax += SiS_Pr->PanelVRE;
3501 SiS_Pr->CVSyncEnd = tempax;
3502 if(SiS_Pr->ChipType < SIS_315H) {
3503 SiS_Pr->CVSyncStart--;
3504 SiS_Pr->CVSyncEnd--;
3505 }
3506
3507 SiS_CalcCRRegisters(SiS_Pr, 8);
3508 SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
3509 SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
3510 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
3511
3512 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
3513
3514 for(i = 0, j = 0; i <= 7; i++, j++) {
3515 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3516 }
3517 for(j = 0x10; i <= 10; i++, j++) {
3518 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3519 }
3520 for(j = 0x15; i <= 12; i++, j++) {
3521 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3522 }
3523 for(j = 0x0A; i <= 15; i++, j++) {
3524 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
3525 }
3526
3527 tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
3528 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
3529
3530 tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
3531 if(modeflag & DoubleScanMode) tempax |= 0x80;
3532 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
3533
3534}
3535
3536void
3537SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
3538 int xres, int yres,
3539 struct fb_var_screeninfo *var, bool writeres
3540)
3541{
3542 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
3543 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
3544 unsigned char sr_data, cr_data, cr_data2;
3545 int A, B, C, D, E, F, temp;
3546
3547 sr_data = crdata[14];
3548
3549 /* Horizontal total */
3550 HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
3551 A = HT + 5;
3552
3553 /* Horizontal display enable end */
3554 HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
3555 E = HDE + 1;
3556
3557 /* Horizontal retrace (=sync) start */
3558 HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
3559 F = HRS - E - 3;
3560
3561 /* Horizontal blank start */
3562 HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
3563
3564 sr_data = crdata[15];
3565 cr_data = crdata[5];
3566
3567 /* Horizontal blank end */
3568 HBE = (crdata[3] & 0x1f) |
3569 ((unsigned short)(cr_data & 0x80) >> 2) |
3570 ((unsigned short)(sr_data & 0x03) << 6);
3571
3572 /* Horizontal retrace (=sync) end */
3573 HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
3574
3575 temp = HBE - ((E - 1) & 255);
3576 B = (temp > 0) ? temp : (temp + 256);
3577
3578 temp = HRE - ((E + F + 3) & 63);
3579 C = (temp > 0) ? temp : (temp + 64);
3580
3581 D = B - F - C;
3582
3583 if(writeres) var->xres = xres = E * 8;
3584 var->left_margin = D * 8;
3585 var->right_margin = F * 8;
3586 var->hsync_len = C * 8;
3587
3588 /* Vertical */
3589 sr_data = crdata[13];
3590 cr_data = crdata[7];
3591
3592 /* Vertical total */
3593 VT = crdata[6] |
3594 ((unsigned short)(cr_data & 0x01) << 8) |
3595 ((unsigned short)(cr_data & 0x20) << 4) |
3596 ((unsigned short)(sr_data & 0x01) << 10);
3597 A = VT + 2;
3598
3599 /* Vertical display enable end */
3600 VDE = crdata[10] |
3601 ((unsigned short)(cr_data & 0x02) << 7) |
3602 ((unsigned short)(cr_data & 0x40) << 3) |
3603 ((unsigned short)(sr_data & 0x02) << 9);
3604 E = VDE + 1;
3605
3606 /* Vertical retrace (=sync) start */
3607 VRS = crdata[8] |
3608 ((unsigned short)(cr_data & 0x04) << 6) |
3609 ((unsigned short)(cr_data & 0x80) << 2) |
3610 ((unsigned short)(sr_data & 0x08) << 7);
3611 F = VRS + 1 - E;
3612
3613 cr_data2 = (crdata[16] & 0x01) << 5;
3614
3615 /* Vertical blank start */
3616 VBS = crdata[11] |
3617 ((unsigned short)(cr_data & 0x08) << 5) |
3618 ((unsigned short)(cr_data2 & 0x20) << 4) |
3619 ((unsigned short)(sr_data & 0x04) << 8);
3620
3621 /* Vertical blank end */
3622 VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
3623 temp = VBE - ((E - 1) & 511);
3624 B = (temp > 0) ? temp : (temp + 512);
3625
3626 /* Vertical retrace (=sync) end */
3627 VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
3628 temp = VRE - ((E + F - 1) & 31);
3629 C = (temp > 0) ? temp : (temp + 32);
3630
3631 D = B - F - C;
3632
3633 if(writeres) var->yres = yres = E;
3634 var->upper_margin = D;
3635 var->lower_margin = F;
3636 var->vsync_len = C;
3637
3638 if((xres == 320) && ((yres == 200) || (yres == 240))) {
3639 /* Terrible hack, but correct CRTC data for
3640 * these modes only produces a black screen...
3641 * (HRE is 0, leading into a too large C and
3642 * a negative D. The CRT controller does not
3643 * seem to like correcting HRE to 50)
3644 */
3645 var->left_margin = (400 - 376);
3646 var->right_margin = (328 - 320);
3647 var->hsync_len = (376 - 328);
3648
3649 }
3650
3651}
3652
3653
3654
3655
diff --git a/drivers/video/fbdev/sis/init.h b/drivers/video/fbdev/sis/init.h
new file mode 100644
index 000000000000..85d6738b6c64
--- /dev/null
+++ b/drivers/video/fbdev/sis/init.h
@@ -0,0 +1,1541 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Data and prototypes for init.c
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INIT_H_
54#define _INIT_H_
55
56#include "initdef.h"
57
58#include "vgatypes.h"
59#include "vstruct.h"
60#ifdef SIS_CP
61#undef SIS_CP
62#endif
63#include <linux/types.h>
64#include <asm/io.h>
65#include <linux/fb.h>
66#include "sis.h"
67#include <video/sisfb.h>
68
69/* Mode numbers */
70static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
71static const unsigned short ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
72static const unsigned short ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
73static const unsigned short ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
74static const unsigned short ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
75static const unsigned short ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
76static const unsigned short ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
77static const unsigned short ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
78static const unsigned short ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
79static const unsigned short ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
80static const unsigned short ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
81static const unsigned short ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
82static const unsigned short ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
83static const unsigned short ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
84static const unsigned short ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
85static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */
86static const unsigned short ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
87static const unsigned short ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
88static const unsigned short ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
89static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
90static const unsigned short ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
91static const unsigned short ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
92static const unsigned short ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
93static const unsigned short ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
94static const unsigned short ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
95static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
96static const unsigned short ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
97static const unsigned short ModeIndex_1280x854[] = {0x1a, 0x1b, 0x00, 0x1c};
98static const unsigned short ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
99static const unsigned short ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
100static const unsigned short ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
101static const unsigned short ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
102static const unsigned short ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
103static const unsigned short ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
104static const unsigned short ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
105static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
106static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
107
108static const unsigned char SiS_MDA_DAC[] =
109{
110 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
112 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
113 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
114 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
116 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
117 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
118};
119
120static const unsigned char SiS_CGA_DAC[] =
121{
122 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
123 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
124 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
125 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
126 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
127 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
128 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
129 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
130};
131
132static const unsigned char SiS_EGA_DAC[] =
133{
134 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
135 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
136 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
137 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
138 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
139 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
140 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
141 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
142};
143
144static const unsigned char SiS_VGA_DAC[] =
145{
146 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
147 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
148 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
149 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
150 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
151 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
152 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
153 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
154 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
155 0x0B,0x0C,0x0D,0x0F,0x10
156};
157
158static const struct SiS_St SiS_SModeIDTable[] =
159{
160 {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00,0x40},
161 {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00,0x40},
162 {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01,0x40},
163 {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02,0x40},
164 {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02,0x40},
165 {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40},
166 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04,0x40},
167 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05,0x40},
168 {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03,0x40},
169 {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03,0x40},
170 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04,0x40},
171 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05,0x40},
172 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05,0x40},
173 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05,0x40},
174 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05,0x40},
175 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05,0x40},
176 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04,0x40},
177 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05,0x40},
178 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05,0x40},
179 {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
180};
181
182static const struct SiS_StResInfo_S SiS_StResInfo[]=
183{
184 { 640,400},
185 { 640,350},
186 { 720,400},
187 { 720,350},
188 { 640,480}
189};
190
191static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
192{
193 { 320, 200, 8, 8}, /* 0x00 */
194 { 320, 240, 8, 8}, /* 0x01 */
195 { 320, 400, 8, 8}, /* 0x02 */
196 { 400, 300, 8, 8}, /* 0x03 */
197 { 512, 384, 8, 8}, /* 0x04 */
198 { 640, 400, 8,16}, /* 0x05 */
199 { 640, 480, 8,16}, /* 0x06 */
200 { 800, 600, 8,16}, /* 0x07 */
201 { 1024, 768, 8,16}, /* 0x08 */
202 { 1280,1024, 8,16}, /* 0x09 */
203 { 1600,1200, 8,16}, /* 0x0a */
204 { 1920,1440, 8,16}, /* 0x0b */
205 { 2048,1536, 8,16}, /* 0x0c */
206 { 720, 480, 8,16}, /* 0x0d */
207 { 720, 576, 8,16}, /* 0x0e */
208 { 1280, 960, 8,16}, /* 0x0f */
209 { 800, 480, 8,16}, /* 0x10 */
210 { 1024, 576, 8,16}, /* 0x11 */
211 { 1280, 720, 8,16}, /* 0x12 */
212 { 856, 480, 8,16}, /* 0x13 */
213 { 1280, 768, 8,16}, /* 0x14 */
214 { 1400,1050, 8,16}, /* 0x15 */
215 { 1152, 864, 8,16}, /* 0x16 */
216 { 848, 480, 8,16}, /* 0x17 */
217 { 1360, 768, 8,16}, /* 0x18 */
218 { 1024, 600, 8,16}, /* 0x19 */
219 { 1152, 768, 8,16}, /* 0x1a */
220 { 768, 576, 8,16}, /* 0x1b */
221 { 1360,1024, 8,16}, /* 0x1c */
222 { 1680,1050, 8,16}, /* 0x1d */
223 { 1280, 800, 8,16}, /* 0x1e */
224 { 1920,1080, 8,16}, /* 0x1f */
225 { 960, 540, 8,16}, /* 0x20 */
226 { 960, 600, 8,16}, /* 0x21 */
227 { 1280, 854, 8,16} /* 0x22 */
228};
229
230#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
231static const struct SiS_StandTable_S SiS_StandTable[]=
232{
233/* 0x00: MD_0_200 */
234 {
235 0x28,0x18,0x08,0x0800,
236 {0x09,0x03,0x00,0x02},
237 0x63,
238 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
239 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
240 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
241 0xff},
242 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
243 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
244 0x08,0x00,0x0f,0x00},
245 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
246 0xff}
247 },
248/* 0x01: MD_1_200 */
249 {
250 0x28,0x18,0x08,0x0800,
251 {0x09,0x03,0x00,0x02},
252 0x63,
253 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
254 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
255 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
256 0xff},
257 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
258 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
259 0x08,0x00,0x0f,0x00},
260 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
261 0xff}
262 },
263/* 0x02: MD_2_200 */
264 {
265 0x50,0x18,0x08,0x1000,
266 {0x01,0x03,0x00,0x02},
267 0x63,
268 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
269 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
270 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
271 0xff},
272 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
273 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
274 0x08,0x00,0x0f,0x00},
275 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
276 0xff}
277 },
278/* 0x03: MD_3_200 - mode 0x03 - 0 */
279 {
280 0x50,0x18,0x08,0x1000,
281 {0x01,0x03,0x00,0x02},
282 0x63,
283 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
284 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
285 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
286 0xff},
287 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
288 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
289 0x08,0x00,0x0f,0x00},
290 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
291 0xff}
292 },
293/* 0x04: MD_4 */
294 {
295 0x28,0x18,0x08,0x4000,
296 {0x09,0x03,0x00,0x02},
297 0x63,
298 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
299 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
300 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
301 0xff},
302 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
303 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
304 0x01,0x00,0x03,0x00},
305 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
306 0xff}
307 },
308/* 0x05: MD_5 */
309 {
310 0x28,0x18,0x08,0x4000,
311 {0x09,0x03,0x00,0x02},
312 0x63,
313 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
314 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
315 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
316 0xff},
317 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
318 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
319 0x01,0x00,0x03,0x00},
320 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
321 0xff}
322 },
323/* 0x06: MD_6 */
324 {
325 0x50,0x18,0x08,0x4000,
326 {0x01,0x01,0x00,0x06},
327 0x63,
328 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
329 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
330 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
331 0xff},
332 {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
333 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
334 0x01,0x00,0x01,0x00},
335 {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
336 0xff}
337 },
338/* 0x07: MD_7 */
339 {
340 0x50,0x18,0x0e,0x1000,
341 {0x00,0x03,0x00,0x03},
342 0xa6,
343 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
344 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
345 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
346 0xff},
347 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
348 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
349 0x0e,0x00,0x0f,0x08},
350 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
351 0xff}
352 },
353/* 0x08: MDA_DAC */
354 {
355 0x00,0x00,0x00,0x0000,
356 {0x00,0x00,0x00,0x15},
357 0x15,
358 {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
359 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
360 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
361 0x00},
362 {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
363 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
364 0x15,0x15,0x15,0x15},
365 {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
366 0x3f}
367 },
368/* 0x09: CGA_DAC */
369 {
370 0x00,0x10,0x04,0x0114,
371 {0x11,0x09,0x15,0x00},
372 0x10,
373 {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
374 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
375 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
376 0x04},
377 {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
378 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
379 0x3e,0x2b,0x3b,0x2f},
380 {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
381 0x3f}
382 },
383/* 0x0a: EGA_DAC */
384 {
385 0x00,0x10,0x04,0x0114,
386 {0x11,0x05,0x15,0x20},
387 0x30,
388 {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
389 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
390 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
391 0x06},
392 {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
393 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
394 0x1e,0x0b,0x1b,0x0f},
395 {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
396 0x3f}
397 },
398/* 0x0b: VGA_DAC */
399 {
400 0x00,0x10,0x04,0x0114,
401 {0x11,0x09,0x15,0x2a},
402 0x3a,
403 {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
404 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
405 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
406 0x1f},
407 {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
408 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
409 0x1c,0x0e,0x11,0x15},
410 {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
411 0x04}
412 },
413/* 0x0c */
414 {
415 0x08,0x0c,0x10,0x0a08,
416 {0x0c,0x0e,0x10,0x0b},
417 0x0c,
418 {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
419 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
420 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
421 0x06},
422 {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
423 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
424 0x00,0x00,0x00,0x00},
425 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
426 0x00}
427 },
428/* 0x0d: MD_D */
429 {
430 0x28,0x18,0x08,0x2000,
431 {0x09,0x0f,0x00,0x06},
432 0x63,
433 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 2c is 2b for 300 */
434 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
435 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
436 0xff},
437 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
438 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
439 0x01,0x00,0x0f,0x00},
440 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
441 0xff}
442 },
443/* 0x0e: MD_E */
444 {
445 0x50,0x18,0x08,0x4000,
446 {0x01,0x0f,0x00,0x06},
447 0x63,
448 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
449 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
451 0xff},
452 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
453 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
454 0x01,0x00,0x0f,0x00},
455 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
456 0xff}
457 },
458/* 0x0f: ExtVGATable - modes > 0x13 */
459 {
460 0x00,0x00,0x00,0x0000,
461 {0x01,0x0f,0x00,0x0e},
462 0x23,
463 {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
464 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
465 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
466 0xff},
467 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
468 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
469 0x01,0x00,0x00,0x00},
470 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
471 0xff}
472 },
473/* 0x10: ROM_SAVEPTR - totally different for 300 */
474 {
475 0x9f,0x3b,0x00,0x00c0,
476 {0x00,0x00,0x00,0x00},
477 0x00,
478 {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
479 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
480 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
481 0x00},
482 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
483 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
484 0x00,0x00,0x00,0x00},
485 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
486 0x00}
487 },
488/* 0x11: MD_F */
489 {
490 0x50,0x18,0x0e,0x8000,
491 {0x01,0x0f,0x00,0x06},
492 0xa2,
493 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
494 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
495 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
496 0xff},
497 {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
498 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
499 0x0b,0x00,0x05,0x00},
500 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
501 0xff}
502 },
503/* 0x12: MD_10 */
504 {
505 0x50,0x18,0x0e,0x8000,
506 {0x01,0x0f,0x00,0x06},
507 0xa3,
508 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
509 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
510 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
511 0xff},
512 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
513 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
514 0x01,0x00,0x0f,0x00},
515 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
516 0xff}
517 },
518/* 0x13: MD_0_350 */
519 {
520 0x28,0x18,0x0e,0x0800,
521 {0x09,0x03,0x00,0x02},
522 0xa3,
523 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
524 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
525 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
526 0xff},
527 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
528 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
529 0x08,0x00,0x0f,0x00},
530 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
531 0xff}
532 },
533/* 0x14: MD_1_350 */
534 {
535 0x28,0x18,0x0e,0x0800,
536 {0x09,0x03,0x00,0x02},
537 0xa3,
538 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
539 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
540 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
541 0xff},
542 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
543 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
544 0x08,0x00,0x0f,0x00},
545 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
546 0xff}
547 },
548/* 0x15: MD_2_350 */
549 {
550 0x50,0x18,0x0e,0x1000,
551 {0x01,0x03,0x00,0x02},
552 0xa3,
553 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
554 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
555 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
556 0xff},
557 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
558 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
559 0x08,0x00,0x0f,0x00},
560 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
561 0xff}
562 },
563/* 0x16: MD_3_350 - mode 0x03 - 1 */
564 {
565 0x50,0x18,0x0e,0x1000,
566 {0x01,0x03,0x00,0x02},
567 0xa3,
568 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
569 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
570 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
571 0xff},
572 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
573 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
574 0x08,0x00,0x0f,0x00},
575 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
576 0xff}
577 },
578/* 0x17: MD_0_1_400 */
579 {
580 0x28,0x18,0x10,0x0800,
581 {0x08,0x03,0x00,0x02},
582 0x67,
583 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
584 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
585 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
586 0xff},
587 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
588 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
589 0x0c,0x00,0x0f,0x08},
590 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
591 0xff}
592 },
593/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
594 {
595 0x50,0x18,0x10,0x1000,
596 {0x00,0x03,0x00,0x02},
597 0x67,
598 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
599 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
600 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
601 0xff},
602 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
603 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
604 0x0c,0x00,0x0f,0x08},
605 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
606 0xff}
607 },
608/* 0x19: MD_7_400 */
609 {
610 0x50,0x18,0x10,0x1000,
611 {0x00,0x03,0x00,0x02},
612 0x66,
613 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
614 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
615 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
616 0xff},
617 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
618 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
619 0x0e,0x00,0x0f,0x08},
620 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
621 0xff}
622 },
623/* 0x1a: MD_11 */
624 {
625 0x50,0x1d,0x10,0xa000,
626 {0x01,0x0f,0x00,0x06},
627 0xe3,
628 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
629 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
630 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, /* e9,8b is ea,8c on 300 */
631 0xff},
632 {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
633 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
634 0x01,0x00,0x0f,0x00},
635 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
636 0xff}
637 },
638/* 0x1b: ExtEGATable - Modes <= 0x02 */
639 {
640 0x50,0x1d,0x10,0xa000,
641 {0x01,0x0f,0x00,0x06},
642 0xe3,
643 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
644 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
645 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, /* e9,8b is ea,8c on 300 */
646 0xff},
647 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
648 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
649 0x01,0x00,0x0f,0x00},
650 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
651 0xff}
652 },
653/* 0x1c: MD_13 */
654 {
655 0x28,0x18,0x08,0x2000,
656 {0x01,0x0f,0x00,0x0e},
657 0x63,
658 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
659 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
660 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
661 0xff},
662 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
663 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
664 0x41,0x00,0x0f,0x00},
665 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
666 0xff}
667 }
668};
669#endif
670
671/**************************************************************/
672/* SIS VIDEO BRIDGE ----------------------------------------- */
673/**************************************************************/
674
675static const unsigned char SiS_SoftSetting = 0x30; /* RAM setting */
676
677static const unsigned char SiS_OutputSelect = 0x40;
678
679static const unsigned char SiS_NTSCTiming[] = {
680 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
681 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
682 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
683 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
684 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
685 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
686 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
687 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
688};
689
690static const unsigned char SiS_PALTiming[] = {
691 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
692 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
693 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
694 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
695 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
696 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
697 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
698 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
699};
700
701static const unsigned char SiS_HiTVExtTiming[] = {
702 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
703 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
704 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
705 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
706 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
707 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
708 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
709 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
710};
711
712static const unsigned char SiS_HiTVSt1Timing[] = {
713 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
714 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
715 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
716 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
717 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
718 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
719 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
720 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
721};
722
723static const unsigned char SiS_HiTVSt2Timing[] = {
724 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
725 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
726 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
727 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
728 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
729 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
730 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
731 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
732};
733
734#if 0
735static const unsigned char SiS_HiTVTextTiming[] = {
736 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
737 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
738 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
739 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
740 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
741 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
742 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
743 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
744};
745#endif
746
747static const unsigned char SiS_HiTVGroup3Data[] = {
748 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
749 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
750 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
751 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
752 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
753 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
754 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
755 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
756};
757
758static const unsigned char SiS_HiTVGroup3Simu[] = {
759 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
760 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
761 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
762 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
763 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
764 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
765 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
766 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
767};
768
769#if 0
770static const unsigned char SiS_HiTVGroup3Text[] = {
771 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
772 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
773 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
774 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
775 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
776 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
777 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
778 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
779};
780#endif
781
782static const struct SiS_TVData SiS_StPALData[] =
783{
784 { 1, 1, 864, 525,1270, 400, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
785 { 1, 1, 864, 525,1270, 350, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
786 { 1, 1, 864, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
787 { 1, 1, 864, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
788 { 1, 1, 864, 525,1270, 480, 50, 0, 760, 0,0xf4,0xff,0x1c,0x22},
789 { 1, 1, 864, 525,1270, 600, 50, 0, 0,0x300,0xf4,0xff,0x1c,0x22}
790};
791
792static const struct SiS_TVData SiS_ExtPALData[] =
793{
794 { 27, 10, 848, 448,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
795 { 108, 35, 848, 398,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22},
796 { 12, 5, 954, 448,1270, 530, 50, 0, 50, 0,0xf1,0x04,0x1f,0x18},
797 { 9, 4, 960, 463,1644, 438, 50, 0, 50, 0,0xf4,0x0b,0x1c,0x0a},
798 { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
799 { 36, 25,1060, 648,1270, 530, 438, 0, 438, 0,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 */
800 { 3, 2,1080, 619,1270, 540, 438, 0, 438, 0,0xf3,0x00,0x1d,0x20}, /* 720x576 */
801 { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
802 { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
803 { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a} /* 720x480 */
804};
805
806static const struct SiS_TVData SiS_StNTSCData[] =
807{
808 { 1, 1, 858, 525,1270, 400, 50, 0, 760, 0,0xf1,0x04,0x1f,0x18},
809 { 1, 1, 858, 525,1270, 350, 50, 0, 640, 0,0xf1,0x04,0x1f,0x18},
810 { 1, 1, 858, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
811 { 1, 1, 858, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
812 { 1, 1, 858, 525,1270, 480, 0, 0, 760, 0,0xf1,0x04,0x1f,0x18}
813};
814
815static const struct SiS_TVData SiS_ExtNTSCData[] =
816{
817 { 143, 65, 858, 443,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
818 { 88, 35, 858, 393,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18},
819 { 143, 70, 924, 443,1270, 440, 92, 0, 92, 0,0xf1,0x04,0x1f,0x18},
820 { 143, 70, 924, 393,1270, 440, 92, 0, 92, 0,0xf4,0x0b,0x1c,0x0a},
821 { 143, 76, 836, 523,1270, 440, 224, 0, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
822 { 143, 120,1056, 643,1270, 440, 0, 1, 0, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
823 { 143, 76, 836, 523,1270, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
824 { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */
825#if 0 /* flimmert und ist unten abgeschnitten (NTSCHT, NTSC clock) */
826 { 65, 64,1056, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
827#endif
828#if 0
829 { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
830#endif
831#if 0
832 { 1, 1,1120, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
833#endif
834#if 0
835 { 1, 1, 938, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
836#endif
837#if 0 /* zoom hin, unten abgeschnitten (NTSC2HT, NTSC1024 clock) */
838 { 1, 1,1072, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
839#endif
840#if 1 /* zu weit links (squeezed) (NTSC2HT, NTSC1024 clock) */
841 { 1, 1,1100, 846,1270, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
842#endif
843#if 0 /* zu weit links, rechts abgeschnitten (NTSC2HT, NTSC1024 clock) */
844 { 1, 1,1100, 846,1412, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
845#endif
846};
847
848static const struct SiS_TVData SiS_StHiTVData[] = /* Slave + TVSimu */
849{
850 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
851 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
852 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
853 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
854 { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
855 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150, 1, 0, 0, 0, 0, 0, 0}
856};
857
858static const struct SiS_TVData SiS_St2HiTVData[] = /* Slave */
859{
860 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
861 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
862 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
863 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
864 { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d, 1, 0, 0, 0, 0, 0, 0},
865 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c, 1, 0, 0, 0, 0, 0, 0}
866};
867
868static const struct SiS_TVData SiS_ExtHiTVData[] =
869{ /* all ok */
870 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
871 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
872 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
873 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
874 { 5, 1, 0x348,0x233,0x670,0x3c0,0x166, 1, 0, 0, 0, 0, 0, 0}, /* 640x480 */
875 { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x600 */
876 { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 */
877 { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x1024 */
878 { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x480 */
879 { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x576 */
880 { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x720 */
881 { 8, 3, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 960x600 */
882};
883
884static const struct SiS_TVData SiS_St525pData[] =
885{
886 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
887 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
888 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
889 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
890 { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
891};
892
893static const struct SiS_TVData SiS_St750pData[] =
894{
895 { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
896 { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
897 { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
898 { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
899 { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
900};
901
902static const struct SiS_TVData SiS_Ext750pData[] =
903{ /* all ok */
904 { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0}, /* 320x200/640x400 */
905 { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
906 { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
907 { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
908 { 2, 1, 1100, 590, 1130, 640, 50, 0, 0, 0, 0, 0, 0, 0}, /* 640x480 */
909 { 3, 2, 1210, 690, 1130, 660, 50, 0, 0, 0, 0, 0, 0, 0}, /* 800x600 OK */
910 { 2, 1, 1100, 562, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720x480 OK */
911 { 1, 1, 1375, 878, 1130, 640, 638, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 OK */
912 { 5, 3, 1100, 675, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720/768x576 OK */
913 { 25, 24, 1496, 755, 1120, 680, 50, 0, 0, 0, 0, 0, 0, 0} /* 1280x720 OK */
914};
915
916static const struct SiS_LCDData SiS_LCD1280x720Data[] = /* 2.03.00 */
917{
918 { 44, 15, 864, 430, 1408, 806 }, /* 640x400 */
919 { 128, 35, 792, 385, 1408, 806 },
920 { 44, 15, 864, 430, 1408, 806 },
921 { 128, 35, 792, 385, 1408, 806 },
922 { 22, 9, 864, 516, 1408, 806 }, /* 640x480 */
923 { 8, 5, 1056, 655, 1408, 806 }, /* 800x600 */
924 { 0, 0, 0, 0, 0, 0 }, /* 1024x768 */
925 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
926 { 0, 0, 0, 0, 0, 0 },
927 { 0, 0, 0, 0, 0, 0 },
928 { 1, 1, 1408, 806, 1408, 806 } /* 1280x720 */
929};
930
931/* About 1280x768: For TMDS, Panel_1280x768 will only be set if
932 * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
933 * Other TMDS panels of this resolution will be treated as custom.
934 * For LVDS, we know another type (_2).
935 * (Note: 1280x768_3 is now special for SiS301/NetVista
936 */
937
938static const struct SiS_LCDData SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
939{
940 { 64, 21, 858, 434, 1408, 806 }, /* 640x400 */
941 { 32, 9, 858, 372, 1408, 806 },
942 { 64, 21, 858, 434, 1408, 806 },
943 { 32, 9, 858, 372, 1408, 806 },
944 { 143, 68, 1024, 527, 1408, 806 }, /* 640x480 */
945 { 64, 51, 1364, 663, 1408, 806 }, /* 800x600 */
946 { 88, 81, 1296, 806, 1408, 806 }, /* 1024x768 */
947 { 0, 0, 0, 0, 0, 0 },
948 { 1, 1, 1408, 806, 1408, 806 }, /* 1280x768 */
949 { 0, 0, 0, 0, 0, 0 },
950 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 - from Ext */
951};
952
953static const struct SiS_LCDData SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
954{
955 { 16, 5, 960, 410, 1600, 806 }, /* 640x400 */
956 { 64, 21, 1152, 364, 1600, 806 },
957 { 16, 5, 960, 410, 1600, 806 },
958 { 64, 21, 1152, 364, 1600, 806 },
959 { 32, 13, 1040, 493, 1600, 806 }, /* 640x480 */
960 { 16, 9, 1152, 618, 1600, 806 }, /* 800x600 */
961 { 25, 21, 1344, 796, 1600, 806 }, /* 1024x768 */
962 { 0, 0, 0, 0, 0, 0 },
963 { 1, 1, 1600, 806, 1600, 806 }, /* 1280x768 */
964 { 0, 0, 0, 0, 0, 0 },
965 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 */
966};
967
968#if 0 /* Not used; _3 now reserved for NetVista (SiS301) */
969static const struct SiS_LCDData SiS_LCD1280x768_3Data[] =
970{
971 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
972 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
973 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
974 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
975 { 32, 15, 1056, 513, 1408, 806 }, /* ,664 */ /* 640x480 */
976 { 176, 125, 1280, 640, 1408, 806 }, /* ,768 */ /* 800x600 */
977 { 64, 61, 1342, 806, 1408, 806 }, /* 1024x768 */
978 { 0, 0, 0, 0, 0, 0 },
979 { 1, 1, 1408, 806, 1408, 806 }, /* 1280x768 */
980 { 0, 0, 0, 0, 0, 0 },
981 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 from above */
982};
983#endif
984
985static const struct SiS_LCDData SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
986{
987 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
988 { 128, 49, 1232, 361, 1408, 816 },
989 { 128, 51, 1122, 412, 1408, 816 },
990 { 128, 49, 1232, 361, 1408, 816 },
991 { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
992 { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
993 { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
994 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
995 { 1, 1, 1408, 816, 1408, 816 }, /* 1280x800 */
996 { 0, 0, 0, 0, 0, 0 }, /* 1280x768 (patch index) */
997 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
998};
999
1000static const struct SiS_LCDData SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
1001{
1002 { 97, 42, 1344, 409, 1552, 812 }, /* 640x400 */
1003 { 97, 35, 1280, 358, 1552, 812 },
1004 { 97, 42, 1344, 409, 1552, 812 },
1005 { 97, 35, 1280, 358, 1552, 812 },
1006 { 97, 39, 1040, 488, 1552, 812 }, /* 640x480 */
1007 { 194, 105, 1120, 608, 1552, 812 }, /* 800x600 */
1008 { 97, 84, 1400, 780, 1552, 812 }, /* 1024x768 */
1009 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1010 { 1, 1, 1552, 812, 1552, 812 }, /* 1280x800 */
1011 { 97, 96, 1600, 780, 1552, 812 }, /* 1280x768 - patch index */
1012 { 97, 90, 1600, 730, 1552, 812 } /* 1280x720 */
1013};
1014
1015#if 0
1016static const struct SiS_LCDData SiS_LCD1280x800_3Data[] = /* 2.02.05a (LVDS); m250 */
1017{
1018 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
1019 { 128, 49, 1232, 361, 1408, 816 },
1020 { 128, 51, 1122, 412, 1408, 816 },
1021 { 128, 49, 1232, 361, 1408, 816 },
1022 { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
1023 { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
1024 { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
1025 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1026 { 1, 1, 1408, 816, 1408, 816 }, /* 1280x800 */
1027 { 0, 0, 0, 0, 0, 0 }, /* 1280x768 - patch index */
1028 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
1029};
1030#endif
1031
1032static const struct SiS_LCDData SiS_LCD1280x854Data[] = /* 2.21.00CS (LVDS) */
1033{
1034 { 56, 15, 936, 410, 1664, 861 }, /* 640x400 */
1035 { 64, 25, 1586, 355, 1664, 861 },
1036 { 56, 15, 936, 410, 1664, 861 },
1037 { 64, 25, 1586, 355, 1664, 861 },
1038 { 91, 45, 1464, 485, 1664, 861 }, /* 640x480 */
1039 { 182, 75, 976, 605, 1664, 861 }, /* 800x600 */
1040 { 91, 66, 1342, 774, 1664, 861 }, /* 1024x768 */
1041 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1042 { 26, 25, 1708, 807, 1664, 861 }, /* 1280x800 */
1043 { 13, 12, 1708, 774, 1664, 861 }, /* 1280x768 - patch index */
1044 { 52, 45, 1708, 725, 1664, 861 }, /* 1280x720 */
1045 { 0, 0, 0, 0, 0, 0 },
1046 { 0, 0, 0, 0, 0, 0 },
1047 { 1, 1, 1664, 861, 1664, 861 } /* 1280x854 */
1048};
1049
1050static const struct SiS_LCDData SiS_LCD1280x960Data[] =
1051{
1052 { 9, 2, 800, 500, 1800, 1000 },
1053 { 9, 2, 800, 500, 1800, 1000 },
1054 { 4, 1, 900, 500, 1800, 1000 },
1055 { 4, 1, 900, 500, 1800, 1000 },
1056 { 9, 2, 800, 500, 1800, 1000 },
1057 { 30, 11, 1056, 625, 1800, 1000 },
1058 { 5, 3, 1350, 800, 1800, 1000 },
1059 { 1, 1, 1576, 1050, 1576, 1050 },
1060 { 1, 1, 1800, 1000, 1800, 1000 },
1061 { 0, 0, 0, 0, 0, 0 },
1062 { 0, 0, 0, 0, 0, 0 },
1063 { 0, 0, 0, 0, 0, 0 },
1064 { 0, 0, 0, 0, 0, 0 },
1065 { 0, 0, 0, 0, 0, 0 }
1066};
1067
1068static const struct SiS_LCDData SiS_StLCD1400x1050Data[] =
1069{
1070 { 211, 100, 2100, 408, 1688, 1066 },
1071 { 211, 64, 1536, 358, 1688, 1066 },
1072 { 211, 100, 2100, 408, 1688, 1066 },
1073 { 211, 64, 1536, 358, 1688, 1066 },
1074 { 211, 48, 840, 488, 1688, 1066 },
1075 { 211, 72, 1008, 609, 1688, 1066 },
1076 { 211, 128, 1400, 776, 1688, 1066 },
1077 { 211, 205, 1680, 1041, 1688, 1066 },
1078 { 1, 1, 1688, 1066, 1688, 1066 },
1079 { 0, 0, 0, 0, 0, 0 },
1080 { 0, 0, 0, 0, 0, 0 },
1081 { 0, 0, 0, 0, 0, 0 },
1082 { 0, 0, 0, 0, 0, 0 },
1083 { 0, 0, 0, 0, 0, 0 }
1084};
1085
1086static const struct SiS_LCDData SiS_ExtLCD1400x1050Data[] =
1087{
1088/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */
1089 { 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */
1090 { 211, 64, 1536, 358, 1688, 1066 },
1091 { 211, 100, 2100, 408, 1688, 1066 },
1092 { 211, 64, 1536, 358, 1688, 1066 },
1093/* { 211, 80, 1400, 490, 1688, 1066 }, 640x480 (6330) */
1094 { 211, 48, 840, 488, 1688, 1066 }, /* 640x480 (6325) WORKS */
1095/* { 211, 117, 1638, 613, 1688, 1066 }, 800x600 (6330) */
1096 { 211, 72, 1008, 609, 1688, 1066 }, /* 800x600 (6325) WORKS */
1097 { 211, 128, 1400, 776, 1688, 1066 }, /* 1024x768 */
1098 { 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
1099 { 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
1100 { 0, 0, 0, 0, 0, 0 }, /* kludge */
1101 { 211, 120, 1400, 730, 1688, 1066 }, /* 1280x720 */
1102 { 0, 0, 0, 0, 0, 0 },
1103 { 0, 0, 0, 0, 0, 0 },
1104 { 0, 0, 0, 0, 0, 0 }
1105};
1106
1107static const struct SiS_LCDData SiS_LCD1680x1050Data[] =
1108{
1109 { 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */
1110 { 10, 3, 1710, 362, 1900, 1066 },
1111 { 95, 24, 1260, 410, 1900, 1066 },
1112 { 10, 3, 1710, 362, 1900, 1066 },
1113 { 95, 32, 1400, 490, 1900, 1066 }, /* 4 640x480 */
1114 { 95, 42, 1470, 610, 1900, 1066 }, /* 5 800x600 */
1115 { 95, 64, 1750, 784, 1900, 1066 }, /* 6 1024x768 */
1116 { 95, 94, 1900, 1055, 1900, 1066 }, /* 7 1280x1024 */
1117 { 41, 31, 1900, 806, 1900, 1066 }, /* 8 1280x768 */
1118 { 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch index */
1119 { 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */
1120 { 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
1121 { 1, 1, 1900, 1066, 1900, 1066 }, /* 12 1680x1050 */
1122 { 0, 0, 0, 0, 0, 0 }
1123};
1124
1125static const struct SiS_LCDData SiS_StLCD1600x1200Data[] =
1126{
1127 {27, 4, 800, 500, 2160, 1250 },
1128 {27, 4, 800, 500, 2160, 1250 },
1129 { 6, 1, 900, 500, 2160, 1250 },
1130 { 6, 1, 900, 500, 2160, 1250 },
1131 {27, 1, 800, 500, 2160, 1250 },
1132 { 4, 1,1080, 625, 2160, 1250 },
1133 { 5, 2,1350, 800, 2160, 1250 },
1134 {135,88,1600,1100, 2160, 1250 },
1135 {72, 49,1680,1092, 2160, 1250 },
1136 { 1, 1,2160,1250, 2160, 1250 },
1137 { 0, 0, 0, 0, 0, 0 },
1138 { 0, 0, 0, 0, 0, 0 },
1139 { 0, 0, 0, 0, 0, 0 },
1140 { 0, 0, 0, 0, 0, 0 }
1141};
1142
1143static const struct SiS_LCDData SiS_ExtLCD1600x1200Data[] =
1144{
1145 {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
1146/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */
1147 {27, 4, 800, 500, 2160, 1250 },
1148 { 6, 1, 900, 500, 2160, 1250 },
1149 { 6, 1, 900, 500, 2160, 1250 },
1150 {45, 8, 960, 505, 2160, 1250 }, /* 640x480 (6330) WORKS */
1151/* {27, 1, 800, 500, 2160, 1250 }, 640x480 (6325) */
1152 { 4, 1,1080, 625, 2160, 1250 },
1153 { 5, 2,1350, 800, 2160, 1250 },
1154 {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
1155 {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
1156 { 1, 1,2160,1250, 2160, 1250 },
1157 { 0, 0, 0, 0, 0, 0 },
1158 { 0, 0, 0, 0, 0, 0 },
1159 { 0, 0, 0, 0, 0, 0 },
1160 { 0, 0, 0, 0, 0, 0 }
1161};
1162
1163static const struct SiS_LCDData SiS_NoScaleData[] =
1164{
1165 { 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */
1166 { 1, 1, 800, 449, 800, 449 },
1167 { 1, 1, 900, 449, 900, 449 },
1168 { 1, 1, 900, 449, 900, 449 },
1169 { 1, 1, 800, 525, 800, 525 }, /* 0x04: 320x240, 640x480 */
1170 { 1, 1,1056, 628,1056, 628 }, /* 0x05: 400x300, 800x600 */
1171 { 1, 1,1344, 806,1344, 806 }, /* 0x06: 512x384, 1024x768 */
1172 { 1, 1,1688,1066,1688,1066 }, /* 0x07: 1280x1024 */
1173 { 1, 1,1688, 802,1688, 802 }, /* 0x08: 1280x768: Fujitsu, TMDS only */
1174 { 1, 1,2160,1250,2160,1250 }, /* 0x09: 1600x1200 */
1175 { 1, 1,1800,1000,1800,1000 }, /* 0x0a: 1280x960 */
1176 { 1, 1,1688,1066,1688,1066 }, /* 0x0b: 1400x1050 */
1177 { 1, 1,1650, 750,1650, 750 }, /* 0x0c: 1280x720 (TMDS, projector) */
1178 { 1, 1,1552, 812,1552, 812 }, /* 0x0d: 1280x800_2 (LVDS) (was: 1408,816/ 1656,841) */
1179 { 1, 1,1900,1066,1900,1066 }, /* 0x0e: 1680x1050 (LVDS) */
1180 { 1, 1,1660, 806,1660, 806 }, /* 0x0f: 1280x768_2 (LVDS) */
1181 { 1, 1,1664, 798,1664, 798 }, /* 0x10: 1280x768_3 (NetVista SiS 301) - TODO */
1182 { 1, 1,1688, 802,1688, 802 }, /* 0x11: 1280x768 (TMDS Fujitsu) */
1183 { 1, 1,1408, 806,1408, 806 }, /* 0x12: 1280x720 (LVDS) */
1184 { 1, 1, 896, 497, 896, 497 }, /* 0x13: 720x480 */
1185 { 1, 1, 912, 597, 912, 597 }, /* 0x14: 720x576 */
1186 { 1, 1, 912, 597, 912, 597 }, /* 0x15: 768x576 */
1187 { 1, 1,1056, 497,1056, 497 }, /* 0x16: 848x480 */
1188 { 1, 1,1064, 497,1064, 497 }, /* 0x17: 856x480 */
1189 { 1, 1,1056, 497,1056, 497 }, /* 0x18: 800x480 */
1190 { 1, 1,1328, 739,1328, 739 }, /* 0x19: 1024x576 */
1191 { 1, 1,1680, 892,1680, 892 }, /* 0x1a: 1152x864 */
1192 { 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */
1193 { 1, 1,1104, 563,1104, 563 }, /* 0x1c: 960x540 */
1194 { 1, 1,1120, 618,1120, 618 }, /* 0x1d: 960x600 */
1195 { 1, 1,1408, 816,1408, 816 }, /* 0x1f: 1280x800 (TMDS special) */
1196 { 1, 1,1760,1235,1760,1235 }, /* 0x20: 1600x1200 for LCDA */
1197 { 1, 1,2048,1320,2048,1320 }, /* 0x21: 1600x1200 for non-SiS LVDS */
1198 { 1, 1,1664, 861,1664, 861 } /* 0x22: 1280x854 */
1199};
1200
1201/**************************************************************/
1202/* LVDS ----------------------------------------------------- */
1203/**************************************************************/
1204
1205/* FSTN/DSTN 320x240, 2 variants */
1206static const struct SiS_LVDSData SiS_LVDS320x240Data_1[]=
1207{
1208 { 848, 433, 400, 525},
1209 { 848, 389, 400, 525},
1210 { 848, 433, 400, 525},
1211 { 848, 389, 400, 525},
1212 { 848, 518, 400, 525},
1213 {1056, 628, 400, 525},
1214 { 400, 525, 400, 525} /* xSTN */
1215};
1216
1217static const struct SiS_LVDSData SiS_LVDS320x240Data_2[]=
1218{
1219 { 800, 445, 800, 525},
1220 { 800, 395, 800, 525},
1221 { 800, 445, 800, 525},
1222 { 800, 395, 800, 525},
1223 { 800, 525, 800, 525},
1224 {1056, 628,1056, 628},
1225 { 480, 525, 480, 525} /* xSTN */
1226};
1227
1228static const struct SiS_LVDSData SiS_LVDS640x480Data_1[]=
1229{
1230 { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
1231 { 800, 395, 800, 525},
1232 { 800, 445, 800, 525},
1233 { 800, 395, 800, 525},
1234 { 800, 525, 800, 525}
1235};
1236
1237static const struct SiS_LVDSData SiS_LVDS800x600Data_1[]=
1238{
1239 { 848, 433,1060, 629},
1240 { 848, 389,1060, 629},
1241 { 848, 433,1060, 629},
1242 { 848, 389,1060, 629},
1243 { 848, 518,1060, 629},
1244 {1056, 628,1056, 628}
1245};
1246
1247static const struct SiS_LVDSData SiS_LVDS1024x600Data_1[] =
1248{
1249 { 840, 604,1344, 800},
1250 { 840, 560,1344, 800},
1251 { 840, 604,1344, 800},
1252 { 840, 560,1344, 800},
1253 { 840, 689,1344, 800},
1254 {1050, 800,1344, 800},
1255 {1344, 800,1344, 800}
1256};
1257
1258static const struct SiS_LVDSData SiS_LVDS1024x768Data_1[]=
1259{
1260 { 840, 438,1344, 806},
1261 { 840, 409,1344, 806},
1262 { 840, 438,1344, 806},
1263 { 840, 409,1344, 806},
1264 { 840, 518,1344, 806}, /* 640x480 */
1265 {1050, 638,1344, 806}, /* 800x600 */
1266 {1344, 806,1344, 806}, /* 1024x768 */
1267};
1268
1269static const struct SiS_LVDSData SiS_CHTVUNTSCData[]=
1270{
1271 { 840, 600, 840, 600},
1272 { 840, 600, 840, 600},
1273 { 840, 600, 840, 600},
1274 { 840, 600, 840, 600},
1275 { 784, 600, 784, 600},
1276 {1064, 750,1064, 750},
1277 {1160, 945,1160, 945}
1278};
1279
1280static const struct SiS_LVDSData SiS_CHTVONTSCData[]=
1281{
1282 { 840, 525, 840, 525},
1283 { 840, 525, 840, 525},
1284 { 840, 525, 840, 525},
1285 { 840, 525, 840, 525},
1286 { 784, 525, 784, 525},
1287 {1040, 700,1040, 700},
1288 {1160, 840,1160, 840}
1289};
1290
1291/* CRT1 CRTC data for slave modes */
1292
1293static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_1[] =
1294{
1295 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1296 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1297 0x00 }},
1298 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1299 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1300 0x00 }},
1301 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1302 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1303 0x00 }},
1304 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1305 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1306 0x00 }},
1307 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1308 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1309 0x00 }},
1310 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1311 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1312 0x01 }},
1313 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1314 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1315 0x00 }}
1316};
1317
1318static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2[] =
1319{
1320 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1321 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1322 0x00}},
1323 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1324 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1325 0x00}},
1326 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1327 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1328 0x00}},
1329 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1330 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1331 0x00}},
1332 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1333 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1334 0x00}},
1335 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1336 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1337 0x01}},
1338#if 0
1339 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1340 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1341 0x00}}
1342#endif
1343 {{0x5f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
1344 0xe9,0x8b,0xe8,0x0c,0x00,0x00,0x05,
1345 0x00}},
1346};
1347
1348static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2_H[] =
1349{
1350 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1351 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1352 0x00}},
1353 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1354 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1355 0x00}},
1356 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1357 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1358 0x00}},
1359 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1360 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1361 0x00}},
1362 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1363 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1364 0x00}},
1365 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1366 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1367 0x01}},
1368 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1369 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1370 0x00}}
1371};
1372
1373static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3[] =
1374{
1375 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1376 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1377 0x00}},
1378 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1379 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1380 0x00}},
1381 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1382 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1383 0x00}},
1384 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1385 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1386 0x00}},
1387 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1388 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1389 0x00}},
1390 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1391 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1392 0x01}},
1393 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1394 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1395 0x00}}
1396};
1397
1398static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3_H[] =
1399{
1400 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1401 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1402 0x00}},
1403 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1404 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1405 0x00}},
1406 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1407 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1408 0x00}},
1409 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1410 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1411 0x00}},
1412 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1413 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1414 0x00}},
1415 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1416 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1417 0x01}},
1418 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1419 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1420 0x00}}
1421};
1422
1423static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1[] =
1424{
1425 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1426 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1427 0x00}},
1428 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1429 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1430 0x00}},
1431 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1432 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1433 0x00}},
1434 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1435 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1436 0x00}},
1437 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1438 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1439 0x00}},
1440 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1441 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1442 0x01}}
1443};
1444
1445static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
1446{
1447 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1448 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1449 0x00}},
1450 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1451 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1452 0x00}},
1453 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1454 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1455 0x00}},
1456 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1457 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1458 0x00}},
1459 {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
1460 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1461 0x00}}
1462};
1463
1464bool SiSInitPtr(struct SiS_Private *SiS_Pr);
1465unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
1466 int VDisplay, int Depth, bool FSTN,
1467 unsigned short CustomT, int LCDwith, int LCDheight,
1468 unsigned int VBFlags2);
1469unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
1470 int VDisplay, int Depth, unsigned int VBFlags2);
1471unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
1472 int VDisplay, int Depth, unsigned int VBFlags2);
1473
1474void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
1475void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
1476void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
1477void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
1478void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
1479unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1480 unsigned short ModeIdIndex);
1481bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
1482
1483bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1484 unsigned short *ModeIdIndex);
1485unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1486 unsigned short ModeIdIndex);
1487unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
1488unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
1489unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1490 unsigned short ModeIdIndex);
1491unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
1492 unsigned short ModeIdIndex, unsigned short RRTI);
1493#ifdef CONFIG_FB_SIS_300
1494void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
1495 unsigned short *idx2);
1496unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
1497unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
1498#endif
1499void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
1500bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
1501void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
1502void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1503 unsigned short ModeIdIndex);
1504void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
1505 int yres, struct fb_var_screeninfo *var, bool writeres);
1506
1507/* From init301.c: */
1508extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1509 unsigned short ModeIdIndex, int chkcrt2mode);
1510extern void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1511 unsigned short ModeIdIndex);
1512extern void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
1513extern void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1514 unsigned short ModeIdIndex);
1515extern void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
1516extern void SiS_DisableBridge(struct SiS_Private *);
1517extern bool SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
1518extern unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1519 unsigned short ModeIdIndex);
1520extern void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
1521extern unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1522 unsigned short ModeIdIndex);
1523extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
1524extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1525 unsigned short ModeIdIndex, unsigned short RRTI);
1526extern bool SiS_IsVAMode(struct SiS_Private *);
1527extern bool SiS_IsDualEdge(struct SiS_Private *);
1528
1529#ifdef CONFIG_FB_SIS_300
1530extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
1531extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
1532 unsigned int val);
1533#endif
1534#ifdef CONFIG_FB_SIS_315
1535extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
1536 unsigned char val);
1537extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
1538#endif
1539
1540#endif
1541
diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c
new file mode 100644
index 000000000000..a89e3cafd5ad
--- /dev/null
+++ b/drivers/video/fbdev/sis/init301.c
@@ -0,0 +1,11071 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7 * XGI V3XT/V5/V8, Z7
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9 *
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11 *
12 * If distributed as part of the Linux kernel, the following license terms
13 * apply:
14 *
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
19 * *
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
24 * *
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28 *
29 * Otherwise, the following license terms apply:
30 *
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
33 * * are met:
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
41 * *
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 *
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 *
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56 * Used by permission.
57 *
58 */
59
60#if 1
61#define SET_EMI /* 302LV/ELV: Set EMI values */
62#endif
63
64#if 1
65#define SET_PWD /* 301/302LV: Set PWD */
66#endif
67
68#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
69#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
70#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
71
72#include "init301.h"
73
74#ifdef CONFIG_FB_SIS_300
75#include "oem300.h"
76#endif
77
78#ifdef CONFIG_FB_SIS_315
79#include "oem310.h"
80#endif
81
82#define SiS_I2CDELAY 1000
83#define SiS_I2CDELAYSHORT 150
84
85static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
86static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
87
88/*********************************************/
89/* HELPER: Lock/Unlock CRT2 */
90/*********************************************/
91
92void
93SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
94{
95 if(SiS_Pr->ChipType == XGI_20)
96 return;
97 else if(SiS_Pr->ChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101}
102
103static
104void
105SiS_LockCRT2(struct SiS_Private *SiS_Pr)
106{
107 if(SiS_Pr->ChipType == XGI_20)
108 return;
109 else if(SiS_Pr->ChipType >= SIS_315H)
110 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
111 else
112 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
113}
114
115/*********************************************/
116/* HELPER: Write SR11 */
117/*********************************************/
118
119static void
120SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
121{
122 if(SiS_Pr->ChipType >= SIS_661) {
123 DataAND &= 0x0f;
124 DataOR &= 0x0f;
125 }
126 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
127}
128
129/*********************************************/
130/* HELPER: Get Pointer to LCD structure */
131/*********************************************/
132
133#ifdef CONFIG_FB_SIS_315
134static unsigned char *
135GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
136{
137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
138 unsigned char *myptr = NULL;
139 unsigned short romindex = 0, reg = 0, idx = 0;
140
141 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
142 * due to the variaty of panels the BIOS doesn't know about.
143 * Exception: If the BIOS has better knowledge (such as in case
144 * of machines with a 301C and a panel that does not support DDC)
145 * use the BIOS data as well.
146 */
147
148 if((SiS_Pr->SiS_ROMNew) &&
149 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
150
151 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
152 else reg = 0x7d;
153
154 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
155
156 if(idx < (8*26)) {
157 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
158 }
159 romindex = SISGETROMW(0x100);
160 if(romindex) {
161 romindex += idx;
162 myptr = &ROMAddr[romindex];
163 }
164 }
165 return myptr;
166}
167
168static unsigned short
169GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
170{
171 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
172 unsigned short romptr = 0;
173
174 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
175 * due to the variaty of panels the BIOS doesn't know about.
176 * Exception: If the BIOS has better knowledge (such as in case
177 * of machines with a 301C and a panel that does not support DDC)
178 * use the BIOS data as well.
179 */
180
181 if((SiS_Pr->SiS_ROMNew) &&
182 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
183 romptr = SISGETROMW(0x102);
184 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
185 }
186
187 return romptr;
188}
189#endif
190
191/*********************************************/
192/* Adjust Rate for CRT2 */
193/*********************************************/
194
195static bool
196SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
197 unsigned short RRTI, unsigned short *i)
198{
199 unsigned short checkmask=0, modeid, infoflag;
200
201 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
202
203 if(SiS_Pr->SiS_VBType & VB_SISVB) {
204
205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
206
207 checkmask |= SupportRAMDAC2;
208 if(SiS_Pr->ChipType >= SIS_315H) {
209 checkmask |= SupportRAMDAC2_135;
210 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
211 checkmask |= SupportRAMDAC2_162;
212 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
213 checkmask |= SupportRAMDAC2_202;
214 }
215 }
216 }
217
218 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
219
220 checkmask |= SupportLCD;
221 if(SiS_Pr->ChipType >= SIS_315H) {
222 if(SiS_Pr->SiS_VBType & VB_SISVB) {
223 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
224 if(modeid == 0x2e) checkmask |= Support64048060Hz;
225 }
226 }
227 }
228
229 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
230
231 checkmask |= SupportHiVision;
232
233 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
234
235 checkmask |= SupportTV;
236 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
237 checkmask |= SupportTV1024;
238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
239 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
240 checkmask |= SupportYPbPr750p;
241 }
242 }
243 }
244
245 }
246
247 } else { /* LVDS */
248
249 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
250 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
251 checkmask |= SupportCHTV;
252 }
253 }
254
255 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
256 checkmask |= SupportLCD;
257 }
258
259 }
260
261 /* Look backwards in table for matching CRT2 mode */
262 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
263 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
264 if(infoflag & checkmask) return true;
265 if((*i) == 0) break;
266 }
267
268 /* Look through the whole mode-section of the table from the beginning
269 * for a matching CRT2 mode if no mode was found yet.
270 */
271 for((*i) = 0; ; (*i)++) {
272 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
273 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
274 if(infoflag & checkmask) return true;
275 }
276 return false;
277}
278
279/*********************************************/
280/* Get rate index */
281/*********************************************/
282
283unsigned short
284SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
285{
286 unsigned short RRTI,i,backup_i;
287 unsigned short modeflag,index,temp,backupindex;
288 static const unsigned short LCDRefreshIndex[] = {
289 0x00, 0x00, 0x01, 0x01,
290 0x01, 0x01, 0x01, 0x01,
291 0x01, 0x01, 0x01, 0x01,
292 0x01, 0x01, 0x01, 0x01,
293 0x00, 0x00, 0x00, 0x00
294 };
295
296 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
297 if(ModeNo == 0xfe) return 0;
298
299 if(ModeNo <= 0x13) {
300 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
301 } else {
302 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
303 }
304
305 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
306 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
307 if(modeflag & HalfDCLK) return 0;
308 }
309 }
310
311 if(ModeNo < 0x14) return 0xFFFF;
312
313 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
314 backupindex = index;
315
316 if(index > 0) index--;
317
318 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
321 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
322 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
323 }
324 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
325 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
326 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
327 if(index > temp) index = temp;
328 }
329 }
330 } else {
331 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
332 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
333 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
334 }
335 }
336 }
337
338 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
339 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
340
341 if(SiS_Pr->ChipType >= SIS_315H) {
342 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
343 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
344 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
345 if(backupindex <= 1) RRTI++;
346 }
347 }
348 }
349
350 i = 0;
351 do {
352 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
353 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
354 temp &= ModeTypeMask;
355 if(temp < SiS_Pr->SiS_ModeType) break;
356 i++;
357 index--;
358 } while(index != 0xFFFF);
359
360 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
361 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
362 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
363 if(temp & InterlaceMode) i++;
364 }
365 }
366
367 i--;
368
369 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
370 backup_i = i;
371 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
372 i = backup_i;
373 }
374 }
375
376 return (RRTI + i);
377}
378
379/*********************************************/
380/* STORE CRT2 INFO in CR34 */
381/*********************************************/
382
383static void
384SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
385{
386 unsigned short temp1, temp2;
387
388 /* Store CRT1 ModeNo in CR34 */
389 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
390 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
391 temp2 = ~(SetInSlaveMode >> 8);
392 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
393}
394
395/*********************************************/
396/* HELPER: GET SOME DATA FROM BIOS ROM */
397/*********************************************/
398
399#ifdef CONFIG_FB_SIS_300
400static bool
401SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
402{
403 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
404 unsigned short temp,temp1;
405
406 if(SiS_Pr->SiS_UseROM) {
407 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
408 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
409 temp1 = SISGETROMW(0x23b);
410 if(temp1 & temp) return true;
411 }
412 }
413 return false;
414}
415
416static bool
417SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
418{
419 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
420 unsigned short temp,temp1;
421
422 if(SiS_Pr->SiS_UseROM) {
423 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
424 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
425 temp1 = SISGETROMW(0x23d);
426 if(temp1 & temp) return true;
427 }
428 }
429 return false;
430}
431#endif
432
433/*********************************************/
434/* HELPER: DELAY FUNCTIONS */
435/*********************************************/
436
437void
438SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
439{
440 while (delaytime-- > 0)
441 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
442}
443
444#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
445static void
446SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
447{
448 SiS_DDC2Delay(SiS_Pr, delay * 36);
449}
450#endif
451
452#ifdef CONFIG_FB_SIS_315
453static void
454SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
455{
456 while(delay--) {
457 SiS_GenericDelay(SiS_Pr, 6623);
458 }
459}
460#endif
461
462#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
463static void
464SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
465{
466 while(delay--) {
467 SiS_GenericDelay(SiS_Pr, 66);
468 }
469}
470#endif
471
472static void
473SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
474{
475#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
476 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
477 unsigned short PanelID, DelayIndex, Delay=0;
478#endif
479
480 if(SiS_Pr->ChipType < SIS_315H) {
481
482#ifdef CONFIG_FB_SIS_300
483
484 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
485 if(SiS_Pr->SiS_VBType & VB_SISVB) {
486 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
487 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
488 }
489 DelayIndex = PanelID >> 4;
490 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
491 Delay = 3;
492 } else {
493 if(DelayTime >= 2) DelayTime -= 2;
494 if(!(DelayTime & 0x01)) {
495 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
496 } else {
497 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
498 }
499 if(SiS_Pr->SiS_UseROM) {
500 if(ROMAddr[0x220] & 0x40) {
501 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
502 else Delay = (unsigned short)ROMAddr[0x226];
503 }
504 }
505 }
506 SiS_ShortDelay(SiS_Pr, Delay);
507
508#endif /* CONFIG_FB_SIS_300 */
509
510 } else {
511
512#ifdef CONFIG_FB_SIS_315
513
514 if((SiS_Pr->ChipType >= SIS_661) ||
515 (SiS_Pr->ChipType <= SIS_315PRO) ||
516 (SiS_Pr->ChipType == SIS_330) ||
517 (SiS_Pr->SiS_ROMNew)) {
518
519 if(!(DelayTime & 0x01)) {
520 SiS_DDC2Delay(SiS_Pr, 0x1000);
521 } else {
522 SiS_DDC2Delay(SiS_Pr, 0x4000);
523 }
524
525 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
526 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
527 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
528
529 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
530 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
531 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
532 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
533 }
534 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
535 DelayIndex = PanelID & 0x0f;
536 } else {
537 DelayIndex = PanelID >> 4;
538 }
539 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
540 Delay = 3;
541 } else {
542 if(DelayTime >= 2) DelayTime -= 2;
543 if(!(DelayTime & 0x01)) {
544 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
545 } else {
546 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
547 }
548 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
549 if(ROMAddr[0x13c] & 0x40) {
550 if(!(DelayTime & 0x01)) {
551 Delay = (unsigned short)ROMAddr[0x17e];
552 } else {
553 Delay = (unsigned short)ROMAddr[0x17f];
554 }
555 }
556 }
557 }
558 SiS_ShortDelay(SiS_Pr, Delay);
559 }
560
561 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
562
563 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
564 if(!(DelayTime & 0x01)) {
565 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
566 } else {
567 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
568 }
569 Delay <<= 8;
570 SiS_DDC2Delay(SiS_Pr, Delay);
571
572 }
573
574#endif /* CONFIG_FB_SIS_315 */
575
576 }
577}
578
579#ifdef CONFIG_FB_SIS_315
580static void
581SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
582{
583 int i;
584 for(i = 0; i < DelayLoop; i++) {
585 SiS_PanelDelay(SiS_Pr, DelayTime);
586 }
587}
588#endif
589
590/*********************************************/
591/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
592/*********************************************/
593
594void
595SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
596{
597 unsigned short watchdog;
598
599 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
600 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
601
602 watchdog = 65535;
603 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
604 watchdog = 65535;
605 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
606}
607
608#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
609static void
610SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
611{
612 unsigned short watchdog;
613
614 watchdog = 65535;
615 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
616 watchdog = 65535;
617 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
618}
619#endif
620
621static void
622SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
623{
624 if(SiS_Pr->ChipType < SIS_315H) {
625#ifdef CONFIG_FB_SIS_300
626 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
627 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
628 }
629 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
630 SiS_WaitRetrace1(SiS_Pr);
631 } else {
632 SiS_WaitRetrace2(SiS_Pr, 0x25);
633 }
634#endif
635 } else {
636#ifdef CONFIG_FB_SIS_315
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
638 SiS_WaitRetrace1(SiS_Pr);
639 } else {
640 SiS_WaitRetrace2(SiS_Pr, 0x30);
641 }
642#endif
643 }
644}
645
646static void
647SiS_VBWait(struct SiS_Private *SiS_Pr)
648{
649 unsigned short tempal,temp,i,j;
650
651 temp = 0;
652 for(i = 0; i < 3; i++) {
653 for(j = 0; j < 100; j++) {
654 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
655 if(temp & 0x01) {
656 if((tempal & 0x08)) continue;
657 else break;
658 } else {
659 if(!(tempal & 0x08)) continue;
660 else break;
661 }
662 }
663 temp ^= 0x01;
664 }
665}
666
667static void
668SiS_VBLongWait(struct SiS_Private *SiS_Pr)
669{
670 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
671 SiS_VBWait(SiS_Pr);
672 } else {
673 SiS_WaitRetrace1(SiS_Pr);
674 }
675}
676
677/*********************************************/
678/* HELPER: MISC */
679/*********************************************/
680
681#ifdef CONFIG_FB_SIS_300
682static bool
683SiS_Is301B(struct SiS_Private *SiS_Pr)
684{
685 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
686 return false;
687}
688#endif
689
690static bool
691SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
692{
693 if(SiS_Pr->ChipType == SIS_730) {
694 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
695 }
696 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
697 return false;
698}
699
700bool
701SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
702{
703#ifdef CONFIG_FB_SIS_315
704 if(SiS_Pr->ChipType >= SIS_315H) {
705 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
706 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
707 }
708 }
709#endif
710 return false;
711}
712
713bool
714SiS_IsVAMode(struct SiS_Private *SiS_Pr)
715{
716#ifdef CONFIG_FB_SIS_315
717 unsigned short flag;
718
719 if(SiS_Pr->ChipType >= SIS_315H) {
720 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
721 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
722 }
723#endif
724 return false;
725}
726
727#ifdef CONFIG_FB_SIS_315
728static bool
729SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
730{
731 if(SiS_IsVAMode(SiS_Pr)) return true;
732 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
733 return false;
734}
735#endif
736
737static bool
738SiS_IsDualLink(struct SiS_Private *SiS_Pr)
739{
740#ifdef CONFIG_FB_SIS_315
741 if(SiS_Pr->ChipType >= SIS_315H) {
742 if((SiS_CRT2IsLCD(SiS_Pr)) ||
743 (SiS_IsVAMode(SiS_Pr))) {
744 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
745 }
746 }
747#endif
748 return false;
749}
750
751#ifdef CONFIG_FB_SIS_315
752static bool
753SiS_TVEnabled(struct SiS_Private *SiS_Pr)
754{
755 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
756 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
757 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
758 }
759 return false;
760}
761#endif
762
763#ifdef CONFIG_FB_SIS_315
764static bool
765SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
766{
767 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
768 return false;
769}
770#endif
771
772#ifdef CONFIG_FB_SIS_315
773static bool
774SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
775{
776 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
777 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
778 }
779 return false;
780}
781#endif
782
783#ifdef CONFIG_FB_SIS_315
784static bool
785SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
786{
787 unsigned short flag;
788
789 if(SiS_Pr->ChipType == SIS_650) {
790 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
791 /* Check for revision != A0 only */
792 if((flag == 0xe0) || (flag == 0xc0) ||
793 (flag == 0xb0) || (flag == 0x90)) return false;
794 } else if(SiS_Pr->ChipType >= SIS_661) return false;
795 return true;
796}
797#endif
798
799#ifdef CONFIG_FB_SIS_315
800static bool
801SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
802{
803 if(SiS_Pr->ChipType >= SIS_315H) {
804 /* YPrPb = 0x08 */
805 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
806 }
807 return false;
808}
809#endif
810
811#ifdef CONFIG_FB_SIS_315
812static bool
813SiS_IsChScart(struct SiS_Private *SiS_Pr)
814{
815 if(SiS_Pr->ChipType >= SIS_315H) {
816 /* Scart = 0x04 */
817 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
818 }
819 return false;
820}
821#endif
822
823#ifdef CONFIG_FB_SIS_315
824static bool
825SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
826{
827 unsigned short flag;
828
829 if(SiS_Pr->ChipType >= SIS_315H) {
830 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
831 if(flag & SetCRT2ToTV) return true;
832 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
833 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
834 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
835 } else {
836 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
837 if(flag & SetCRT2ToTV) return true;
838 }
839 return false;
840}
841#endif
842
843#ifdef CONFIG_FB_SIS_315
844static bool
845SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
846{
847 unsigned short flag;
848
849 if(SiS_Pr->ChipType >= SIS_315H) {
850 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
851 if(flag & SetCRT2ToLCD) return true;
852 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
853 if(flag & SetToLCDA) return true;
854 } else {
855 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
856 if(flag & SetCRT2ToLCD) return true;
857 }
858 return false;
859}
860#endif
861
862static bool
863SiS_HaveBridge(struct SiS_Private *SiS_Pr)
864{
865 unsigned short flag;
866
867 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
868 return true;
869 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
870 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
871 if((flag == 1) || (flag == 2)) return true;
872 }
873 return false;
874}
875
876static bool
877SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
878{
879 unsigned short flag;
880
881 if(SiS_HaveBridge(SiS_Pr)) {
882 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
883 if(SiS_Pr->ChipType < SIS_315H) {
884 flag &= 0xa0;
885 if((flag == 0x80) || (flag == 0x20)) return true;
886 } else {
887 flag &= 0x50;
888 if((flag == 0x40) || (flag == 0x10)) return true;
889 }
890 }
891 return false;
892}
893
894static bool
895SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
896{
897 unsigned short flag1;
898
899 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
900 if(flag1 & (SetInSlaveMode >> 8)) return true;
901 return false;
902}
903
904/*********************************************/
905/* GET VIDEO BRIDGE CONFIG INFO */
906/*********************************************/
907
908/* Setup general purpose IO for Chrontel communication */
909#ifdef CONFIG_FB_SIS_300
910void
911SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
912{
913 unsigned int acpibase;
914 unsigned short temp;
915
916 if(!(SiS_Pr->SiS_ChSW)) return;
917
918 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
919 acpibase &= 0xFFFF;
920 if(!acpibase) return;
921 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
922 temp &= 0xFEFF;
923 SiS_SetRegShort((acpibase + 0x3c), temp);
924 temp = SiS_GetRegShort((acpibase + 0x3c));
925 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
926 temp &= 0xFEFF;
927 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
928 SiS_SetRegShort((acpibase + 0x3a), temp);
929 temp = SiS_GetRegShort((acpibase + 0x3a));
930}
931#endif
932
933void
934SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
935 unsigned short ModeIdIndex, int checkcrt2mode)
936{
937 unsigned short tempax, tempbx, temp;
938 unsigned short modeflag, resinfo = 0;
939
940 SiS_Pr->SiS_SetFlag = 0;
941
942 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
943
944 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
945
946 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
947 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
948 }
949
950 tempbx = 0;
951
952 if(SiS_HaveBridge(SiS_Pr)) {
953
954 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
955 tempbx |= temp;
956 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
957 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
958 tempbx |= tempax;
959
960#ifdef CONFIG_FB_SIS_315
961 if(SiS_Pr->ChipType >= SIS_315H) {
962 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
963 if(ModeNo == 0x03) {
964 /* Mode 0x03 is never in driver mode */
965 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
966 }
967 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
968 /* Reset LCDA setting if not driver mode */
969 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
970 }
971 if(IS_SIS650) {
972 if(SiS_Pr->SiS_UseLCDA) {
973 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
974 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
975 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
976 }
977 }
978 }
979 }
980 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
981 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
982 tempbx |= SetCRT2ToLCDA;
983 }
984 }
985
986 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
987 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
988 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
989 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
990 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
991 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
992 tempbx |= SetCRT2ToYPbPr525750;
993 }
994 }
995 }
996
997 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
998 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
999 if(temp & SetToLCDA) {
1000 tempbx |= SetCRT2ToLCDA;
1001 }
1002 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1003 if(temp & EnableCHYPbPr) {
1004 tempbx |= SetCRT2ToCHYPbPr;
1005 }
1006 }
1007 }
1008 }
1009
1010#endif /* CONFIG_FB_SIS_315 */
1011
1012 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1013 tempbx &= ~(SetCRT2ToRAMDAC);
1014 }
1015
1016 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1017 temp = SetCRT2ToSVIDEO |
1018 SetCRT2ToAVIDEO |
1019 SetCRT2ToSCART |
1020 SetCRT2ToLCDA |
1021 SetCRT2ToLCD |
1022 SetCRT2ToRAMDAC |
1023 SetCRT2ToHiVision |
1024 SetCRT2ToYPbPr525750;
1025 } else {
1026 if(SiS_Pr->ChipType >= SIS_315H) {
1027 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1028 temp = SetCRT2ToAVIDEO |
1029 SetCRT2ToSVIDEO |
1030 SetCRT2ToSCART |
1031 SetCRT2ToLCDA |
1032 SetCRT2ToLCD |
1033 SetCRT2ToCHYPbPr;
1034 } else {
1035 temp = SetCRT2ToLCDA |
1036 SetCRT2ToLCD;
1037 }
1038 } else {
1039 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040 temp = SetCRT2ToTV | SetCRT2ToLCD;
1041 } else {
1042 temp = SetCRT2ToLCD;
1043 }
1044 }
1045 }
1046
1047 if(!(tempbx & temp)) {
1048 tempax = DisableCRT2Display;
1049 tempbx = 0;
1050 }
1051
1052 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1053
1054 unsigned short clearmask = ( DriverMode |
1055 DisableCRT2Display |
1056 LoadDACFlag |
1057 SetNotSimuMode |
1058 SetInSlaveMode |
1059 SetPALTV |
1060 SwitchCRT2 |
1061 SetSimuScanMode );
1062
1063 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1064 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1065 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1066 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1067 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1068 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1069
1070 } else {
1071
1072 if(SiS_Pr->ChipType >= SIS_315H) {
1073 if(tempbx & SetCRT2ToLCDA) {
1074 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1075 }
1076 }
1077 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1078 if(tempbx & SetCRT2ToTV) {
1079 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1080 }
1081 }
1082 if(tempbx & SetCRT2ToLCD) {
1083 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1084 }
1085 if(SiS_Pr->ChipType >= SIS_315H) {
1086 if(tempbx & SetCRT2ToLCDA) {
1087 tempbx |= SetCRT2ToLCD;
1088 }
1089 }
1090
1091 }
1092
1093 if(tempax & DisableCRT2Display) {
1094 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1095 tempbx = SetSimuScanMode | DisableCRT2Display;
1096 }
1097 }
1098
1099 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1100
1101 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1102 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1103 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1104 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1105 modeflag &= (~CRT2Mode);
1106 }
1107 }
1108
1109 if(!(tempbx & SetSimuScanMode)) {
1110 if(tempbx & SwitchCRT2) {
1111 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1112 if(resinfo != SIS_RI_1600x1200) {
1113 tempbx |= SetSimuScanMode;
1114 }
1115 }
1116 } else {
1117 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1118 if(!(tempbx & DriverMode)) {
1119 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1120 tempbx |= SetSimuScanMode;
1121 }
1122 }
1123 }
1124 }
1125 }
1126
1127 if(!(tempbx & DisableCRT2Display)) {
1128 if(tempbx & DriverMode) {
1129 if(tempbx & SetSimuScanMode) {
1130 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1131 if(resinfo != SIS_RI_1600x1200) {
1132 tempbx |= SetInSlaveMode;
1133 }
1134 }
1135 }
1136 } else {
1137 tempbx |= SetInSlaveMode;
1138 }
1139 }
1140
1141 }
1142
1143 SiS_Pr->SiS_VBInfo = tempbx;
1144
1145#ifdef CONFIG_FB_SIS_300
1146 if(SiS_Pr->ChipType == SIS_630) {
1147 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1148 }
1149#endif
1150
1151#if 0
1152 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1153 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1154#endif
1155}
1156
1157/*********************************************/
1158/* DETERMINE YPbPr MODE */
1159/*********************************************/
1160
1161void
1162SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1163{
1164
1165 unsigned char temp;
1166
1167 /* Note: This variable is only used on 30xLV systems.
1168 * CR38 has a different meaning on LVDS/CH7019 systems.
1169 * On 661 and later, these bits moved to CR35.
1170 *
1171 * On 301, 301B, only HiVision 1080i is supported.
1172 * On 30xLV, 301C, only YPbPr 1080i is supported.
1173 */
1174
1175 SiS_Pr->SiS_YPbPr = 0;
1176 if(SiS_Pr->ChipType >= SIS_661) return;
1177
1178 if(SiS_Pr->SiS_VBType) {
1179 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1180 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1181 }
1182 }
1183
1184 if(SiS_Pr->ChipType >= SIS_315H) {
1185 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1186 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1187 if(temp & 0x08) {
1188 switch((temp >> 4)) {
1189 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1190 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1191 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1192 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1193 }
1194 }
1195 }
1196 }
1197
1198}
1199
1200/*********************************************/
1201/* DETERMINE TVMode flag */
1202/*********************************************/
1203
1204void
1205SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1206{
1207 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1208 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1209 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1210
1211 SiS_Pr->SiS_TVMode = 0;
1212
1213 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1214 if(SiS_Pr->UseCustomMode) return;
1215
1216 if(ModeNo > 0x13) {
1217 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1218 }
1219
1220 if(SiS_Pr->ChipType < SIS_661) {
1221
1222 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1223
1224 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1225 temp = 0;
1226 if((SiS_Pr->ChipType == SIS_630) ||
1227 (SiS_Pr->ChipType == SIS_730)) {
1228 temp = 0x35;
1229 romindex = 0xfe;
1230 } else if(SiS_Pr->ChipType >= SIS_315H) {
1231 temp = 0x38;
1232 if(SiS_Pr->ChipType < XGI_20) {
1233 romindex = 0xf3;
1234 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1235 }
1236 }
1237 if(temp) {
1238 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1239 OutputSelect = ROMAddr[romindex];
1240 if(!(OutputSelect & EnablePALMN)) {
1241 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1242 }
1243 }
1244 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1245 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1246 if(temp1 & EnablePALM) { /* 0x40 */
1247 SiS_Pr->SiS_TVMode |= TVSetPALM;
1248 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1249 } else if(temp1 & EnablePALN) { /* 0x80 */
1250 SiS_Pr->SiS_TVMode |= TVSetPALN;
1251 }
1252 } else {
1253 if(temp1 & EnableNTSCJ) { /* 0x40 */
1254 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1255 }
1256 }
1257 }
1258 /* Translate HiVision/YPbPr to our new flags */
1259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1260 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1261 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1262 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1263 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1264 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1265 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1266 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1267 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1268 SiS_Pr->SiS_TVMode |= TVSetPAL;
1269 }
1270 }
1271 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1272 if(SiS_Pr->SiS_CHOverScan) {
1273 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1274 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1275 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1276 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1277 }
1278 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1279 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1280 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1281 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1282 }
1283 }
1284 if(SiS_Pr->SiS_CHSOverScan) {
1285 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1286 }
1287 }
1288 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1289 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1290 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1291 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1292 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1293 } else {
1294 if(temp & EnableNTSCJ) {
1295 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1296 }
1297 }
1298 }
1299 }
1300
1301 } else { /* 661 and later */
1302
1303 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1304 if(temp1 & 0x01) {
1305 SiS_Pr->SiS_TVMode |= TVSetPAL;
1306 if(temp1 & 0x08) {
1307 SiS_Pr->SiS_TVMode |= TVSetPALN;
1308 } else if(temp1 & 0x04) {
1309 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1310 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1311 }
1312 SiS_Pr->SiS_TVMode |= TVSetPALM;
1313 }
1314 } else {
1315 if(temp1 & 0x02) {
1316 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1317 }
1318 }
1319 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1320 if(SiS_Pr->SiS_CHOverScan) {
1321 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1322 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1323 }
1324 }
1325 }
1326 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1327 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1328 temp1 &= 0xe0;
1329 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1330 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1331 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1332 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1333 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1334 }
1335 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1336 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1337 SiS_Pr->SiS_TVMode |= TVAspect169;
1338 } else {
1339 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1340 if(temp1 & 0x02) {
1341 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1342 SiS_Pr->SiS_TVMode |= TVAspect169;
1343 } else {
1344 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1345 }
1346 } else {
1347 SiS_Pr->SiS_TVMode |= TVAspect43;
1348 }
1349 }
1350 }
1351 }
1352 }
1353
1354 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1355
1356 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1357
1358 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1359 SiS_Pr->SiS_TVMode |= TVSetPAL;
1360 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1361 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1362 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1363 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1364 }
1365 }
1366
1367 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1368 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1369 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1370 }
1371 }
1372
1373 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1374 if(resinfo == SIS_RI_1024x768) {
1375 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1376 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1377 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1378 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1379 }
1380 }
1381 }
1382
1383 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1384 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1385 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1386 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1387 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1388 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1389 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1390 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1391 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1392 }
1393 }
1394
1395 }
1396
1397 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1398}
1399
1400/*********************************************/
1401/* GET LCD INFO */
1402/*********************************************/
1403
1404static unsigned short
1405SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1406{
1407 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1408 /* Translate my LCDResInfo to BIOS value */
1409 switch(temp) {
1410 case Panel_1280x768_2: temp = Panel_1280x768; break;
1411 case Panel_1280x800_2: temp = Panel_1280x800; break;
1412 case Panel_1280x854: temp = Panel661_1280x854; break;
1413 }
1414 return temp;
1415}
1416
1417static void
1418SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1419{
1420#ifdef CONFIG_FB_SIS_315
1421 unsigned char *ROMAddr;
1422 unsigned short temp;
1423
1424 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1425 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1426 SiS_Pr->SiS_NeedRomModeData = true;
1427 SiS_Pr->PanelHT = temp;
1428 }
1429 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1430 SiS_Pr->SiS_NeedRomModeData = true;
1431 SiS_Pr->PanelVT = temp;
1432 }
1433 SiS_Pr->PanelHRS = SISGETROMW(10);
1434 SiS_Pr->PanelHRE = SISGETROMW(12);
1435 SiS_Pr->PanelVRS = SISGETROMW(14);
1436 SiS_Pr->PanelVRE = SISGETROMW(16);
1437 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1438 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1439 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1440 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1441 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1442 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1443 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1444
1445 }
1446#endif
1447}
1448
1449static void
1450SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1451 const unsigned char *nonscalingmodes)
1452{
1453 int i = 0;
1454 while(nonscalingmodes[i] != 0xff) {
1455 if(nonscalingmodes[i++] == resinfo) {
1456 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1457 (SiS_Pr->UsePanelScaler == -1)) {
1458 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1459 }
1460 break;
1461 }
1462 }
1463}
1464
1465void
1466SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1467{
1468 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1469 bool panelcanscale = false;
1470#ifdef CONFIG_FB_SIS_300
1471 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1472 static const unsigned char SiS300SeriesLCDRes[] =
1473 { 0, 1, 2, 3, 7, 4, 5, 8,
1474 0, 0, 10, 0, 0, 0, 0, 15 };
1475#endif
1476#ifdef CONFIG_FB_SIS_315
1477 unsigned char *myptr = NULL;
1478#endif
1479
1480 SiS_Pr->SiS_LCDResInfo = 0;
1481 SiS_Pr->SiS_LCDTypeInfo = 0;
1482 SiS_Pr->SiS_LCDInfo = 0;
1483 SiS_Pr->PanelHRS = 999; /* HSync start */
1484 SiS_Pr->PanelHRE = 999; /* HSync end */
1485 SiS_Pr->PanelVRS = 999; /* VSync start */
1486 SiS_Pr->PanelVRE = 999; /* VSync end */
1487 SiS_Pr->SiS_NeedRomModeData = false;
1488
1489 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1490 SiS_Pr->Alternate1600x1200 = false;
1491
1492 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1493
1494 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1495
1496 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1497 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1498 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1499 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1500 }
1501
1502 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1503
1504 /* For broken BIOSes: Assume 1024x768 */
1505 if(temp == 0) temp = 0x02;
1506
1507 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1508 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1509 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1510 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1511 } else {
1512 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1513 }
1514 temp &= 0x0f;
1515#ifdef CONFIG_FB_SIS_300
1516 if(SiS_Pr->ChipType < SIS_315H) {
1517 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1518 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1519 if(temp < 0x0f) temp &= 0x07;
1520 }
1521 /* Translate 300 series LCDRes to 315 series for unified usage */
1522 temp = SiS300SeriesLCDRes[temp];
1523 }
1524#endif
1525
1526 /* Translate to our internal types */
1527#ifdef CONFIG_FB_SIS_315
1528 if(SiS_Pr->ChipType == SIS_550) {
1529 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1530 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1531 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1532 } else if(SiS_Pr->ChipType >= SIS_661) {
1533 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1534 }
1535#endif
1536
1537 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1538 if(temp == Panel310_1280x768) {
1539 temp = Panel_1280x768_2;
1540 }
1541 if(SiS_Pr->SiS_ROMNew) {
1542 if(temp == Panel661_1280x800) {
1543 temp = Panel_1280x800_2;
1544 }
1545 }
1546 }
1547
1548 SiS_Pr->SiS_LCDResInfo = temp;
1549
1550#ifdef CONFIG_FB_SIS_300
1551 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1552 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1553 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1554 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1555 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1556 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1557 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1558 }
1559 }
1560#endif
1561
1562 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1563 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1564 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1565 } else {
1566 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1567 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1568 }
1569
1570 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1571 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1572 /* Need temp below! */
1573
1574 /* These must/can't scale no matter what */
1575 switch(SiS_Pr->SiS_LCDResInfo) {
1576 case Panel_320x240_1:
1577 case Panel_320x240_2:
1578 case Panel_320x240_3:
1579 case Panel_1280x960:
1580 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1581 break;
1582 case Panel_640x480:
1583 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1584 }
1585
1586 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1587
1588 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1589 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1590
1591 /* Dual link, Pass 1:1 BIOS default, etc. */
1592#ifdef CONFIG_FB_SIS_315
1593 if(SiS_Pr->ChipType >= SIS_661) {
1594 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1595 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1596 }
1597 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1598 if(SiS_Pr->SiS_ROMNew) {
1599 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1600 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1601 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1602 }
1603 }
1604 } else if(SiS_Pr->ChipType >= SIS_315H) {
1605 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1606 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1607 }
1608 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1609 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1610 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1611 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1612 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1613 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1614 }
1615 } else if(!(SiS_Pr->SiS_ROMNew)) {
1616 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1617 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1618 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1619 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1620 }
1621 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1622 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1623 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1624 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1625 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1626 }
1627 }
1628 }
1629 }
1630#endif
1631
1632 /* Pass 1:1 */
1633 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1634 /* Always center screen on LVDS (if scaling is disabled) */
1635 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1636 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1637 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1638 /* Always center screen on SiS LVDS (if scaling is disabled) */
1639 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1640 } else {
1641 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1642 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1643 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1644 }
1645 }
1646
1647 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1648 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1649
1650 switch(SiS_Pr->SiS_LCDResInfo) {
1651 case Panel_320x240_1:
1652 case Panel_320x240_2:
1653 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1654 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1655 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1656 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1657 break;
1658 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1659 SiS_Pr->PanelVRE = 3;
1660 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1661 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1662 break;
1663 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1664 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1665 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1666 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1667 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1668 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1669 break;
1670 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1671 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1672 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1673 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1674 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1675 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1676 break;
1677 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1678 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1679 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1680 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1681 if(SiS_Pr->ChipType < SIS_315H) {
1682 SiS_Pr->PanelHRS = 23;
1683 SiS_Pr->PanelVRE = 5;
1684 }
1685 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1686 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1687 SiS_GetLCDInfoBIOS(SiS_Pr);
1688 break;
1689 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1690 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1691 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1692 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1693 if(SiS_Pr->ChipType < SIS_315H) {
1694 SiS_Pr->PanelHRS = 23;
1695 SiS_Pr->PanelVRE = 5;
1696 }
1697 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1699 break;
1700 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1701 break;
1702 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1703 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1704 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1705 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1706 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1707 /* Data above for TMDS (projector); get from BIOS for LVDS */
1708 SiS_GetLCDInfoBIOS(SiS_Pr);
1709 break;
1710 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1711 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1712 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1713 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1714 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1715 } else {
1716 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1717 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1718 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1719 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1720 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1721 }
1722 break;
1723 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1724 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1725 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1726 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1727 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1728 SiS_GetLCDInfoBIOS(SiS_Pr);
1729 break;
1730 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1731 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1732 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1733 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1734 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1735 SiS_GetLCDInfoBIOS(SiS_Pr);
1736 break;
1737 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1738 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1739 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1740 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1741 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1742 SiS_GetLCDInfoBIOS(SiS_Pr);
1743 break;
1744 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1745 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1746 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1747 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1748 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1749 SiS_GetLCDInfoBIOS(SiS_Pr);
1750 break;
1751 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1752 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1753 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1754 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1755 if(resinfo == SIS_RI_1280x1024) {
1756 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1757 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1758 }
1759 break;
1760 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1761 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1762 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1763 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1764 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1765 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1766 SiS_GetLCDInfoBIOS(SiS_Pr);
1767 break;
1768 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1769 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1770 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1771 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1772 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1773 SiS_GetLCDInfoBIOS(SiS_Pr);
1774 break;
1775 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1776 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1777 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1778 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1779 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1780 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1782 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1783 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1784 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1785 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1786 SiS_Pr->Alternate1600x1200 = true;
1787 }
1788 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1789 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1790 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1791 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1792 }
1793 SiS_GetLCDInfoBIOS(SiS_Pr);
1794 break;
1795 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1796 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1797 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1798 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1799 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1800 SiS_GetLCDInfoBIOS(SiS_Pr);
1801 break;
1802 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1803 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1804 break;
1805 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1806 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1807 break;
1808 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1809 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1810 break;
1811 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1812 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1813 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1814 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1815 if(SiS_Pr->CP_PreferredIndex != -1) {
1816 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1817 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1818 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1819 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1820 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1821 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1822 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1823 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1824 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1825 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1826 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1827 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1828 if(SiS_Pr->CP_PrefClock) {
1829 int idx;
1830 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1831 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1832 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1833 else idx = VCLK_CUSTOM_315;
1834 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1835 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1836 SiS_Pr->SiS_VCLKData[idx].SR2B =
1837 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1838 SiS_Pr->SiS_VCLKData[idx].SR2C =
1839 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1840 }
1841 }
1842 break;
1843 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1844 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1845 break;
1846 }
1847
1848 /* Special cases */
1849 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1850 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1851 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1852 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1853 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1854 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1855 SiS_Pr->PanelHRS = 999;
1856 SiS_Pr->PanelHRE = 999;
1857 }
1858
1859 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1860 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1861 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1862 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1863 SiS_Pr->PanelVRS = 999;
1864 SiS_Pr->PanelVRE = 999;
1865 }
1866
1867 /* DontExpand overrule */
1868 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1869
1870 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1871 /* No scaling for this mode on any panel (LCD=CRT2)*/
1872 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1873 }
1874
1875 switch(SiS_Pr->SiS_LCDResInfo) {
1876
1877 case Panel_Custom:
1878 case Panel_1152x864:
1879 case Panel_1280x768: /* TMDS only */
1880 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1881 break;
1882
1883 case Panel_800x600: {
1884 static const unsigned char nonscalingmodes[] = {
1885 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1886 };
1887 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1888 break;
1889 }
1890 case Panel_1024x768: {
1891 static const unsigned char nonscalingmodes[] = {
1892 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1893 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1894 0xff
1895 };
1896 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1897 break;
1898 }
1899 case Panel_1280x720: {
1900 static const unsigned char nonscalingmodes[] = {
1901 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1902 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1903 0xff
1904 };
1905 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1906 if(SiS_Pr->PanelHT == 1650) {
1907 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1908 }
1909 break;
1910 }
1911 case Panel_1280x768_2: { /* LVDS only */
1912 static const unsigned char nonscalingmodes[] = {
1913 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1914 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1915 SIS_RI_1152x768,0xff
1916 };
1917 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1918 switch(resinfo) {
1919 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1920 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1921 }
1922 break;
1923 }
1924 break;
1925 }
1926 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1927 static const unsigned char nonscalingmodes[] = {
1928 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1929 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1930 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1931 };
1932 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1933 break;
1934 }
1935 case Panel_1280x800_2: { /* SiS LVDS */
1936 static const unsigned char nonscalingmodes[] = {
1937 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1938 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1939 SIS_RI_1152x768,0xff
1940 };
1941 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1942 switch(resinfo) {
1943 case SIS_RI_1280x720:
1944 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1945 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1946 }
1947 break;
1948 }
1949 break;
1950 }
1951 case Panel_1280x854: { /* SiS LVDS */
1952 static const unsigned char nonscalingmodes[] = {
1953 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1954 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1955 SIS_RI_1152x768,0xff
1956 };
1957 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1958 switch(resinfo) {
1959 case SIS_RI_1280x720:
1960 case SIS_RI_1280x768:
1961 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
1962 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1963 }
1964 break;
1965 }
1966 break;
1967 }
1968 case Panel_1280x960: {
1969 static const unsigned char nonscalingmodes[] = {
1970 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1971 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1972 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1973 SIS_RI_1280x854,0xff
1974 };
1975 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976 break;
1977 }
1978 case Panel_1280x1024: {
1979 static const unsigned char nonscalingmodes[] = {
1980 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1981 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1982 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1983 SIS_RI_1280x854,SIS_RI_1280x960,0xff
1984 };
1985 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1986 break;
1987 }
1988 case Panel_1400x1050: {
1989 static const unsigned char nonscalingmodes[] = {
1990 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1991 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1992 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
1993 SIS_RI_1280x960,0xff
1994 };
1995 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1996 switch(resinfo) {
1997 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1998 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1999 }
2000 break;
2001 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2002 break;
2003 }
2004 break;
2005 }
2006 case Panel_1600x1200: {
2007 static const unsigned char nonscalingmodes[] = {
2008 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2009 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2010 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2011 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2012 };
2013 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 break;
2015 }
2016 case Panel_1680x1050: {
2017 static const unsigned char nonscalingmodes[] = {
2018 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2019 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2020 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2021 SIS_RI_1360x1024,0xff
2022 };
2023 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2024 break;
2025 }
2026 }
2027 }
2028
2029#ifdef CONFIG_FB_SIS_300
2030 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2031 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2032 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2033 }
2034 }
2035
2036 if(SiS_Pr->ChipType < SIS_315H) {
2037 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2038 if(SiS_Pr->SiS_UseROM) {
2039 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2040 if(!(ROMAddr[0x235] & 0x02)) {
2041 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2042 }
2043 }
2044 }
2045 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2046 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2047 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2048 }
2049 }
2050 }
2051#endif
2052
2053 /* Special cases */
2054
2055 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2056 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2057 }
2058
2059 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2060 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2061 }
2062
2063 switch(SiS_Pr->SiS_LCDResInfo) {
2064 case Panel_640x480:
2065 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2066 break;
2067 case Panel_1280x800:
2068 /* Don't pass 1:1 by default (TMDS special) */
2069 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2070 break;
2071 case Panel_1280x960:
2072 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2073 break;
2074 case Panel_Custom:
2075 if((!SiS_Pr->CP_PrefClock) ||
2076 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2077 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2078 }
2079 break;
2080 }
2081
2082 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2083 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2084 }
2085
2086 /* (In)validate LCDPass11 flag */
2087 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2088 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2089 }
2090
2091 /* LVDS DDA */
2092 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2093
2094 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2095 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2096 if(ModeNo == 0x12) {
2097 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2098 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2099 }
2100 } else if(ModeNo > 0x13) {
2101 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2102 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2103 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2104 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2105 }
2106 }
2107 }
2108 }
2109 }
2110 }
2111
2112 if(modeflag & HalfDCLK) {
2113 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2114 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2115 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2116 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2118 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2119 } else if(ModeNo > 0x13) {
2120 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2121 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2122 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2123 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2124 }
2125 }
2126 }
2127
2128 }
2129
2130 /* VESA timing */
2131 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2132 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2133 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2134 }
2135 } else {
2136 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2137 }
2138
2139#if 0
2140 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2141 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2142#endif
2143}
2144
2145/*********************************************/
2146/* GET VCLK */
2147/*********************************************/
2148
2149unsigned short
2150SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2151 unsigned short RefreshRateTableIndex)
2152{
2153 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2154 unsigned short modeflag, resinfo, tempbx;
2155 const unsigned char *CHTVVCLKPtr = NULL;
2156
2157 if(ModeNo <= 0x13) {
2158 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2159 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2160 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2161 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2162 VCLKIndexGENCRT = VCLKIndexGEN;
2163 } else {
2164 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2165 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2166 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2167 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2168 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2169 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2170 }
2171
2172 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2173
2174 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2175
2176 CRT2Index >>= 6;
2177 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2178
2179 if(SiS_Pr->ChipType < SIS_315H) {
2180 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2181 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2182 VCLKIndex = VCLKIndexGEN;
2183 }
2184 } else {
2185 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2186 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2187 switch(resinfo) {
2188 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2189 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2190 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2191 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2192 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2193 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2194 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2195 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2196 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2197 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2198 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2199 default: VCLKIndex = VCLKIndexGEN;
2200 }
2201
2202 if(ModeNo <= 0x13) {
2203 if(SiS_Pr->ChipType <= SIS_315PRO) {
2204 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2205 } else {
2206 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2207 }
2208 }
2209 if(SiS_Pr->ChipType <= SIS_315PRO) {
2210 if(VCLKIndex == 0) VCLKIndex = 0x41;
2211 if(VCLKIndex == 1) VCLKIndex = 0x43;
2212 if(VCLKIndex == 4) VCLKIndex = 0x44;
2213 }
2214 }
2215 }
2216
2217 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2218
2219 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2220 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2221 else VCLKIndex = HiTVVCLK;
2222 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2223 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2224 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2225 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2226 else VCLKIndex = TVVCLK;
2227
2228 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2229 else VCLKIndex += TVCLKBASE_315;
2230
2231 } else { /* VGA2 */
2232
2233 VCLKIndex = VCLKIndexGENCRT;
2234 if(SiS_Pr->ChipType < SIS_315H) {
2235 if(ModeNo > 0x13) {
2236 if( (SiS_Pr->ChipType == SIS_630) &&
2237 (SiS_Pr->ChipRevision >= 0x30)) {
2238 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2239 }
2240 /* Better VGA2 clock for 1280x1024@75 */
2241 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2242 }
2243 }
2244 }
2245
2246 } else { /* If not programming CRT2 */
2247
2248 VCLKIndex = VCLKIndexGENCRT;
2249 if(SiS_Pr->ChipType < SIS_315H) {
2250 if(ModeNo > 0x13) {
2251 if( (SiS_Pr->ChipType != SIS_630) &&
2252 (SiS_Pr->ChipType != SIS_300) ) {
2253 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2254 }
2255 }
2256 }
2257 }
2258
2259 } else { /* LVDS */
2260
2261 VCLKIndex = CRT2Index;
2262
2263 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2264
2265 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2266
2267 VCLKIndex &= 0x1f;
2268 tempbx = 0;
2269 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2270 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2271 tempbx += 2;
2272 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2273 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2274 }
2275 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2276 tempbx = 4;
2277 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2278 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2279 tempbx = 6;
2280 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2281 }
2282 }
2283 switch(tempbx) {
2284 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2285 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2286 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2287 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2288 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2289 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2290 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2291 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2292 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2293 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2294 }
2295 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2296
2297 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2298
2299 if(SiS_Pr->ChipType < SIS_315H) {
2300 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2301 } else {
2302 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2303 }
2304
2305#ifdef CONFIG_FB_SIS_300
2306 /* Special Timing: Barco iQ Pro R series */
2307 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2308
2309 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2310 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2311 if(SiS_Pr->ChipType < SIS_315H) {
2312 VCLKIndex = VCLK34_300;
2313 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2314 } else {
2315 VCLKIndex = VCLK34_315;
2316 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2317 }
2318 }
2319#endif
2320
2321 } else {
2322
2323 VCLKIndex = VCLKIndexGENCRT;
2324 if(SiS_Pr->ChipType < SIS_315H) {
2325 if(ModeNo > 0x13) {
2326 if( (SiS_Pr->ChipType == SIS_630) &&
2327 (SiS_Pr->ChipRevision >= 0x30) ) {
2328 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2329 }
2330 }
2331 }
2332 }
2333
2334 } else { /* if not programming CRT2 */
2335
2336 VCLKIndex = VCLKIndexGENCRT;
2337 if(SiS_Pr->ChipType < SIS_315H) {
2338 if(ModeNo > 0x13) {
2339 if( (SiS_Pr->ChipType != SIS_630) &&
2340 (SiS_Pr->ChipType != SIS_300) ) {
2341 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2342 }
2343#if 0
2344 if(SiS_Pr->ChipType == SIS_730) {
2345 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2346 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2347 }
2348#endif
2349 }
2350 }
2351
2352 }
2353
2354 }
2355
2356 return VCLKIndex;
2357}
2358
2359/*********************************************/
2360/* SET CRT2 MODE TYPE REGISTERS */
2361/*********************************************/
2362
2363static void
2364SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2365{
2366 unsigned short i, j, modeflag, tempah=0;
2367 short tempcl;
2368#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2369 unsigned short tempbl;
2370#endif
2371#ifdef CONFIG_FB_SIS_315
2372 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2373 unsigned short tempah2, tempbl2;
2374#endif
2375
2376 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2377
2378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2379
2380 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2381 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2382
2383 } else {
2384
2385 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2386 if(SiS_Pr->ChipType >= SIS_315H) {
2387 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2388 }
2389
2390 tempcl = SiS_Pr->SiS_ModeType;
2391
2392 if(SiS_Pr->ChipType < SIS_315H) {
2393
2394#ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2395
2396 /* For 301BDH: (with LCD via LVDS) */
2397 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2398 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2399 tempbl &= 0xef;
2400 tempbl |= 0x02;
2401 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2402 tempbl |= 0x10;
2403 tempbl &= 0xfd;
2404 }
2405 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2406 }
2407
2408 if(ModeNo > 0x13) {
2409 tempcl -= ModeVGA;
2410 if(tempcl >= 0) {
2411 tempah = ((0x10 >> tempcl) | 0x80);
2412 }
2413 } else tempah = 0x80;
2414
2415 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2416
2417#endif /* CONFIG_FB_SIS_300 */
2418
2419 } else {
2420
2421#ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2422
2423 if(ModeNo > 0x13) {
2424 tempcl -= ModeVGA;
2425 if(tempcl >= 0) {
2426 tempah = (0x08 >> tempcl);
2427 if (tempah == 0) tempah = 1;
2428 tempah |= 0x40;
2429 }
2430 } else tempah = 0x40;
2431
2432 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2433
2434#endif /* CONFIG_FB_SIS_315 */
2435
2436 }
2437
2438 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2439
2440 if(SiS_Pr->ChipType < SIS_315H) {
2441 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2442 } else {
2443#ifdef CONFIG_FB_SIS_315
2444 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2445 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2446 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2447 if(IS_SIS740) {
2448 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2449 } else {
2450 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2451 }
2452 }
2453#endif
2454 }
2455
2456 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2457
2458 tempah = 0x01;
2459 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2460 tempah |= 0x02;
2461 }
2462 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2463 tempah ^= 0x05;
2464 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2465 tempah ^= 0x01;
2466 }
2467 }
2468
2469 if(SiS_Pr->ChipType < SIS_315H) {
2470
2471 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2472
2473 tempah = (tempah << 5) & 0xFF;
2474 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2475 tempah = (tempah >> 5) & 0xFF;
2476
2477 } else {
2478
2479 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2480 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2481 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2482 tempah &= ~0x08;
2483
2484 }
2485
2486 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2487 tempah |= 0x10;
2488 }
2489
2490 tempah |= 0x80;
2491 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2492 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2493 }
2494
2495 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2496 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2497 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2498 tempah |= 0x20;
2499 }
2500 }
2501 }
2502
2503 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2504
2505 tempah = 0x80;
2506 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2507 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2508 }
2509
2510 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2511
2512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2513 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2514 tempah |= 0x40;
2515 }
2516 }
2517
2518 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2519
2520 } else { /* LVDS */
2521
2522 if(SiS_Pr->ChipType >= SIS_315H) {
2523
2524#ifdef CONFIG_FB_SIS_315
2525 /* LVDS can only be slave in 8bpp modes */
2526 tempah = 0x80;
2527 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2528 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2529 tempah |= 0x02;
2530 }
2531 }
2532
2533 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2534
2535 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2536
2537 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2538
2539 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2540#endif
2541
2542 } else {
2543
2544#ifdef CONFIG_FB_SIS_300
2545 tempah = 0;
2546 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2547 tempah |= 0x02;
2548 }
2549 tempah <<= 5;
2550
2551 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2552
2553 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2554#endif
2555
2556 }
2557
2558 }
2559
2560 } /* LCDA */
2561
2562 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2563
2564 if(SiS_Pr->ChipType >= SIS_315H) {
2565
2566#ifdef CONFIG_FB_SIS_315
2567 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2568
2569 /* The following is nearly unpreditable and varies from machine
2570 * to machine. Especially the 301DH seems to be a real trouble
2571 * maker. Some BIOSes simply set the registers (like in the
2572 * NoLCD-if-statements here), some set them according to the
2573 * LCDA stuff. It is very likely that some machines are not
2574 * treated correctly in the following, very case-orientated
2575 * code. What do I do then...?
2576 */
2577
2578 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2579
2580 if(!(IS_SIS740)) {
2581 tempah = 0x04; /* For all bridges */
2582 tempbl = 0xfb;
2583 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2584 tempah = 0x00;
2585 if(SiS_IsDualEdge(SiS_Pr)) {
2586 tempbl = 0xff;
2587 }
2588 }
2589 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2590 }
2591
2592 /* The following two are responsible for eventually wrong colors
2593 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2594 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2595 * in a 650 box (Jake). What is the criteria?
2596 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2597 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2598 * chipset than the bridge revision.
2599 */
2600
2601 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2602 tempah = 0x30;
2603 tempbl = 0xc0;
2604 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2605 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2606 tempah = 0x00;
2607 tempbl = 0x00;
2608 }
2609 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2610 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2611 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2612 /* Fixes "TV-blue-bug" on 315+301 */
2613 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2614 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2615 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2616 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2617 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2618 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2619 tempah = 0x30; tempah2 = 0xc0;
2620 tempbl = 0xcf; tempbl2 = 0x3f;
2621 if(SiS_Pr->SiS_TVBlue == 0) {
2622 tempah = tempah2 = 0x00;
2623 } else if(SiS_Pr->SiS_TVBlue == -1) {
2624 /* Set on 651/M650, clear on 315/650 */
2625 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2626 tempah = tempah2 = 0x00;
2627 }
2628 }
2629 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2630 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2631 } else {
2632 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2633 tempbl = 0xcf; tempbl2 = 0x3f;
2634 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2635 tempah = tempah2 = 0x00;
2636 if(SiS_IsDualEdge(SiS_Pr)) {
2637 tempbl = tempbl2 = 0xff;
2638 }
2639 }
2640 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2641 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2642 }
2643
2644 if(IS_SIS740) {
2645 tempah = 0x80;
2646 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2647 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2648 } else {
2649 tempah = 0x00;
2650 tempbl = 0x7f;
2651 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2652 tempbl = 0xff;
2653 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2654 }
2655 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2656 }
2657
2658#endif /* CONFIG_FB_SIS_315 */
2659
2660 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2661
2662#ifdef CONFIG_FB_SIS_300
2663 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2664
2665 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2666 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2667 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2668 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2669 } else {
2670 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2671 }
2672#endif
2673
2674 }
2675
2676 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2677 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2678 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2679 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2680 }
2681 }
2682
2683 } else { /* LVDS */
2684
2685#ifdef CONFIG_FB_SIS_315
2686 if(SiS_Pr->ChipType >= SIS_315H) {
2687
2688 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2689
2690 tempah = 0x04;
2691 tempbl = 0xfb;
2692 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2693 tempah = 0x00;
2694 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2695 }
2696 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2697
2698 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2699 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2700 }
2701
2702 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2703
2704 } else if(SiS_Pr->ChipType == SIS_550) {
2705
2706 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2707 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2708
2709 }
2710
2711 }
2712#endif
2713
2714 }
2715
2716}
2717
2718/*********************************************/
2719/* GET RESOLUTION DATA */
2720/*********************************************/
2721
2722unsigned short
2723SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2724{
2725 if(ModeNo <= 0x13)
2726 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2727 else
2728 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2729}
2730
2731static void
2732SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2733{
2734 unsigned short xres, yres, modeflag=0, resindex;
2735
2736 if(SiS_Pr->UseCustomMode) {
2737 xres = SiS_Pr->CHDisplay;
2738 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2739 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2740 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2741 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2742 return;
2743 }
2744
2745 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2746
2747 if(ModeNo <= 0x13) {
2748 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2749 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2750 } else {
2751 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2752 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2753 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2754 }
2755
2756 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2757
2758 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2759 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2760 if(yres == 350) yres = 400;
2761 }
2762 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2763 if(ModeNo == 0x12) yres = 400;
2764 }
2765 }
2766
2767 if(modeflag & HalfDCLK) xres <<= 1;
2768 if(modeflag & DoubleScanMode) yres <<= 1;
2769
2770 }
2771
2772 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2773
2774 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2775 switch(SiS_Pr->SiS_LCDResInfo) {
2776 case Panel_1024x768:
2777 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2778 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2779 if(yres == 350) yres = 357;
2780 if(yres == 400) yres = 420;
2781 if(yres == 480) yres = 525;
2782 }
2783 }
2784 break;
2785 case Panel_1280x1024:
2786 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2787 /* BIOS bug - does this regardless of scaling */
2788 if(yres == 400) yres = 405;
2789 }
2790 if(yres == 350) yres = 360;
2791 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2792 if(yres == 360) yres = 375;
2793 }
2794 break;
2795 case Panel_1600x1200:
2796 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2797 if(yres == 1024) yres = 1056;
2798 }
2799 break;
2800 }
2801 }
2802
2803 } else {
2804
2805 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2806 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2807 if(xres == 720) xres = 640;
2808 }
2809 } else if(xres == 720) xres = 640;
2810
2811 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2812 yres = 400;
2813 if(SiS_Pr->ChipType >= SIS_315H) {
2814 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2815 } else {
2816 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2817 }
2818 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2819 }
2820
2821 }
2822 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2823 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2824}
2825
2826/*********************************************/
2827/* GET CRT2 TIMING DATA */
2828/*********************************************/
2829
2830static void
2831SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2832 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2833 unsigned short *ResIndex)
2834{
2835 unsigned short tempbx=0, tempal=0, resinfo=0;
2836
2837 if(ModeNo <= 0x13) {
2838 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2839 } else {
2840 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2841 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2842 }
2843
2844 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2845
2846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2847
2848 tempbx = SiS_Pr->SiS_LCDResInfo;
2849 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2850
2851 /* patch index */
2852 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2853 if (resinfo == SIS_RI_1280x800) tempal = 9;
2854 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2855 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2856 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2857 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2858 if (resinfo == SIS_RI_1280x768) tempal = 9;
2859 }
2860
2861 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2862 /* Pass 1:1 only (center-screen handled outside) */
2863 /* This is never called for the panel's native resolution */
2864 /* since Pass1:1 will not be set in this case */
2865 tempbx = 100;
2866 if(ModeNo >= 0x13) {
2867 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2868 }
2869 }
2870
2871#ifdef CONFIG_FB_SIS_315
2872 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2873 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2874 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2875 tempbx = 200;
2876 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2877 }
2878 }
2879 }
2880#endif
2881
2882 } else { /* TV */
2883
2884 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2885 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2886 tempbx = 2;
2887 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2888 tempbx = 13;
2889 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2890 }
2891 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2892 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2893 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2894 else tempbx = 5;
2895 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2896 } else {
2897 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2898 else tempbx = 4;
2899 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2900 }
2901
2902 }
2903
2904 tempal &= 0x3F;
2905
2906 if(ModeNo > 0x13) {
2907 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2908 switch(resinfo) {
2909 case SIS_RI_720x480:
2910 tempal = 6;
2911 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2912 break;
2913 case SIS_RI_720x576:
2914 case SIS_RI_768x576:
2915 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2916 tempal = 6;
2917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2918 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2919 }
2920 break;
2921 case SIS_RI_800x480:
2922 tempal = 4;
2923 break;
2924 case SIS_RI_512x384:
2925 case SIS_RI_1024x768:
2926 tempal = 7;
2927 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2928 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2929 }
2930 break;
2931 case SIS_RI_1280x720:
2932 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2933 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2934 }
2935 break;
2936 }
2937 }
2938 }
2939
2940 *CRT2Index = tempbx;
2941 *ResIndex = tempal;
2942
2943 } else { /* LVDS, 301B-DH (if running on LCD) */
2944
2945 tempbx = 0;
2946 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2947
2948 tempbx = 90;
2949 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2950 tempbx = 92;
2951 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2952 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2953 }
2954 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
2955 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2956 }
2957 if(tempbx != 99) {
2958 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2959 }
2960
2961 } else {
2962
2963 switch(SiS_Pr->SiS_LCDResInfo) {
2964 case Panel_640x480: tempbx = 12; break;
2965 case Panel_320x240_1: tempbx = 10; break;
2966 case Panel_320x240_2:
2967 case Panel_320x240_3: tempbx = 14; break;
2968 case Panel_800x600: tempbx = 16; break;
2969 case Panel_1024x600: tempbx = 18; break;
2970 case Panel_1152x768:
2971 case Panel_1024x768: tempbx = 20; break;
2972 case Panel_1280x768: tempbx = 22; break;
2973 case Panel_1280x1024: tempbx = 24; break;
2974 case Panel_1400x1050: tempbx = 26; break;
2975 case Panel_1600x1200: tempbx = 28; break;
2976#ifdef CONFIG_FB_SIS_300
2977 case Panel_Barco1366: tempbx = 80; break;
2978#endif
2979 }
2980
2981 switch(SiS_Pr->SiS_LCDResInfo) {
2982 case Panel_320x240_1:
2983 case Panel_320x240_2:
2984 case Panel_320x240_3:
2985 case Panel_640x480:
2986 break;
2987 default:
2988 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2989 }
2990
2991 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
2992
2993#ifdef CONFIG_FB_SIS_300
2994 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2995 tempbx = 82;
2996 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2997 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2998 tempbx = 84;
2999 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3000 }
3001#endif
3002
3003 }
3004
3005 (*CRT2Index) = tempbx;
3006 (*ResIndex) = tempal & 0x1F;
3007 }
3008}
3009
3010static void
3011SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3012 unsigned short RefreshRateTableIndex)
3013{
3014 unsigned short tempax=0, tempbx=0, index, dotclock;
3015 unsigned short temp1=0, modeflag=0, tempcx=0;
3016
3017 SiS_Pr->SiS_RVBHCMAX = 1;
3018 SiS_Pr->SiS_RVBHCFACT = 1;
3019
3020 if(ModeNo <= 0x13) {
3021
3022 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3023 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3024
3025 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3026 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3027 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3028
3029 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3030
3031 } else {
3032
3033 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3034 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3035
3036 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3037 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3038 tempax &= 0x03FF;
3039 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3040 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3041 tempcx &= 0x0100;
3042 tempcx <<= 2;
3043 tempbx |= tempcx;
3044 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3045
3046 dotclock = 8;
3047
3048 }
3049
3050 if(temp1 & 0x01) tempbx |= 0x0100;
3051 if(temp1 & 0x20) tempbx |= 0x0200;
3052
3053 tempax += 5;
3054 tempax *= dotclock;
3055 if(modeflag & HalfDCLK) tempax <<= 1;
3056
3057 tempbx++;
3058
3059 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3060 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3061}
3062
3063static void
3064SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3065 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3066{
3067 unsigned short ResIndex;
3068
3069 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3070 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3071 if(SiS_Pr->UseCustomMode) {
3072 ResIndex = SiS_Pr->CHTotal;
3073 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3074 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3075 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3076 } else {
3077 if(ModeNo < 0x13) {
3078 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3079 } else {
3080 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3081 }
3082 if(ResIndex == 0x09) {
3083 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3084 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3085 }
3086 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3087 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3088 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3089 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3090 }
3091 } else {
3092 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3093 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3094 }
3095 } else {
3096 /* This handles custom modes and custom panels */
3097 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3098 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3099 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3100 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3101 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3102 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3103 }
3104}
3105
3106static void
3107SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3108 unsigned short RefreshRateTableIndex)
3109{
3110 unsigned short CRT2Index, ResIndex, backup;
3111 const struct SiS_LVDSData *LVDSData = NULL;
3112
3113 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3114
3115 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3116 SiS_Pr->SiS_RVBHCMAX = 1;
3117 SiS_Pr->SiS_RVBHCFACT = 1;
3118 SiS_Pr->SiS_NewFlickerMode = 0;
3119 SiS_Pr->SiS_RVBHRS = 50;
3120 SiS_Pr->SiS_RY1COE = 0;
3121 SiS_Pr->SiS_RY2COE = 0;
3122 SiS_Pr->SiS_RY3COE = 0;
3123 SiS_Pr->SiS_RY4COE = 0;
3124 SiS_Pr->SiS_RVBHRS2 = 0;
3125 }
3126
3127 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3128
3129#ifdef CONFIG_FB_SIS_315
3130 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3131 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3132#endif
3133
3134 } else {
3135
3136 /* 301BDH needs LVDS Data */
3137 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3138 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3139 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3140 }
3141
3142 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3143 &CRT2Index, &ResIndex);
3144
3145 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3146
3147 switch(CRT2Index) {
3148 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3149 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3150 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3151 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3152 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3153 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3154#ifdef CONFIG_FB_SIS_300
3155 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3156 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3157 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3158 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3159 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3160#endif
3161 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3162 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3163 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3164 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3165 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3166 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3167 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3168 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3169 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3170 }
3171
3172 if(LVDSData) {
3173 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3174 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3175 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3176 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3177 } else {
3178 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3179 }
3180
3181 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3182 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3183 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3184 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3185 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3186 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3187 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3188#ifdef CONFIG_FB_SIS_300
3189 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3190 if(ResIndex < 0x08) {
3191 SiS_Pr->SiS_HDE = 1280;
3192 SiS_Pr->SiS_VDE = 1024;
3193 }
3194 }
3195#endif
3196 }
3197 }
3198 }
3199}
3200
3201static void
3202SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3203 unsigned short RefreshRateTableIndex)
3204{
3205 unsigned char *ROMAddr = NULL;
3206 unsigned short tempax, tempbx, modeflag, romptr=0;
3207 unsigned short resinfo, CRT2Index, ResIndex;
3208 const struct SiS_LCDData *LCDPtr = NULL;
3209 const struct SiS_TVData *TVPtr = NULL;
3210#ifdef CONFIG_FB_SIS_315
3211 short resinfo661;
3212#endif
3213
3214 if(ModeNo <= 0x13) {
3215 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3216 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3217 } else if(SiS_Pr->UseCustomMode) {
3218 modeflag = SiS_Pr->CModeFlag;
3219 resinfo = 0;
3220 } else {
3221 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3222 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3223#ifdef CONFIG_FB_SIS_315
3224 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3225 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3226 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3227 (resinfo661 >= 0) &&
3228 (SiS_Pr->SiS_NeedRomModeData) ) {
3229 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3230 if((romptr = (SISGETROMW(21)))) {
3231 romptr += (resinfo661 * 10);
3232 ROMAddr = SiS_Pr->VirtualRomBase;
3233 }
3234 }
3235 }
3236#endif
3237 }
3238
3239 SiS_Pr->SiS_NewFlickerMode = 0;
3240 SiS_Pr->SiS_RVBHRS = 50;
3241 SiS_Pr->SiS_RY1COE = 0;
3242 SiS_Pr->SiS_RY2COE = 0;
3243 SiS_Pr->SiS_RY3COE = 0;
3244 SiS_Pr->SiS_RY4COE = 0;
3245 SiS_Pr->SiS_RVBHRS2 = 0;
3246
3247 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3248
3249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3250
3251 if(SiS_Pr->UseCustomMode) {
3252
3253 SiS_Pr->SiS_RVBHCMAX = 1;
3254 SiS_Pr->SiS_RVBHCFACT = 1;
3255 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3256 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3257
3258 tempax = SiS_Pr->CHTotal;
3259 if(modeflag & HalfDCLK) tempax <<= 1;
3260 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3261 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3262
3263 } else {
3264
3265 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3266
3267 }
3268
3269 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3270
3271 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3272 &CRT2Index,&ResIndex);
3273
3274 switch(CRT2Index) {
3275 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3276 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3277 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3278 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3279 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3280 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3281 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3282 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3283 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3284 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3285 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3286 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3287 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3288 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3289 }
3290
3291 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3292 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3293 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3294 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3295 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3296 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3297 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3298 if(modeflag & HalfDCLK) {
3299 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3300 if(SiS_Pr->SiS_RVBHRS2) {
3301 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3302 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3303 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3304 else SiS_Pr->SiS_RVBHRS2 += tempax;
3305 }
3306 } else {
3307 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3308 }
3309 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3310
3311 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3312
3313 if((resinfo == SIS_RI_960x600) ||
3314 (resinfo == SIS_RI_1024x768) ||
3315 (resinfo == SIS_RI_1280x1024) ||
3316 (resinfo == SIS_RI_1280x720)) {
3317 SiS_Pr->SiS_NewFlickerMode = 0x40;
3318 }
3319
3320 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3321
3322 SiS_Pr->SiS_HT = ExtHiTVHT;
3323 SiS_Pr->SiS_VT = ExtHiTVVT;
3324 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3325 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3326 SiS_Pr->SiS_HT = StHiTVHT;
3327 SiS_Pr->SiS_VT = StHiTVVT;
3328 }
3329 }
3330
3331 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3332
3333 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3334 SiS_Pr->SiS_HT = 1650;
3335 SiS_Pr->SiS_VT = 750;
3336 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3337 SiS_Pr->SiS_HT = NTSCHT;
3338 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3339 SiS_Pr->SiS_VT = NTSCVT;
3340 } else {
3341 SiS_Pr->SiS_HT = NTSCHT;
3342 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3343 SiS_Pr->SiS_VT = NTSCVT;
3344 }
3345
3346 } else {
3347
3348 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3349 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3350 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3351 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3352
3353 if(modeflag & HalfDCLK) {
3354 SiS_Pr->SiS_RY1COE = 0x00;
3355 SiS_Pr->SiS_RY2COE = 0xf4;
3356 SiS_Pr->SiS_RY3COE = 0x10;
3357 SiS_Pr->SiS_RY4COE = 0x38;
3358 }
3359
3360 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3361 SiS_Pr->SiS_HT = NTSCHT;
3362 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3363 SiS_Pr->SiS_VT = NTSCVT;
3364 } else {
3365 SiS_Pr->SiS_HT = PALHT;
3366 SiS_Pr->SiS_VT = PALVT;
3367 }
3368
3369 }
3370
3371 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3372
3373 SiS_Pr->SiS_RVBHCMAX = 1;
3374 SiS_Pr->SiS_RVBHCFACT = 1;
3375
3376 if(SiS_Pr->UseCustomMode) {
3377
3378 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3379 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3380
3381 tempax = SiS_Pr->CHTotal;
3382 if(modeflag & HalfDCLK) tempax <<= 1;
3383 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3384 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3385
3386 } else {
3387
3388 bool gotit = false;
3389
3390 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3391
3392 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3393 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3394 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3395 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3396 gotit = true;
3397
3398 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3399
3400#ifdef CONFIG_FB_SIS_315
3401 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3402 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3403 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3404 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3405 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3406 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3407 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3408 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3409 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3410 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3411 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3412 else SiS_Pr->SiS_RVBHRS2 += tempax;
3413 }
3414 if(SiS_Pr->SiS_VGAHT) gotit = true;
3415 else {
3416 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3417 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3418 SiS_Pr->SiS_RVBHCMAX = 1;
3419 SiS_Pr->SiS_RVBHCFACT = 1;
3420 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3421 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3422 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3423 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3424 SiS_Pr->SiS_RVBHRS2 = 0;
3425 gotit = true;
3426 }
3427#endif
3428
3429 }
3430
3431 if(!gotit) {
3432
3433 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3434 &CRT2Index,&ResIndex);
3435
3436 switch(CRT2Index) {
3437 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3438 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3439 case Panel_1280x720 :
3440 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3441 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3442 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3443 case Panel_1280x800 :
3444 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3445 case Panel_1280x800_2 :
3446 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3447 case Panel_1280x854 :
3448 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3449 case Panel_1280x960 :
3450 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3451 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3452 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3453 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3454 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3455 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3456 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3457 case Panel_1680x1050 :
3458 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3459 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3460#ifdef CONFIG_FB_SIS_315
3461 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3462 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3463#endif
3464 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3465 }
3466
3467 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3468 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3469 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3470 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3471 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3472 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3473
3474 }
3475
3476 tempax = SiS_Pr->PanelXRes;
3477 tempbx = SiS_Pr->PanelYRes;
3478
3479 switch(SiS_Pr->SiS_LCDResInfo) {
3480 case Panel_1024x768:
3481 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3482 if(SiS_Pr->ChipType < SIS_315H) {
3483 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3484 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3485 }
3486 } else {
3487 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3488 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3489 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3490 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3491 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3492 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3493 }
3494 break;
3495 case Panel_1280x960:
3496 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3497 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3498 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3499 break;
3500 case Panel_1280x1024:
3501 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3502 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3503 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3504 break;
3505 case Panel_1600x1200:
3506 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3507 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3508 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3509 }
3510 break;
3511 }
3512
3513 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3514 tempax = SiS_Pr->SiS_VGAHDE;
3515 tempbx = SiS_Pr->SiS_VGAVDE;
3516 }
3517
3518 SiS_Pr->SiS_HDE = tempax;
3519 SiS_Pr->SiS_VDE = tempbx;
3520 }
3521 }
3522}
3523
3524static void
3525SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3526 unsigned short RefreshRateTableIndex)
3527{
3528
3529 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3530
3531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3532 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3533 } else {
3534 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3535 /* Need LVDS Data for LCD on 301B-DH */
3536 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3537 } else {
3538 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3539 }
3540 }
3541
3542 } else {
3543
3544 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3545
3546 }
3547}
3548
3549/*********************************************/
3550/* GET LVDS DES (SKEW) DATA */
3551/*********************************************/
3552
3553static const struct SiS_LVDSDes *
3554SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3555{
3556 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3557
3558#ifdef CONFIG_FB_SIS_300
3559 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3560
3561 if(SiS_Pr->ChipType < SIS_315H) {
3562 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3563 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3564 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3565 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3566 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3567 }
3568 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3569 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3570 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3571 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3572 }
3573 }
3574 }
3575 }
3576 }
3577#endif
3578 return PanelDesPtr;
3579}
3580
3581static void
3582SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3583 unsigned short RefreshRateTableIndex)
3584{
3585 unsigned short modeflag, ResIndex;
3586 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3587
3588 SiS_Pr->SiS_LCDHDES = 0;
3589 SiS_Pr->SiS_LCDVDES = 0;
3590
3591 /* Some special cases */
3592 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3593
3594 /* Trumpion */
3595 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3596 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3597 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3598 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3599 }
3600 }
3601 return;
3602 }
3603
3604 /* 640x480 on LVDS */
3605 if(SiS_Pr->ChipType < SIS_315H) {
3606 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3607 SiS_Pr->SiS_LCDHDES = 8;
3608 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3609 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3610 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3611 return;
3612 }
3613 }
3614
3615 } /* LCD */
3616
3617 if( (SiS_Pr->UseCustomMode) ||
3618 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3619 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3620 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3621 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3622 return;
3623 }
3624
3625 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3626 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3627
3628 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3629
3630#ifdef CONFIG_FB_SIS_315
3631 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3632 /* non-pass 1:1 only, see above */
3633 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3634 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3635 }
3636 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3637 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3638 }
3639 }
3640 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3641 switch(SiS_Pr->SiS_CustomT) {
3642 case CUT_UNIWILL1024:
3643 case CUT_UNIWILL10242:
3644 case CUT_CLEVO1400:
3645 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3646 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3647 }
3648 break;
3649 }
3650 switch(SiS_Pr->SiS_LCDResInfo) {
3651 case Panel_1280x1024:
3652 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3653 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3654 }
3655 break;
3656 case Panel_1280x800: /* Verified for Averatec 6240 */
3657 case Panel_1280x800_2: /* Verified for Asus A4L */
3658 case Panel_1280x854: /* Not verified yet FIXME */
3659 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3660 break;
3661 }
3662 }
3663#endif
3664
3665 } else {
3666
3667 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3668
3669 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3670 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3671 }
3672
3673 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3674
3675 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3676 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3677
3678 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3679
3680 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3681 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3682 }
3683 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3684 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3685 } else {
3686 if(SiS_Pr->ChipType < SIS_315H) {
3687 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3688 } else {
3689 switch(SiS_Pr->SiS_LCDResInfo) {
3690 case Panel_800x600:
3691 case Panel_1024x768:
3692 case Panel_1280x1024:
3693 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3694 break;
3695 case Panel_1400x1050:
3696 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3697 break;
3698 }
3699 }
3700 }
3701
3702 } else {
3703
3704 if(SiS_Pr->ChipType < SIS_315H) {
3705#ifdef CONFIG_FB_SIS_300
3706 switch(SiS_Pr->SiS_LCDResInfo) {
3707 case Panel_800x600:
3708 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3709 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3710 } else {
3711 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3712 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3713 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3714 else SiS_Pr->SiS_LCDVDES -= 4;
3715 }
3716 break;
3717 case Panel_1024x768:
3718 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3719 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3720 } else {
3721 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3722 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3723 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3724 }
3725 break;
3726 case Panel_1024x600:
3727 default:
3728 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3729 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3730 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3731 } else {
3732 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3733 }
3734 break;
3735 }
3736
3737 switch(SiS_Pr->SiS_LCDTypeInfo) {
3738 case 1:
3739 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3740 break;
3741 case 3: /* 640x480 only? */
3742 SiS_Pr->SiS_LCDHDES = 8;
3743 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3744 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3745 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3746 break;
3747 }
3748#endif
3749 } else {
3750#ifdef CONFIG_FB_SIS_315
3751 switch(SiS_Pr->SiS_LCDResInfo) {
3752 case Panel_1024x768:
3753 case Panel_1280x1024:
3754 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3755 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3756 }
3757 break;
3758 case Panel_320x240_1:
3759 case Panel_320x240_2:
3760 case Panel_320x240_3:
3761 SiS_Pr->SiS_LCDVDES = 524;
3762 break;
3763 }
3764#endif
3765 }
3766 }
3767
3768 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3769 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3770 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3771 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3772 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3773 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3774 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3775 if(SiS_Pr->ChipType < SIS_315H) {
3776 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3777 } else {
3778#ifdef CONFIG_FB_SIS_315
3779 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3780 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3781 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3782 if(!(modeflag & HalfDCLK)) {
3783 SiS_Pr->SiS_LCDHDES = 320;
3784 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3785 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3786 }
3787#endif
3788 }
3789 }
3790 }
3791 }
3792 }
3793 }
3794}
3795
3796/*********************************************/
3797/* DISABLE VIDEO BRIDGE */
3798/*********************************************/
3799
3800#ifdef CONFIG_FB_SIS_315
3801static int
3802SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3803{
3804 int ret = 0;
3805#ifdef SET_PWD
3806 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3807 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3808 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3809 unsigned short temp;
3810
3811 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3812 (romptr) &&
3813 (SiS_Pr->SiS_PWDOffset) ) {
3814 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3815 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3816 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3817 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3818 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3819 temp = 0x00;
3820 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3821 temp = 0x80;
3822 ret = 1;
3823 }
3824 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3825 }
3826#endif
3827 return ret;
3828}
3829#endif
3830
3831/* NEVER use any variables (VBInfo), this will be called
3832 * from outside the context of modeswitch!
3833 * MUST call getVBType before calling this
3834 */
3835void
3836SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3837{
3838#ifdef CONFIG_FB_SIS_315
3839 unsigned short tempah, pushax=0, modenum;
3840#endif
3841 unsigned short temp=0;
3842
3843 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3844
3845 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3846
3847 if(SiS_Pr->ChipType < SIS_315H) {
3848
3849#ifdef CONFIG_FB_SIS_300 /* 300 series */
3850
3851 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3852 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3853 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3854 } else {
3855 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3856 }
3857 SiS_PanelDelay(SiS_Pr, 3);
3858 }
3859 if(SiS_Is301B(SiS_Pr)) {
3860 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3861 SiS_ShortDelay(SiS_Pr,1);
3862 }
3863 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3864 SiS_DisplayOff(SiS_Pr);
3865 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3866 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3867 SiS_UnLockCRT2(SiS_Pr);
3868 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3869 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3870 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3871 }
3872 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3873 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3874 SiS_PanelDelay(SiS_Pr, 2);
3875 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3876 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3877 } else {
3878 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3879 }
3880 }
3881
3882#endif /* CONFIG_FB_SIS_300 */
3883
3884 } else {
3885
3886#ifdef CONFIG_FB_SIS_315 /* 315 series */
3887
3888 int didpwd = 0;
3889 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3890 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3891
3892 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3893
3894 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3895
3896#ifdef SET_EMI
3897 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3898 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3899 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3900 }
3901 }
3902#endif
3903
3904 didpwd = SiS_HandlePWD(SiS_Pr);
3905
3906 if( (modenum <= 0x13) ||
3907 (SiS_IsVAMode(SiS_Pr)) ||
3908 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3909 if(!didpwd) {
3910 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3911 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3912 } else {
3913 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3914 }
3915 }
3916
3917 if(!custom1) {
3918 SiS_DDC2Delay(SiS_Pr,0xff00);
3919 SiS_DDC2Delay(SiS_Pr,0xe000);
3920 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3921 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3922 if(IS_SIS740) {
3923 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3924 }
3925 SiS_PanelDelay(SiS_Pr, 3);
3926 }
3927
3928 }
3929
3930 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3931 /* if(SiS_Pr->ChipType < SIS_340) {*/
3932 tempah = 0xef;
3933 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3934 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3935 /*}*/
3936 }
3937
3938 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3939 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3940 }
3941
3942 tempah = 0x3f;
3943 if(SiS_IsDualEdge(SiS_Pr)) {
3944 tempah = 0x7f;
3945 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3946 }
3947 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3948
3949 if((SiS_IsVAMode(SiS_Pr)) ||
3950 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3951
3952 SiS_DisplayOff(SiS_Pr);
3953 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3954 SiS_PanelDelay(SiS_Pr, 2);
3955 }
3956 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3957 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3958
3959 }
3960
3961 if((!(SiS_IsVAMode(SiS_Pr))) ||
3962 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3963
3964 if(!(SiS_IsDualEdge(SiS_Pr))) {
3965 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3966 SiS_DisplayOff(SiS_Pr);
3967 }
3968 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3969
3970 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3971 SiS_PanelDelay(SiS_Pr, 2);
3972 }
3973
3974 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3975 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3976 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3977 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3978 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3979
3980 }
3981
3982 if(SiS_IsNotM650orLater(SiS_Pr)) {
3983 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3984 }
3985
3986 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3987
3988 if( (!(SiS_IsVAMode(SiS_Pr))) &&
3989 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
3990 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3991
3992 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3993 if(!didpwd) {
3994 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3995 }
3996 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
3997 }
3998
3999 if(!custom1) {
4000 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4001 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4002 if(SiS_IsVAorLCD(SiS_Pr)) {
4003 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4004 }
4005 }
4006 }
4007
4008 }
4009
4010#endif /* CONFIG_FB_SIS_315 */
4011
4012 }
4013
4014 } else { /* ============ For 301 ================ */
4015
4016 if(SiS_Pr->ChipType < SIS_315H) {
4017#ifdef CONFIG_FB_SIS_300
4018 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4019 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4020 SiS_PanelDelay(SiS_Pr, 3);
4021 }
4022#endif
4023 }
4024
4025 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4026 SiS_DisplayOff(SiS_Pr);
4027
4028 if(SiS_Pr->ChipType >= SIS_315H) {
4029 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4030 }
4031
4032 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4033
4034 if(SiS_Pr->ChipType >= SIS_315H) {
4035 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4036 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4037 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4038 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4039 } else {
4040#ifdef CONFIG_FB_SIS_300
4041 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4042 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4043 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4044 SiS_PanelDelay(SiS_Pr, 2);
4045 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4046 }
4047#endif
4048 }
4049
4050 }
4051
4052 } else { /* ============ For LVDS =============*/
4053
4054 if(SiS_Pr->ChipType < SIS_315H) {
4055
4056#ifdef CONFIG_FB_SIS_300 /* 300 series */
4057
4058 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4059 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4060 }
4061
4062 if(SiS_Pr->ChipType == SIS_730) {
4063 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4064 SiS_WaitVBRetrace(SiS_Pr);
4065 }
4066 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4067 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4068 SiS_PanelDelay(SiS_Pr, 3);
4069 }
4070 } else {
4071 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4072 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4073 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4074 SiS_WaitVBRetrace(SiS_Pr);
4075 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4076 SiS_DisplayOff(SiS_Pr);
4077 }
4078 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4079 SiS_PanelDelay(SiS_Pr, 3);
4080 }
4081 }
4082 }
4083 }
4084
4085 SiS_DisplayOff(SiS_Pr);
4086
4087 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4088
4089 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4090 SiS_UnLockCRT2(SiS_Pr);
4091 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4092 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4093
4094 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4095 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4096 SiS_PanelDelay(SiS_Pr, 2);
4097 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4098 }
4099
4100#endif /* CONFIG_FB_SIS_300 */
4101
4102 } else {
4103
4104#ifdef CONFIG_FB_SIS_315 /* 315 series */
4105
4106 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4107 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4108 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4109 /* } */
4110 }
4111
4112 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4113
4114 if(SiS_Pr->ChipType == SIS_740) {
4115 temp = SiS_GetCH701x(SiS_Pr,0x61);
4116 if(temp < 1) {
4117 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4118 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4119 }
4120
4121 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4122 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4123 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4124 }
4125 }
4126
4127 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4128 (SiS_IsVAMode(SiS_Pr)) ) {
4129 SiS_Chrontel701xBLOff(SiS_Pr);
4130 SiS_Chrontel701xOff(SiS_Pr);
4131 }
4132
4133 if(SiS_Pr->ChipType != SIS_740) {
4134 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4135 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4136 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4137 }
4138 }
4139
4140 }
4141
4142 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4143 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4144 SiS_PanelDelay(SiS_Pr, 3);
4145 }
4146
4147 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4148 (!(SiS_IsDualEdge(SiS_Pr))) ||
4149 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4150 SiS_DisplayOff(SiS_Pr);
4151 }
4152
4153 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4154 (!(SiS_IsDualEdge(SiS_Pr))) ||
4155 (!(SiS_IsVAMode(SiS_Pr))) ) {
4156 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4157 }
4158
4159 if(SiS_Pr->ChipType == SIS_740) {
4160 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4161 }
4162
4163 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4164
4165 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4166 (!(SiS_IsDualEdge(SiS_Pr))) ||
4167 (!(SiS_IsVAMode(SiS_Pr))) ) {
4168 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4169 }
4170
4171 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4172 if(SiS_CRT2IsLCD(SiS_Pr)) {
4173 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4174 if(SiS_Pr->ChipType == SIS_550) {
4175 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4176 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4177 }
4178 }
4179 } else {
4180 if(SiS_Pr->ChipType == SIS_740) {
4181 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4183 }
4184 } else if(SiS_IsVAMode(SiS_Pr)) {
4185 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4186 }
4187 }
4188
4189 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4190 if(SiS_IsDualEdge(SiS_Pr)) {
4191 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4192 } else {
4193 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4194 }
4195 }
4196
4197 SiS_UnLockCRT2(SiS_Pr);
4198
4199 if(SiS_Pr->ChipType == SIS_550) {
4200 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4201 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4202 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4203 (!(SiS_IsDualEdge(SiS_Pr))) ||
4204 (!(SiS_IsVAMode(SiS_Pr))) ) {
4205 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4206 }
4207
4208 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4209 if(SiS_CRT2IsLCD(SiS_Pr)) {
4210 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4211 SiS_PanelDelay(SiS_Pr, 2);
4212 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4213 }
4214 }
4215 }
4216
4217#endif /* CONFIG_FB_SIS_315 */
4218
4219 } /* 315 series */
4220
4221 } /* LVDS */
4222
4223}
4224
4225/*********************************************/
4226/* ENABLE VIDEO BRIDGE */
4227/*********************************************/
4228
4229/* NEVER use any variables (VBInfo), this will be called
4230 * from outside the context of a mode switch!
4231 * MUST call getVBType before calling this
4232 */
4233static
4234void
4235SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4236{
4237 unsigned short temp=0, tempah;
4238#ifdef CONFIG_FB_SIS_315
4239 unsigned short temp1, pushax=0;
4240 bool delaylong = false;
4241#endif
4242
4243 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4244
4245 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4246
4247 if(SiS_Pr->ChipType < SIS_315H) {
4248
4249#ifdef CONFIG_FB_SIS_300 /* 300 series */
4250
4251 if(SiS_CRT2IsLCD(SiS_Pr)) {
4252 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4253 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4254 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4255 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4256 }
4257 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4258 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4259 SiS_PanelDelay(SiS_Pr, 0);
4260 }
4261 }
4262 }
4263
4264 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4265 (SiS_CRT2IsLCD(SiS_Pr))) {
4266
4267 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4268 SiS_DisplayOn(SiS_Pr);
4269 SiS_UnLockCRT2(SiS_Pr);
4270 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4271 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4272 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4273 } else {
4274 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4275 }
4276 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4277 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4278 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4279 SiS_PanelDelay(SiS_Pr, 1);
4280 }
4281 SiS_WaitVBRetrace(SiS_Pr);
4282 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4283 }
4284 }
4285
4286 } else {
4287
4288 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4289 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4290 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4291 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4292 }
4293 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4294 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4295 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4296 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4297 SiS_DisplayOn(SiS_Pr);
4298 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4299 if(SiS_CRT2IsLCD(SiS_Pr)) {
4300 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4301 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4302 SiS_PanelDelay(SiS_Pr, 1);
4303 }
4304 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4305 }
4306 }
4307 }
4308
4309 }
4310
4311
4312#endif /* CONFIG_FB_SIS_300 */
4313
4314 } else {
4315
4316#ifdef CONFIG_FB_SIS_315 /* 315 series */
4317
4318#ifdef SET_EMI
4319 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4320 int didpwd = 0;
4321 /* unsigned short emidelay=0; */
4322#endif
4323
4324 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4325 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4326#ifdef SET_EMI
4327 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4328 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4329 }
4330#endif
4331 }
4332
4333 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4334 /*if(SiS_Pr->ChipType < SIS_340) { */
4335 tempah = 0x10;
4336 if(SiS_LCDAEnabled(SiS_Pr)) {
4337 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4338 else tempah = 0x08;
4339 }
4340 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4341 /*}*/
4342 }
4343
4344 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4345
4346 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4347 SiS_DisplayOff(SiS_Pr);
4348 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4349 if(IS_SIS740) {
4350 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4351 }
4352
4353 didpwd = SiS_HandlePWD(SiS_Pr);
4354
4355 if(SiS_IsVAorLCD(SiS_Pr)) {
4356 if(!didpwd) {
4357 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4358 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4359 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4360 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4361 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4362 SiS_GenericDelay(SiS_Pr, 17664);
4363 }
4364 }
4365 } else {
4366 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4367 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4368 SiS_GenericDelay(SiS_Pr, 17664);
4369 }
4370 }
4371 }
4372
4373 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4374 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4375 delaylong = true;
4376 }
4377
4378 }
4379
4380 if(!(SiS_IsVAMode(SiS_Pr))) {
4381
4382 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4383 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4384 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4385 if(!(tempah & SetCRT2ToRAMDAC)) {
4386 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4387 }
4388 }
4389 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4390
4391 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4392
4393 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4394 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4395
4396 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4397 SiS_PanelDelay(SiS_Pr, 2);
4398 }
4399
4400 } else {
4401
4402 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4403
4404 }
4405
4406 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4407 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4408
4409 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4410 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4411 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4412 /* Enable "LVDS PLL power on" (even on 301C) */
4413 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4414 /* Enable "LVDS Driver Power on" (even on 301C) */
4415 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4416 }
4417 }
4418
4419 tempah = 0xc0;
4420 if(SiS_IsDualEdge(SiS_Pr)) {
4421 tempah = 0x80;
4422 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4423 }
4424 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4425
4426 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4427
4428 SiS_PanelDelay(SiS_Pr, 2);
4429
4430 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4431 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4432
4433 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4434#ifdef SET_EMI
4435 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4436 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4437 SiS_GenericDelay(SiS_Pr, 2048);
4438 }
4439#endif
4440 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4441
4442 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4443#ifdef SET_EMI
4444 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4445
4446 if(SiS_Pr->SiS_ROMNew) {
4447 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4448 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4449 if(romptr) {
4450 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4451 SiS_Pr->EMI_30 = 0;
4452 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4453 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4454 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4455 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4456 /* emidelay = SISGETROMW((romptr + 0x22)); */
4457 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4458 }
4459 }
4460
4461 /* (P4_30|0x40) */
4462 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4463 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4464 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4465 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4466 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4467 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4468 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4469 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4470 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4471
4472 if(SiS_Pr->HaveEMI) {
4473 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4474 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4475 } else {
4476 r30 = 0;
4477 }
4478
4479 /* EMI_30 is read at driver start; however, the BIOS sets this
4480 * (if it is used) only if the LCD is in use. In case we caught
4481 * the machine while on TV output, this bit is not set and we
4482 * don't know if it should be set - hence our detection is wrong.
4483 * Work-around this here:
4484 */
4485
4486 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4487 switch((cr36 & 0x0f)) {
4488 case 2:
4489 r30 |= 0x40;
4490 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4491 if(!SiS_Pr->HaveEMI) {
4492 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4493 if((cr36 & 0xf0) == 0x30) {
4494 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4495 }
4496 }
4497 break;
4498 case 3: /* 1280x1024 */
4499 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4500 if(!SiS_Pr->HaveEMI) {
4501 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4502 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4503 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4504 }
4505 }
4506 break;
4507 case 9: /* 1400x1050 */
4508 r30 |= 0x40;
4509 if(!SiS_Pr->HaveEMI) {
4510 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4511 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4512 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4513 }
4514 }
4515 break;
4516 case 11: /* 1600x1200 - unknown */
4517 r30 |= 0x40;
4518 if(!SiS_Pr->HaveEMI) {
4519 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4520 }
4521 }
4522 }
4523
4524 /* BIOS values don't work so well sometimes */
4525 if(!SiS_Pr->OverruleEMI) {
4526#ifdef COMPAL_HACK
4527 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4528 if((cr36 & 0x0f) == 0x09) {
4529 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4530 }
4531 }
4532#endif
4533#ifdef COMPAQ_HACK
4534 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4535 if((cr36 & 0x0f) == 0x03) {
4536 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4537 }
4538 }
4539#endif
4540#ifdef ASUS_HACK
4541 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4542 if((cr36 & 0x0f) == 0x02) {
4543 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4544 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4545 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4546 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4547 }
4548 }
4549#endif
4550 }
4551
4552 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4553 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4554 SiS_GenericDelay(SiS_Pr, 2048);
4555 }
4556 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4557 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4558 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4559#endif /* SET_EMI */
4560
4561 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4562
4563#ifdef SET_EMI
4564 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4565 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4566 if(r30 & 0x40) {
4567 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4568 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4569 if(delaylong) {
4570 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4571 delaylong = false;
4572 }
4573 SiS_WaitVBRetrace(SiS_Pr);
4574 SiS_WaitVBRetrace(SiS_Pr);
4575 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4576 SiS_GenericDelay(SiS_Pr, 1280);
4577 }
4578 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4579 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4580 }
4581 }
4582#endif
4583 }
4584 }
4585
4586 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4587 if(SiS_IsVAorLCD(SiS_Pr)) {
4588 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4589 if(delaylong) {
4590 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4591 }
4592 SiS_WaitVBRetrace(SiS_Pr);
4593 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4594 SiS_GenericDelay(SiS_Pr, 2048);
4595 SiS_WaitVBRetrace(SiS_Pr);
4596 }
4597 if(!didpwd) {
4598 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4599 } else {
4600 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4601 }
4602 }
4603 }
4604
4605 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4606 SiS_DisplayOn(SiS_Pr);
4607 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4608
4609 }
4610
4611 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4612 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4613 }
4614
4615#endif /* CONFIG_FB_SIS_315 */
4616
4617 }
4618
4619 } else { /* ============ For 301 ================ */
4620
4621 if(SiS_Pr->ChipType < SIS_315H) {
4622 if(SiS_CRT2IsLCD(SiS_Pr)) {
4623 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4624 SiS_PanelDelay(SiS_Pr, 0);
4625 }
4626 }
4627
4628 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4629 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4630 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4631 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4632 }
4633 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4634
4635 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4636
4637 if(SiS_Pr->ChipType >= SIS_315H) {
4638 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4639 if(!(temp & 0x80)) {
4640 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4641 }
4642 }
4643
4644 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4645
4646 SiS_VBLongWait(SiS_Pr);
4647 SiS_DisplayOn(SiS_Pr);
4648 if(SiS_Pr->ChipType >= SIS_315H) {
4649 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4650 }
4651 SiS_VBLongWait(SiS_Pr);
4652
4653 if(SiS_Pr->ChipType < SIS_315H) {
4654 if(SiS_CRT2IsLCD(SiS_Pr)) {
4655 SiS_PanelDelay(SiS_Pr, 1);
4656 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4657 }
4658 }
4659
4660 }
4661
4662 } else { /* =================== For LVDS ================== */
4663
4664 if(SiS_Pr->ChipType < SIS_315H) {
4665
4666#ifdef CONFIG_FB_SIS_300 /* 300 series */
4667
4668 if(SiS_CRT2IsLCD(SiS_Pr)) {
4669 if(SiS_Pr->ChipType == SIS_730) {
4670 SiS_PanelDelay(SiS_Pr, 1);
4671 SiS_PanelDelay(SiS_Pr, 1);
4672 SiS_PanelDelay(SiS_Pr, 1);
4673 }
4674 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4675 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4676 SiS_PanelDelay(SiS_Pr, 0);
4677 }
4678 }
4679
4680 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4681 SiS_DisplayOn(SiS_Pr);
4682 SiS_UnLockCRT2(SiS_Pr);
4683 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4684 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4685 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4686 } else {
4687 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4688 }
4689
4690 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4691 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4692 SiS_WaitVBRetrace(SiS_Pr);
4693 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4694 }
4695 }
4696
4697 if(SiS_CRT2IsLCD(SiS_Pr)) {
4698 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4699 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4700 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4701 SiS_PanelDelay(SiS_Pr, 1);
4702 SiS_PanelDelay(SiS_Pr, 1);
4703 }
4704 SiS_WaitVBRetrace(SiS_Pr);
4705 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4706 }
4707 }
4708 }
4709
4710#endif /* CONFIG_FB_SIS_300 */
4711
4712 } else {
4713
4714#ifdef CONFIG_FB_SIS_315 /* 315 series */
4715
4716 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4717 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4718 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4719 /*}*/
4720 }
4721
4722 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4723 if(SiS_CRT2IsLCD(SiS_Pr)) {
4724 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4725 SiS_PanelDelay(SiS_Pr, 0);
4726 }
4727 }
4728
4729 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4730 SiS_UnLockCRT2(SiS_Pr);
4731
4732 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4733
4734 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4735 temp = SiS_GetCH701x(SiS_Pr,0x66);
4736 temp &= 0x20;
4737 SiS_Chrontel701xBLOff(SiS_Pr);
4738 }
4739
4740 if(SiS_Pr->ChipType != SIS_550) {
4741 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4742 }
4743
4744 if(SiS_Pr->ChipType == SIS_740) {
4745 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4746 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4747 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4748 }
4749 }
4750 }
4751
4752 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4753 if(!(temp1 & 0x80)) {
4754 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4755 }
4756
4757 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4758 if(temp) {
4759 SiS_Chrontel701xBLOn(SiS_Pr);
4760 }
4761 }
4762
4763 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4764 if(SiS_CRT2IsLCD(SiS_Pr)) {
4765 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4766 if(SiS_Pr->ChipType == SIS_550) {
4767 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4768 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4769 }
4770 }
4771 } else if(SiS_IsVAMode(SiS_Pr)) {
4772 if(SiS_Pr->ChipType != SIS_740) {
4773 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4774 }
4775 }
4776
4777 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4778 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4779 }
4780
4781 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4782 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4783 SiS_Chrontel701xOn(SiS_Pr);
4784 }
4785 if( (SiS_IsVAMode(SiS_Pr)) ||
4786 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4787 SiS_ChrontelDoSomething1(SiS_Pr);
4788 }
4789 }
4790
4791 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4792 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4793 if( (SiS_IsVAMode(SiS_Pr)) ||
4794 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4795 SiS_Chrontel701xBLOn(SiS_Pr);
4796 SiS_ChrontelInitTVVSync(SiS_Pr);
4797 }
4798 }
4799 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4800 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4801 if(SiS_CRT2IsLCD(SiS_Pr)) {
4802 SiS_PanelDelay(SiS_Pr, 1);
4803 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4804 }
4805 }
4806 }
4807
4808#endif /* CONFIG_FB_SIS_315 */
4809
4810 } /* 310 series */
4811
4812 } /* LVDS */
4813
4814}
4815
4816/*********************************************/
4817/* SET PART 1 REGISTER GROUP */
4818/*********************************************/
4819
4820/* Set CRT2 OFFSET / PITCH */
4821static void
4822SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4823 unsigned short RRTI)
4824{
4825 unsigned short offset;
4826 unsigned char temp;
4827
4828 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4829
4830 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4831
4832 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4833 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4834
4835 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4836 if(offset & 0x07) temp++;
4837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4838}
4839
4840/* Set CRT2 sync and PanelLink mode */
4841static void
4842SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4843{
4844 unsigned short tempah=0, tempbl, infoflag;
4845
4846 tempbl = 0xC0;
4847
4848 if(SiS_Pr->UseCustomMode) {
4849 infoflag = SiS_Pr->CInfoFlag;
4850 } else {
4851 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4852 }
4853
4854 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4855
4856 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4857 tempah = 0;
4858 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4859 tempah = SiS_Pr->SiS_LCDInfo;
4860 } else tempah = infoflag >> 8;
4861 tempah &= 0xC0;
4862 tempah |= 0x20;
4863 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4864 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4865 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4866 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4867 tempah |= 0xf0;
4868 }
4869 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4870 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4871 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4872 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4873 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4874 tempah |= 0x30;
4875 }
4876 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4877 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4878 tempah &= ~0xc0;
4879 }
4880 }
4881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4882 if(SiS_Pr->ChipType >= SIS_315H) {
4883 tempah >>= 3;
4884 tempah &= 0x18;
4885 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4886 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4887 } else {
4888 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4889 }
4890 } else {
4891 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4892 }
4893
4894 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4895
4896 if(SiS_Pr->ChipType < SIS_315H) {
4897
4898#ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
4899
4900 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4901
4902 tempah = infoflag >> 8;
4903 tempbl = 0;
4904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4905 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4906 tempah = SiS_Pr->SiS_LCDInfo;
4907 tempbl = (tempah >> 6) & 0x03;
4908 }
4909 }
4910 tempah &= 0xC0;
4911 tempah |= 0x20;
4912 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4913 tempah |= 0xc0;
4914 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4915 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4916 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4917 }
4918
4919 } else { /* 630 - 301 */
4920
4921 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4922 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4923 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4924
4925 }
4926
4927#endif /* CONFIG_FB_SIS_300 */
4928
4929 } else {
4930
4931#ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
4932
4933 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4934
4935 tempbl = 0;
4936 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4937 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4938 tempah = infoflag >> 8;
4939 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4940 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4941 }
4942 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4943 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4944 tempah = infoflag >> 8;
4945 tempbl = 0x03;
4946 } else {
4947 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4948 tempbl = (tempah >> 6) & 0x03;
4949 tempbl |= 0x08;
4950 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4951 }
4952 tempah &= 0xC0;
4953 tempah |= 0x20;
4954 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4955 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4956 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4957 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4958 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4959 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4960 }
4961 }
4962
4963 } else { /* 315 - TMDS */
4964
4965 tempah = tempbl = infoflag >> 8;
4966 if(!SiS_Pr->UseCustomMode) {
4967 tempbl = 0;
4968 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4969 if(ModeNo <= 0x13) {
4970 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4971 }
4972 }
4973 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4974 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4975 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4976 tempah = SiS_Pr->SiS_LCDInfo;
4977 tempbl = (tempah >> 6) & 0x03;
4978 }
4979 }
4980 }
4981 }
4982 tempah &= 0xC0;
4983 tempah |= 0x20;
4984 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4985 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4986 /* Imitate BIOS bug */
4987 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4988 }
4989 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4990 tempah >>= 3;
4991 tempah &= 0x18;
4992 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4993 } else {
4994 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4995 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4996 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4997 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4998 }
4999 }
5000 }
5001
5002 }
5003#endif /* CONFIG_FB_SIS_315 */
5004 }
5005 }
5006}
5007
5008/* Set CRT2 FIFO on 300/540/630/730 */
5009#ifdef CONFIG_FB_SIS_300
5010static void
5011SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5012{
5013 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5014 unsigned short temp, index, modeidindex, refreshratetableindex;
5015 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5016 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5017 unsigned int data, pci50, pciA0;
5018 static const unsigned char colortharray[] = {
5019 1, 1, 2, 2, 3, 4
5020 };
5021
5022 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5023
5024 if(!SiS_Pr->CRT1UsesCustomMode) {
5025
5026 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5027 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5028 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5029 SiS_Pr->SiS_SelectCRT2Rate = 0;
5030 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5031
5032 if(CRT1ModeNo >= 0x13) {
5033 /* Get VCLK */
5034 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5035 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5036
5037 /* Get colordepth */
5038 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5039 if(!colorth) colorth++;
5040 }
5041
5042 } else {
5043
5044 CRT1ModeNo = 0xfe;
5045
5046 /* Get VCLK */
5047 VCLK = SiS_Pr->CSRClock_CRT1;
5048
5049 /* Get color depth */
5050 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5051
5052 }
5053
5054 if(CRT1ModeNo >= 0x13) {
5055 /* Get MCLK */
5056 if(SiS_Pr->ChipType == SIS_300) {
5057 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5058 } else {
5059 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5060 }
5061 index &= 0x07;
5062 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5063
5064 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5065 if(!temp) temp++;
5066 temp <<= 2;
5067
5068 data2 = temp - ((colorth * VCLK) / MCLK);
5069
5070 temp = (28 * 16) % data2;
5071 data2 = (28 * 16) / data2;
5072 if(temp) data2++;
5073
5074 if(SiS_Pr->ChipType == SIS_300) {
5075
5076 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5077 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5078
5079 } else {
5080
5081 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5082 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5083
5084 if(SiS_Pr->ChipType == SIS_730) {
5085
5086 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5087 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5088
5089 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5090 index = 0; /* -- do it like the BIOS anyway... */
5091
5092 } else {
5093
5094 pci50 >>= 24;
5095 pciA0 >>= 24;
5096
5097 index = (pci50 >> 1) & 0x07;
5098
5099 if(pci50 & 0x01) index += 6;
5100 if(!(pciA0 & 0x01)) index += 24;
5101
5102 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5103
5104 }
5105
5106 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5107 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5108
5109 }
5110
5111 data += data2; /* CRT1 Request Period */
5112
5113 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5114 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5115
5116 if(!SiS_Pr->UseCustomMode) {
5117
5118 CRT2ModeNo = ModeNo;
5119 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5120
5121 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5122
5123 /* Get VCLK */
5124 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5125 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5126
5127 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5128 if(SiS_Pr->SiS_UseROM) {
5129 if(ROMAddr[0x220] & 0x01) {
5130 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5131 }
5132 }
5133 }
5134
5135 } else {
5136
5137 /* Get VCLK */
5138 CRT2ModeNo = 0xfe;
5139 VCLK = SiS_Pr->CSRClock;
5140
5141 }
5142
5143 /* Get colordepth */
5144 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5145 if(!colorth) colorth++;
5146
5147 data = data * VCLK * colorth;
5148 temp = data % (MCLK << 4);
5149 data = data / (MCLK << 4);
5150 if(temp) data++;
5151
5152 if(data < 6) data = 6;
5153 else if(data > 0x14) data = 0x14;
5154
5155 if(SiS_Pr->ChipType == SIS_300) {
5156 temp = 0x16;
5157 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5158 temp = 0x13;
5159 } else {
5160 temp = 0x16;
5161 if(( (SiS_Pr->ChipType == SIS_630) ||
5162 (SiS_Pr->ChipType == SIS_730) ) &&
5163 (SiS_Pr->ChipRevision >= 0x30))
5164 temp = 0x1b;
5165 }
5166 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5167
5168 if((SiS_Pr->ChipType == SIS_630) &&
5169 (SiS_Pr->ChipRevision >= 0x30)) {
5170 if(data > 0x13) data = 0x13;
5171 }
5172 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5173
5174 } else { /* If mode <= 0x13, we just restore everything */
5175
5176 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5177 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5178
5179 }
5180}
5181#endif
5182
5183/* Set CRT2 FIFO on 315/330 series */
5184#ifdef CONFIG_FB_SIS_315
5185static void
5186SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5187{
5188 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5189 if( (SiS_Pr->ChipType == SIS_760) &&
5190 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5191 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5192 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5193 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5198 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5199 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5200 } else {
5201 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5202 }
5203
5204}
5205#endif
5206
5207static unsigned short
5208SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5209{
5210 unsigned int tempax,tempbx;
5211
5212 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5213 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5214 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5215 return (unsigned short)tempax;
5216}
5217
5218/* Set Part 1 / SiS bridge slave mode */
5219static void
5220SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5221 unsigned short RefreshRateTableIndex)
5222{
5223 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5224 static const unsigned short CRTranslation[] = {
5225 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5226 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5227 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5228 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5229 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5230 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5231 };
5232
5233 if(ModeNo <= 0x13) {
5234 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5235 } else if(SiS_Pr->UseCustomMode) {
5236 modeflag = SiS_Pr->CModeFlag;
5237 xres = SiS_Pr->CHDisplay;
5238 } else {
5239 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5240 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5241 }
5242
5243 /* The following is only done if bridge is in slave mode: */
5244
5245 if(SiS_Pr->ChipType >= SIS_315H) {
5246 if(xres >= 1600) { /* BIOS: == 1600 */
5247 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5248 }
5249 }
5250
5251 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5252
5253 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5254 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5255
5256 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5257 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5258 SiS_Pr->CHBlankStart += 16;
5259 }
5260
5261 SiS_Pr->CHBlankEnd = 32;
5262 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5263 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5264 }
5265
5266 temp = SiS_Pr->SiS_VGAHT - 96;
5267 if(!(modeflag & HalfDCLK)) temp -= 32;
5268 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5269 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5270 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5271 temp -= 3;
5272 temp <<= 3;
5273 } else {
5274 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5275 }
5276 SiS_Pr->CHSyncStart = temp;
5277
5278 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5279
5280 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5281
5282 VGAVDE = SiS_Pr->SiS_VGAVDE;
5283 if (VGAVDE == 357) VGAVDE = 350;
5284 else if(VGAVDE == 360) VGAVDE = 350;
5285 else if(VGAVDE == 375) VGAVDE = 350;
5286 else if(VGAVDE == 405) VGAVDE = 400;
5287 else if(VGAVDE == 420) VGAVDE = 400;
5288 else if(VGAVDE == 525) VGAVDE = 480;
5289 else if(VGAVDE == 1056) VGAVDE = 1024;
5290 SiS_Pr->CVDisplay = VGAVDE;
5291
5292 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5293
5294 SiS_Pr->CVBlankEnd = 1;
5295 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5296
5297 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5298 SiS_Pr->CVSyncStart = VGAVDE + temp;
5299
5300 temp >>= 3;
5301 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5302
5303 SiS_CalcCRRegisters(SiS_Pr, 0);
5304 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5305
5306 for(i = 0; i <= 7; i++) {
5307 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5308 }
5309 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5310 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5311 }
5312 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5313 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5314 }
5315 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5316 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5317 }
5318
5319 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5320 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5321
5322 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5323 if(modeflag & DoubleScanMode) temp |= 0x80;
5324 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5325
5326 temp = 0;
5327 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5328 if(modeflag & HalfDCLK) temp |= 0x08;
5329 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5330
5331 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5332 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5333
5334 temp = 0;
5335 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5336 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5337 }
5338 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5339
5340 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5341 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5342}
5343
5344/* Setup panel link
5345 * This is used for LVDS, LCDA and Chrontel TV output
5346 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5347 */
5348static void
5349SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5350 unsigned short RefreshRateTableIndex)
5351{
5352 unsigned short modeflag, resinfo = 0;
5353 unsigned short push2, tempax, tempbx, tempcx, temp;
5354 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5355 bool islvds = false, issis = false, chkdclkfirst = false;
5356#ifdef CONFIG_FB_SIS_300
5357 unsigned short crt2crtc = 0;
5358#endif
5359#ifdef CONFIG_FB_SIS_315
5360 unsigned short pushcx;
5361#endif
5362
5363 if(ModeNo <= 0x13) {
5364 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5365 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5366#ifdef CONFIG_FB_SIS_300
5367 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5368#endif
5369 } else if(SiS_Pr->UseCustomMode) {
5370 modeflag = SiS_Pr->CModeFlag;
5371 } else {
5372 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5373 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5374#ifdef CONFIG_FB_SIS_300
5375 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5376#endif
5377 }
5378
5379 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5380 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5381 islvds = true;
5382 }
5383
5384 /* is really sis if sis bridge, but not 301B-DH */
5385 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5386 issis = true;
5387 }
5388
5389 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5390 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5391 chkdclkfirst = true;
5392 }
5393 }
5394
5395#ifdef CONFIG_FB_SIS_315
5396 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5397 if(IS_SIS330) {
5398 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5399 } else if(IS_SIS740) {
5400 if(islvds) {
5401 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5402 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5403 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5404 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5405 }
5406 } else {
5407 if(islvds) {
5408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5409 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5410 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5411 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5412 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5413 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5414 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5415 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5416 }
5417 }
5418 }
5419 }
5420 }
5421#endif
5422
5423 /* Horizontal */
5424
5425 tempax = SiS_Pr->SiS_LCDHDES;
5426 if(islvds) {
5427 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5428 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5429 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5430 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5431 tempax -= 8;
5432 }
5433 }
5434 }
5435 }
5436
5437 temp = (tempax & 0x0007);
5438 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5439 temp = (tempax >> 3) & 0x00FF;
5440 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5441
5442 tempbx = SiS_Pr->SiS_HDE;
5443 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5444 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5445 tempbx = SiS_Pr->PanelXRes;
5446 }
5447 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5448 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5449 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5450 tempbx >>= 1;
5451 }
5452 }
5453
5454 tempax += tempbx;
5455 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5456
5457 temp = tempax;
5458 if(temp & 0x07) temp += 8;
5459 temp >>= 3;
5460 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5461
5462 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5463
5464 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5465 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5466 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5467 }
5468 }
5469
5470 tempcx += tempax;
5471 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5472
5473 temp = (tempcx >> 3) & 0x00FF;
5474 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5475 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5476 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5477 switch(ModeNo) {
5478 case 0x04:
5479 case 0x05:
5480 case 0x0d: temp = 0x56; break;
5481 case 0x10: temp = 0x60; break;
5482 case 0x13: temp = 0x5f; break;
5483 case 0x40:
5484 case 0x41:
5485 case 0x4f:
5486 case 0x43:
5487 case 0x44:
5488 case 0x62:
5489 case 0x56:
5490 case 0x53:
5491 case 0x5d:
5492 case 0x5e: temp = 0x54; break;
5493 }
5494 }
5495 }
5496 }
5497 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5498
5499 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5500 temp += 2;
5501 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5502 temp += 8;
5503 if(SiS_Pr->PanelHRE != 999) {
5504 temp = tempcx + SiS_Pr->PanelHRE;
5505 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5506 temp >>= 3;
5507 }
5508 }
5509 } else {
5510 temp += 10;
5511 }
5512
5513 temp &= 0x1F;
5514 temp |= ((tempcx & 0x07) << 5);
5515 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5516
5517 /* Vertical */
5518
5519 tempax = SiS_Pr->SiS_VGAVDE;
5520 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5521 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5522 tempax = SiS_Pr->PanelYRes;
5523 }
5524 }
5525
5526 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5527 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5528
5529 push2 = tempbx;
5530
5531 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5532 if(SiS_Pr->ChipType < SIS_315H) {
5533 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5534 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5535 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5536 }
5537 }
5538 }
5539 if(islvds) tempcx >>= 1;
5540 else tempcx >>= 2;
5541
5542 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5543 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5544 (SiS_Pr->PanelVRS != 999) ) {
5545 tempcx = SiS_Pr->PanelVRS;
5546 tempbx += tempcx;
5547 if(issis) tempbx++;
5548 } else {
5549 tempbx += tempcx;
5550 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5551 else if(issis) tempbx++;
5552 }
5553
5554 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5555
5556 temp = tempbx & 0x00FF;
5557 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5558 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5559 if(ModeNo == 0x10) temp = 0xa9;
5560 }
5561 }
5562 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5563
5564 tempcx >>= 3;
5565 tempcx++;
5566
5567 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5568 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5569 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5570 }
5571 }
5572
5573 tempcx += tempbx;
5574 temp = tempcx & 0x000F;
5575 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5576
5577 temp = ((tempbx >> 8) & 0x07) << 3;
5578 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5579 if(SiS_Pr->SiS_HDE != 640) {
5580 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5581 }
5582 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5583 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5584 tempbx = 0x87;
5585 if((SiS_Pr->ChipType >= SIS_315H) ||
5586 (SiS_Pr->ChipRevision >= 0x30)) {
5587 tempbx = 0x07;
5588 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5589 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5590 }
5591 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5592 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5593 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5594 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5595 } else {
5596 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5597 }
5598 }
5599 }
5600 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5601
5602 tempbx = push2; /* BPLVDEE */
5603
5604 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5605
5606 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5607 switch(SiS_Pr->SiS_LCDResInfo) {
5608 case Panel_640x480:
5609 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5610 tempcx = SiS_Pr->SiS_VGAVDE;
5611 break;
5612 case Panel_800x600:
5613 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5614 if(resinfo == SIS_RI_800x600) tempcx++;
5615 }
5616 break;
5617 case Panel_1024x600:
5618 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5619 if(resinfo == SIS_RI_1024x600) tempcx++;
5620 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5621 if(resinfo == SIS_RI_800x600) tempcx++;
5622 }
5623 }
5624 break;
5625 case Panel_1024x768:
5626 if(SiS_Pr->ChipType < SIS_315H) {
5627 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5628 if(resinfo == SIS_RI_1024x768) tempcx++;
5629 }
5630 }
5631 break;
5632 }
5633 }
5634
5635 temp = ((tempbx >> 8) & 0x07) << 3;
5636 temp |= ((tempcx >> 8) & 0x07);
5637 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5638 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5639 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5640
5641 /* Vertical scaling */
5642
5643 if(SiS_Pr->ChipType < SIS_315H) {
5644
5645#ifdef CONFIG_FB_SIS_300 /* 300 series */
5646 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5647 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5648 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5649 if(temp) tempeax++;
5650
5651 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5652
5653 temp = (unsigned short)(tempeax & 0x00FF);
5654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5655 tempvcfact = temp;
5656#endif /* CONFIG_FB_SIS_300 */
5657
5658 } else {
5659
5660#ifdef CONFIG_FB_SIS_315 /* 315 series */
5661 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5662 tempebx = SiS_Pr->SiS_VDE;
5663 temp = (tempeax % tempebx);
5664 tempeax = tempeax / tempebx;
5665 if(temp) tempeax++;
5666 tempvcfact = tempeax;
5667
5668 temp = (unsigned short)(tempeax & 0x00FF);
5669 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5670 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5671 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5672 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5673 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5674 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5675
5676 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5677 temp = (unsigned short)(tempeax & 0x00FF);
5678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5679 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5681 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5682 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5683 temp = 0;
5684 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5685 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5686 }
5687#endif
5688
5689 }
5690
5691 /* Horizontal scaling */
5692
5693 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5694 if(chkdclkfirst) {
5695 if(modeflag & HalfDCLK) tempeax >>= 1;
5696 }
5697 tempebx = tempeax << 16;
5698 if(SiS_Pr->SiS_HDE == tempeax) {
5699 tempecx = 0xFFFF;
5700 } else {
5701 tempecx = tempebx / SiS_Pr->SiS_HDE;
5702 if(SiS_Pr->ChipType >= SIS_315H) {
5703 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5704 }
5705 }
5706
5707 if(SiS_Pr->ChipType >= SIS_315H) {
5708 tempeax = (tempebx / tempecx) - 1;
5709 } else {
5710 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5711 }
5712 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5713 temp = (unsigned short)(tempecx & 0x00FF);
5714 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5715
5716 if(SiS_Pr->ChipType >= SIS_315H) {
5717 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5718 tempbx = (unsigned short)(tempeax & 0xFFFF);
5719 } else {
5720 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5721 tempbx = tempvcfact & 0x3f;
5722 if(tempbx == 0) tempbx = 64;
5723 tempeax /= tempbx;
5724 tempbx = (unsigned short)(tempeax & 0xFFFF);
5725 }
5726 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5727 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5728 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5729 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5730 }
5731
5732 temp = ((tempbx >> 8) & 0x07) << 3;
5733 temp = temp | ((tempecx >> 8) & 0x07);
5734 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5735 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5736
5737 tempecx >>= 16; /* BPLHCFACT */
5738 if(!chkdclkfirst) {
5739 if(modeflag & HalfDCLK) tempecx >>= 1;
5740 }
5741 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5742 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5743 temp = (unsigned short)(tempecx & 0x00FF);
5744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5745
5746#ifdef CONFIG_FB_SIS_315
5747 if(SiS_Pr->ChipType >= SIS_315H) {
5748 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5749 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5750 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5751 }
5752 } else {
5753 if(islvds) {
5754 if(SiS_Pr->ChipType == SIS_740) {
5755 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5756 } else {
5757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5758 }
5759 }
5760 }
5761 }
5762#endif
5763
5764#ifdef CONFIG_FB_SIS_300
5765 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5766 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5767 unsigned char *trumpdata;
5768 int i, j = crt2crtc;
5769 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5770 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5771 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5772
5773 if(SiS_Pr->SiS_UseROM) {
5774 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5775 } else {
5776 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5777 trumpdata = &SiS300_TrumpionData[j][0];
5778 }
5779
5780 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5781 for(i=0; i<5; i++) {
5782 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5783 }
5784 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5785 if(ModeNo == 0x13) {
5786 for(i=0; i<4; i++) {
5787 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5788 }
5789 } else if(ModeNo == 0x10) {
5790 for(i=0; i<4; i++) {
5791 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5792 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5793 }
5794 }
5795 }
5796 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5797 }
5798#endif
5799
5800#ifdef CONFIG_FB_SIS_315
5801 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5802 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5804 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5805 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5806 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5807 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5808 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5809 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5810 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5811 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5812 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5813 tempax += 64;
5814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5815 temp = (tempax >> 8) << 3;
5816 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5817 tempax += 32; /* Blpe = lBlps+32 */
5818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5820 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5821
5822 tempax = SiS_Pr->SiS_VDE;
5823 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5824 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5825 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5826 tempax >>= 1;
5827 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5828 temp = (tempax >> 8) << 3;
5829 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5830
5831 tempeax = SiS_Pr->SiS_HDE;
5832 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5833 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5834 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5835 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5836 temp = tempeax & 0x7f;
5837 tempeax >>= 7;
5838 if(temp) tempeax++;
5839 temp = tempeax & 0x3f;
5840 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5841 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5842 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5843 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5844 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5845
5846 tempax = SiS_Pr->SiS_HDE;
5847 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5848 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5849 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5850 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5851 pushcx = tempax;
5852 temp = tempax & 0x00FF;
5853 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5854 temp = ((tempax & 0xFF00) >> 8) << 3;
5855 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
5856
5857 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5858 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5859 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5860 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5861 tempeax = tempax * pushcx;
5862 temp = tempeax & 0xFF;
5863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5864 temp = (tempeax & 0xFF00) >> 8;
5865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5866 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5868 temp = ((tempeax & 0x01000000) >> 24) << 7;
5869 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
5870
5871 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5873 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5876
5877 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5878 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5879 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5880 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5881 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5882 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5898 }
5899 }
5900#endif /* CONFIG_FB_SIS_315 */
5901}
5902
5903/* Set Part 1 */
5904static void
5905SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5906 unsigned short RefreshRateTableIndex)
5907{
5908#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
5909 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5910#endif
5911 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5912 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5913#ifdef CONFIG_FB_SIS_315
5914 unsigned short tempbl=0;
5915#endif
5916
5917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5918 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5919 return;
5920 }
5921
5922 if(ModeNo <= 0x13) {
5923 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5924 } else if(SiS_Pr->UseCustomMode) {
5925 modeflag = SiS_Pr->CModeFlag;
5926 } else {
5927 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
5928 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5929 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5930 }
5931
5932 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5933
5934 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
5935 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
5936 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5937
5938 if(SiS_Pr->ChipType < SIS_315H ) {
5939#ifdef CONFIG_FB_SIS_300
5940 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
5941#endif
5942 } else {
5943#ifdef CONFIG_FB_SIS_315
5944 SiS_SetCRT2FIFO_310(SiS_Pr);
5945#endif
5946 }
5947
5948 /* 1. Horizontal setup */
5949
5950 if(SiS_Pr->ChipType < SIS_315H ) {
5951
5952#ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
5953
5954 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
5955 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
5956
5957 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
5958 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5959
5960 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
5962
5963 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
5964 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
5965 tempbx = pushbx + tempcx;
5966 tempcx <<= 1;
5967 tempcx += tempbx;
5968
5969 bridgeadd = 12;
5970
5971#endif /* CONFIG_FB_SIS_300 */
5972
5973 } else {
5974
5975#ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
5976
5977 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
5978 if(modeflag & HalfDCLK) {
5979 if(SiS_Pr->SiS_VBType & VB_SISVB) {
5980 tempcx >>= 1;
5981 } else {
5982 tempax = SiS_Pr->SiS_VGAHDE >> 1;
5983 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
5984 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5985 tempcx = SiS_Pr->SiS_HT - tempax;
5986 }
5987 }
5988 }
5989 tempcx--;
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
5991 temp = (tempcx >> 4) & 0xF0;
5992 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
5993
5994 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
5995 tempbx = SiS_Pr->SiS_VGAHDE;
5996 tempcx -= tempbx;
5997 tempcx >>= 2;
5998 if(modeflag & HalfDCLK) {
5999 tempbx >>= 1;
6000 tempcx >>= 1;
6001 }
6002 tempbx += 16;
6003
6004 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6005
6006 pushbx = tempbx;
6007 tempcx >>= 1;
6008 tempbx += tempcx;
6009 tempcx += tempbx;
6010
6011 bridgeadd = 16;
6012
6013 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6014 if(SiS_Pr->ChipType >= SIS_661) {
6015 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6016 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6017 if(resinfo == SIS_RI_1280x1024) {
6018 tempcx = (tempcx & 0xff00) | 0x30;
6019 } else if(resinfo == SIS_RI_1600x1200) {
6020 tempcx = (tempcx & 0xff00) | 0xff;
6021 }
6022 }
6023 }
6024 }
6025
6026#endif /* CONFIG_FB_SIS_315 */
6027
6028 } /* 315/330 series */
6029
6030 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6031
6032 if(SiS_Pr->UseCustomMode) {
6033 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6034 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6035 tempax = SiS_Pr->SiS_VGAHT;
6036 if(modeflag & HalfDCLK) tempax >>= 1;
6037 tempax--;
6038 if(tempcx > tempax) tempcx = tempax;
6039 }
6040
6041 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6042 unsigned char cr4, cr14, cr5, cr15;
6043 if(SiS_Pr->UseCustomMode) {
6044 cr4 = SiS_Pr->CCRT1CRTC[4];
6045 cr14 = SiS_Pr->CCRT1CRTC[14];
6046 cr5 = SiS_Pr->CCRT1CRTC[5];
6047 cr15 = SiS_Pr->CCRT1CRTC[15];
6048 } else {
6049 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6050 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6051 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6052 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6053 }
6054 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6055 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6056 tempcx &= 0x00FF;
6057 tempcx |= (tempbx & 0xFF00);
6058 tempbx += bridgeadd;
6059 tempcx += bridgeadd;
6060 tempax = SiS_Pr->SiS_VGAHT;
6061 if(modeflag & HalfDCLK) tempax >>= 1;
6062 tempax--;
6063 if(tempcx > tempax) tempcx = tempax;
6064 }
6065
6066 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6067 tempbx = 1040;
6068 tempcx = 1044; /* HWCursor bug! */
6069 }
6070
6071 }
6072
6073 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6074
6075 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6076
6077 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6078 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6079
6080 /* 2. Vertical setup */
6081
6082 tempcx = SiS_Pr->SiS_VGAVT - 1;
6083 temp = tempcx & 0x00FF;
6084
6085 if(SiS_Pr->ChipType < SIS_661) {
6086 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6087 if(SiS_Pr->ChipType < SIS_315H) {
6088 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6089 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6090 temp--;
6091 }
6092 }
6093 } else {
6094 temp--;
6095 }
6096 } else if(SiS_Pr->ChipType >= SIS_315H) {
6097 temp--;
6098 }
6099 }
6100 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6101
6102 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6103 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6104
6105 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6106 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6107
6108 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6109 tempbx++;
6110 tempax = tempbx;
6111 tempcx++;
6112 tempcx -= tempax;
6113 tempcx >>= 2;
6114 tempbx += tempcx;
6115 if(tempcx < 4) tempcx = 4;
6116 tempcx >>= 2;
6117 tempcx += tempbx;
6118 tempcx++;
6119 } else {
6120 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6121 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6122 }
6123
6124 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6125 if(SiS_Pr->UseCustomMode) {
6126 tempbx = SiS_Pr->CVSyncStart;
6127 tempcx = SiS_Pr->CVSyncEnd;
6128 }
6129 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6130 unsigned char cr8, cr7, cr13;
6131 if(SiS_Pr->UseCustomMode) {
6132 cr8 = SiS_Pr->CCRT1CRTC[8];
6133 cr7 = SiS_Pr->CCRT1CRTC[7];
6134 cr13 = SiS_Pr->CCRT1CRTC[13];
6135 tempcx = SiS_Pr->CCRT1CRTC[9];
6136 } else {
6137 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6138 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6139 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6140 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6141 }
6142 tempbx = cr8;
6143 if(cr7 & 0x04) tempbx |= 0x0100;
6144 if(cr7 & 0x80) tempbx |= 0x0200;
6145 if(cr13 & 0x08) tempbx |= 0x0400;
6146 }
6147 }
6148 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6149
6150 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6151 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6152
6153 /* 3. Panel delay compensation */
6154
6155 if(SiS_Pr->ChipType < SIS_315H) {
6156
6157#ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6158
6159 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6160 temp = 0x20;
6161 if(SiS_Pr->ChipType == SIS_300) {
6162 temp = 0x10;
6163 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6164 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6165 }
6166 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6167 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6168 }
6169 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6170 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6171 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6172 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6173 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6174 else temp = 0x20;
6175 }
6176 if(SiS_Pr->SiS_UseROM) {
6177 if(ROMAddr[0x220] & 0x80) {
6178 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6179 temp = ROMAddr[0x221];
6180 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6181 temp = ROMAddr[0x222];
6182 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6183 temp = ROMAddr[0x223];
6184 else
6185 temp = ROMAddr[0x224];
6186 }
6187 }
6188 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6189 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6190 }
6191
6192 } else {
6193 temp = 0x20;
6194 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6195 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6196 }
6197 if(SiS_Pr->SiS_UseROM) {
6198 if(ROMAddr[0x220] & 0x80) {
6199 temp = ROMAddr[0x220];
6200 }
6201 }
6202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6203 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6204 }
6205 }
6206
6207 temp &= 0x3c;
6208
6209 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6210
6211#endif /* CONFIG_FB_SIS_300 */
6212
6213 } else {
6214
6215#ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6216
6217 if(SiS_Pr->ChipType < SIS_661) {
6218
6219 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6220
6221 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6222 else temp = 0x00;
6223
6224 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6225 tempbl = 0xF0;
6226 if(SiS_Pr->ChipType == SIS_650) {
6227 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6228 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6229 }
6230 }
6231
6232 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6233 temp = 0x08;
6234 tempbl = 0;
6235 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6236 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6237 }
6238 }
6239
6240 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6241 }
6242
6243 } /* < 661 */
6244
6245 tempax = 0;
6246 if(modeflag & DoubleScanMode) tempax |= 0x80;
6247 if(modeflag & HalfDCLK) tempax |= 0x40;
6248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6249
6250#endif /* CONFIG_FB_SIS_315 */
6251
6252 }
6253
6254 } /* Slavemode */
6255
6256 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6257 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6258 /* For 301BDH with LCD, we set up the Panel Link */
6259 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6260 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6261 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6262 }
6263 } else {
6264 if(SiS_Pr->ChipType < SIS_315H) {
6265 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6266 } else {
6267 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6268 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6269 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6270 }
6271 } else {
6272 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6273 }
6274 }
6275 }
6276}
6277
6278/*********************************************/
6279/* SET PART 2 REGISTER GROUP */
6280/*********************************************/
6281
6282#ifdef CONFIG_FB_SIS_315
6283static unsigned char *
6284SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6285{
6286 const unsigned char *tableptr = NULL;
6287 unsigned short a, b, p = 0;
6288
6289 a = SiS_Pr->SiS_VGAHDE;
6290 b = SiS_Pr->SiS_HDE;
6291 if(tabletype) {
6292 a = SiS_Pr->SiS_VGAVDE;
6293 b = SiS_Pr->SiS_VDE;
6294 }
6295
6296 if(a < b) {
6297 tableptr = SiS_Part2CLVX_1;
6298 } else if(a == b) {
6299 tableptr = SiS_Part2CLVX_2;
6300 } else {
6301 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6302 tableptr = SiS_Part2CLVX_4;
6303 } else {
6304 tableptr = SiS_Part2CLVX_3;
6305 }
6306 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6307 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6308 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6309 else tableptr = SiS_Part2CLVX_5;
6310 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6311 tableptr = SiS_Part2CLVX_6;
6312 }
6313 do {
6314 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6315 p += 0x42;
6316 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6317 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6318 }
6319 p += 2;
6320 return ((unsigned char *)&tableptr[p]);
6321}
6322
6323static void
6324SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6325 unsigned short RefreshRateTableIndex)
6326{
6327 unsigned char *tableptr;
6328 unsigned char temp;
6329 int i, j;
6330
6331 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6332
6333 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6334 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6335 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6336 }
6337 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6338 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6339 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6340 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6341 }
6342 }
6343 temp = 0x10;
6344 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6345 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6346}
6347
6348static bool
6349SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6350 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6351 unsigned short *ResIndex)
6352{
6353
6354 if(SiS_Pr->ChipType < SIS_315H) return false;
6355
6356 if(ModeNo <= 0x13)
6357 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6358 else
6359 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6360
6361 (*ResIndex) &= 0x3f;
6362 (*CRT2Index) = 0;
6363
6364 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6365 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6366 (*CRT2Index) = 200;
6367 }
6368 }
6369
6370 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6371 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6372 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6373 }
6374 }
6375 return (((*CRT2Index) != 0));
6376}
6377#endif
6378
6379#ifdef CONFIG_FB_SIS_300
6380static void
6381SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6382{
6383 unsigned short tempcx;
6384 static const unsigned char atable[] = {
6385 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6386 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6387 };
6388
6389 if(!SiS_Pr->UseCustomMode) {
6390 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6391 (SiS_Pr->ChipType == SIS_730) ) &&
6392 (SiS_Pr->ChipRevision > 2) ) &&
6393 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6394 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6395 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6396 if(ModeNo == 0x13) {
6397 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6399 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6400 } else if((crt2crtc & 0x3F) == 4) {
6401 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6402 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6403 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6404 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6405 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6406 }
6407 }
6408
6409 if(SiS_Pr->ChipType < SIS_315H) {
6410 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6411 crt2crtc &= 0x1f;
6412 tempcx = 0;
6413 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6414 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6415 tempcx += 7;
6416 }
6417 }
6418 tempcx += crt2crtc;
6419 if(crt2crtc >= 4) {
6420 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6421 }
6422
6423 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6424 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6425 if(crt2crtc == 4) {
6426 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6427 }
6428 }
6429 }
6430 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6431 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6432 }
6433 }
6434 }
6435}
6436
6437/* For ECS A907. Highly preliminary. */
6438static void
6439SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6440 unsigned short ModeNo)
6441{
6442 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6443 unsigned short crt2crtc, resindex;
6444 int i, j;
6445
6446 if(SiS_Pr->ChipType != SIS_300) return;
6447 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6448 if(SiS_Pr->UseCustomMode) return;
6449
6450 if(ModeNo <= 0x13) {
6451 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6452 } else {
6453 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6454 }
6455
6456 resindex = crt2crtc & 0x3F;
6457 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6458 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6459
6460 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6461 if(ModeNo > 0x13) {
6462 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6463 resindex = 4;
6464 }
6465
6466 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6467 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6468 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6469 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6470 }
6471 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6472 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6473 }
6474 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6475 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6476 }
6477 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6478 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6479}
6480#endif
6481
6482static void
6483SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6484{
6485 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6486 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6487 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6488
6489 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6490 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6491 const unsigned char specialtv[] = {
6492 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6493 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6494 0x58,0xe4,0x73,0xda,0x13
6495 };
6496 int i, j;
6497 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6498 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6499 }
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6501 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6502 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6505 } else {
6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6508 }
6509 }
6510 }
6511 } else {
6512 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6513 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6514 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6515 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6516 } else {
6517 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6518 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6519 }
6520 }
6521}
6522
6523static void
6524SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6525{
6526 unsigned short temp;
6527
6528 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6529 if(SiS_Pr->SiS_VGAVDE == 525) {
6530 temp = 0xc3;
6531 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6532 temp++;
6533 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6534 }
6535 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6536 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6537 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6538 temp = 0x4d;
6539 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6540 temp++;
6541 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6542 }
6543 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6544 }
6545 }
6546
6547 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6548 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6549 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6550 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6551 /* Not always for LV, see SetGrp2 */
6552 }
6553 temp = 1;
6554 if(ModeNo <= 0x13) temp = 3;
6555 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6556 }
6557#if 0
6558 /* 651+301C, for 1280x768 - do I really need that? */
6559 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6560 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6561 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6562 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6563 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6564 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6565 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6566 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6567 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6568 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6569 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6570 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6571 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6572 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6573 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6574 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6575 }
6576 }
6577 }
6578#endif
6579 }
6580}
6581
6582static void
6583SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6584 unsigned short RefreshRateTableIndex)
6585{
6586 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6587 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6588 unsigned int longtemp, PhaseIndex;
6589 bool newtvphase;
6590 const unsigned char *TimingPoint;
6591#ifdef CONFIG_FB_SIS_315
6592 unsigned short resindex, CRT2Index;
6593 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6594
6595 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6596#endif
6597
6598 if(ModeNo <= 0x13) {
6599 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6600 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6601 } else if(SiS_Pr->UseCustomMode) {
6602 modeflag = SiS_Pr->CModeFlag;
6603 crt2crtc = 0;
6604 } else {
6605 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6606 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6607 }
6608
6609 temp = 0;
6610 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6611 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6612 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6613 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6614
6615 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6616
6617 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6618
6619 PhaseIndex = 0x01; /* SiS_PALPhase */
6620 TimingPoint = SiS_Pr->SiS_PALTiming;
6621
6622 newtvphase = false;
6623 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6624 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6625 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6626 newtvphase = true;
6627 }
6628
6629 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6630
6631 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6632 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6633 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6634 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6635 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6636 }
6637 }
6638
6639 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6640
6641 i = 0;
6642 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6643 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6644
6645 TimingPoint = &SiS_YPbPrTable[i][0];
6646
6647 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6648
6649 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6650
6651 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6652
6653 } else {
6654
6655 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6656 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6657 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6658
6659 }
6660
6661 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6662 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6663 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6664 }
6665
6666 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6667 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6668 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6669 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6670 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6671 } else {
6672 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6673 }
6674 }
6675
6676 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6677 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6678 }
6679
6680 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6681 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6682 }
6683 for(i = 0x39; i <= 0x45; i++, j++) {
6684 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6685 }
6686
6687 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6688 if(SiS_Pr->SiS_ModeType != ModeText) {
6689 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6690 }
6691 }
6692
6693 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6694
6695 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6696 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6697 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6698 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6699
6700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6701 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6702 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6703 else tempax = 440; /* NTSC, YPbPr 525 */
6704
6705 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6706 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6707 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6708
6709 tempax -= SiS_Pr->SiS_VDE;
6710 tempax >>= 1;
6711 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6712 tempax >>= 1;
6713 }
6714 tempax &= 0x00ff;
6715
6716 temp = tempax + (unsigned short)TimingPoint[0];
6717 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6718
6719 temp = tempax + (unsigned short)TimingPoint[1];
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6721
6722 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6723 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6726 } else {
6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6728 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6729 }
6730 }
6731
6732 }
6733
6734 tempcx = SiS_Pr->SiS_HT;
6735 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6736 tempcx--;
6737 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6738 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6739 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6740
6741 tempcx = SiS_Pr->SiS_HT >> 1;
6742 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6743 tempcx += 7;
6744 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6745 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6746
6747 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6748 tempbx += tempcx;
6749 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6750 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6751
6752 tempbx += 8;
6753 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6754 tempbx -= 4;
6755 tempcx = tempbx;
6756 }
6757 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6758
6759 j += 2;
6760 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6761 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6762 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6763
6764 tempcx += 8;
6765 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6766 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6767
6768 tempcx = SiS_Pr->SiS_HT >> 1;
6769 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6770 j += 2;
6771 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6772 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6773
6774 tempcx -= 11;
6775 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6776 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6777 }
6778 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6779
6780 tempbx = SiS_Pr->SiS_VDE;
6781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6782 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6783 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6784 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6785 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6786 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6787 tempbx >>= 1;
6788 if(SiS_Pr->ChipType >= SIS_315H) {
6789 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6790 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6791 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6792 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6793 if(crt2crtc == 4) tempbx++;
6794 }
6795 }
6796 }
6797 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6798 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6799 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6800 }
6801 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6802 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6803 }
6804 }
6805 }
6806 tempbx -= 2;
6807 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6808
6809 temp = (tempcx >> 8) & 0x0F;
6810 temp |= ((tempbx >> 2) & 0xC0);
6811 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6812 temp |= 0x10;
6813 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6814 }
6815 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6816
6817 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6818 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6819 }
6820
6821 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6822 tempbx = SiS_Pr->SiS_VDE;
6823 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6824 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6825 tempbx >>= 1;
6826 }
6827 tempbx -= 3;
6828 temp = ((tempbx >> 3) & 0x60) | 0x18;
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6831
6832 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6833 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6834 }
6835 }
6836
6837 tempbx = 0;
6838 if(!(modeflag & HalfDCLK)) {
6839 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6840 tempax = 0;
6841 tempbx |= 0x20;
6842 }
6843 }
6844
6845 tempch = tempcl = 0x01;
6846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6847 if(SiS_Pr->SiS_VGAHDE >= 960) {
6848 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6849 tempcl = 0x20;
6850 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6851 tempch = 20;
6852 tempbx &= ~0x20;
6853 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6854 tempch = 25;
6855 } else {
6856 tempch = 25; /* OK */
6857 }
6858 }
6859 }
6860 }
6861
6862 if(!(tempbx & 0x20)) {
6863 if(modeflag & HalfDCLK) tempcl <<= 1;
6864 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6865 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6866 tempax = longtemp / SiS_Pr->SiS_HDE;
6867 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6868 tempbx |= ((tempax >> 8) & 0x1F);
6869 tempcx = tempax >> 13;
6870 }
6871
6872 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6873 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6874
6875 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6876
6877 tempcx &= 0x07;
6878 if(tempbx & 0x20) tempcx = 0;
6879 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6880
6881 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6882 tempbx = 0x0382;
6883 tempcx = 0x007e;
6884 } else {
6885 tempbx = 0x0369;
6886 tempcx = 0x0061;
6887 }
6888 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6889 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6890 temp = (tempcx & 0x0300) >> 6;
6891 temp |= ((tempbx >> 8) & 0x03);
6892 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6893 temp |= 0x10;
6894 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6895 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6896 }
6897 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6898
6899 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6900 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6901
6902 SiS_SetTVSpecial(SiS_Pr, ModeNo);
6903
6904 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6905 temp = 0;
6906 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6907 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6908 }
6909
6910 }
6911
6912 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6913 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6914 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6915 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6916 }
6917 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6918 }
6919
6920 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6921 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6922 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6923 }
6924 }
6925
6926 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6927
6928 /* From here: Part2 LCD setup */
6929
6930 tempbx = SiS_Pr->SiS_HDE;
6931 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6932 tempbx--; /* RHACTE = HDE - 1 */
6933 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6934 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6935
6936 temp = 0x01;
6937 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6938 if(SiS_Pr->SiS_ModeType == ModeEGA) {
6939 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6940 temp = 0x02;
6941 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6942 temp = 0x01;
6943 }
6944 }
6945 }
6946 }
6947 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6948
6949 tempbx = SiS_Pr->SiS_VDE - 1;
6950 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6951 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6952
6953 tempcx = SiS_Pr->SiS_VT - 1;
6954 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6955 temp = (tempcx >> 3) & 0xE0;
6956 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6957 /* Enable dithering; only do this for 32bpp mode */
6958 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6959 temp |= 0x10;
6960 }
6961 }
6962 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6963
6964 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6965 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6966
6967 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6968 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6969
6970#ifdef CONFIG_FB_SIS_315
6971 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6972 &CRT2Index, &resindex)) {
6973 switch(CRT2Index) {
6974 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
6975 default:
6976 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
6977 }
6978
6979 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6980 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6981 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6982 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6983 }
6984 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6985 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6986 }
6987 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6988 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6989 }
6990 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6991 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6992
6993 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
6994
6995 } else {
6996#endif
6997
6998 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
6999 /* Clevo dual-link 1024x768 */
7000 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7001 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7002
7003 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7004 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7005 tempbx = SiS_Pr->SiS_VDE - 1;
7006 tempcx = SiS_Pr->SiS_VT - 1;
7007 } else {
7008 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7009 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7010 }
7011 } else {
7012 tempbx = SiS_Pr->PanelYRes;
7013 tempcx = SiS_Pr->SiS_VT;
7014 tempax = 1;
7015 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7016 tempax = SiS_Pr->PanelYRes;
7017 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7018 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7019 tempax = tempcx = 0;
7020 } else {
7021 tempax -= SiS_Pr->SiS_VDE;
7022 }
7023 tempax >>= 1;
7024 }
7025 tempcx -= tempax; /* lcdvdes */
7026 tempbx -= tempax; /* lcdvdee */
7027 }
7028
7029 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7030
7031 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7032 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7033
7034 temp = (tempbx >> 5) & 0x38;
7035 temp |= ((tempcx >> 8) & 0x07);
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7037
7038 tempax = SiS_Pr->SiS_VDE;
7039 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7040 tempax = SiS_Pr->PanelYRes;
7041 }
7042 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7043 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7044 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7045 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7046 }
7047 }
7048
7049 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7050 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7051 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7052 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7053 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7054 if(tempax % 4) { tempax >>= 2; tempax++; }
7055 else { tempax >>= 2; }
7056 tempbx -= (tempax - 1);
7057 } else {
7058 tempbx -= 10;
7059 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7060 }
7061 }
7062 }
7063 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7064 tempbx++;
7065 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7066 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7067 tempbx = 770;
7068 tempcx = 3;
7069 }
7070 }
7071 }
7072
7073 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7074
7075 if(SiS_Pr->UseCustomMode) {
7076 tempbx = SiS_Pr->CVSyncStart;
7077 }
7078
7079 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7080
7081 temp = (tempbx >> 4) & 0xF0;
7082 tempbx += (tempcx + 1);
7083 temp |= (tempbx & 0x0F);
7084
7085 if(SiS_Pr->UseCustomMode) {
7086 temp &= 0xf0;
7087 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7088 }
7089
7090 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7091
7092#ifdef CONFIG_FB_SIS_300
7093 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7094#endif
7095
7096 bridgeoffset = 7;
7097 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7098 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7099 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7100 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7101 /* Higher bridgeoffset shifts to the LEFT */
7102
7103 temp = 0;
7104 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7105 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7106 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7107 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7108 }
7109 }
7110 temp += bridgeoffset;
7111 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7112 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7113
7114 tempcx = SiS_Pr->SiS_HT;
7115 tempax = tempbx = SiS_Pr->SiS_HDE;
7116 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7117 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7118 tempax = SiS_Pr->PanelXRes;
7119 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7120 }
7121 }
7122 if(SiS_IsDualLink(SiS_Pr)) {
7123 tempcx >>= 1;
7124 tempbx >>= 1;
7125 tempax >>= 1;
7126 }
7127
7128 tempbx += bridgeoffset;
7129
7130 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7131 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7132
7133 tempcx = (tempcx - tempax) >> 2;
7134
7135 tempbx += tempcx;
7136 push2 = tempbx;
7137
7138 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7139 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7140 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7141 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7142 }
7143 }
7144 }
7145
7146 if(SiS_Pr->UseCustomMode) {
7147 tempbx = SiS_Pr->CHSyncStart;
7148 if(modeflag & HalfDCLK) tempbx <<= 1;
7149 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7150 tempbx += bridgeoffset;
7151 }
7152
7153 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7154 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7155
7156 tempbx = push2;
7157
7158 tempcx <<= 1;
7159 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7160 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7161 }
7162 tempbx += tempcx;
7163
7164 if(SiS_Pr->UseCustomMode) {
7165 tempbx = SiS_Pr->CHSyncEnd;
7166 if(modeflag & HalfDCLK) tempbx <<= 1;
7167 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7168 tempbx += bridgeoffset;
7169 }
7170
7171 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7172
7173 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7174
7175#ifdef CONFIG_FB_SIS_300
7176 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7177#endif
7178#ifdef CONFIG_FB_SIS_315
7179 } /* CRT2-LCD from table */
7180#endif
7181}
7182
7183/*********************************************/
7184/* SET PART 3 REGISTER GROUP */
7185/*********************************************/
7186
7187static void
7188SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7189{
7190 unsigned short i;
7191 const unsigned char *tempdi;
7192
7193 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7194
7195#ifndef SIS_CP
7196 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7197#else
7198 SIS_CP_INIT301_CP
7199#endif
7200
7201 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7202 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7203 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7204 } else {
7205 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7206 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7207 }
7208
7209 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7210 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7211 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7212 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7213 }
7214
7215 tempdi = NULL;
7216 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7217 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7218 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7219 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7220 }
7221 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7222 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7223 tempdi = SiS_HiTVGroup3_1;
7224 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7225 }
7226 }
7227 if(tempdi) {
7228 for(i=0; i<=0x3E; i++) {
7229 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7230 }
7231 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7232 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7233 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7234 }
7235 }
7236 }
7237
7238#ifdef SIS_CP
7239 SIS_CP_INIT301_CP2
7240#endif
7241}
7242
7243/*********************************************/
7244/* SET PART 4 REGISTER GROUP */
7245/*********************************************/
7246
7247#ifdef CONFIG_FB_SIS_315
7248#if 0
7249static void
7250SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7251{
7252 unsigned short temp, temp1, temp2;
7253
7254 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7255 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7256 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7257 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7258 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7259 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7260 temp = (unsigned short)((int)(temp) + shift);
7261 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7262 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7263 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7264 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7265 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7266 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7267}
7268#endif
7269
7270static void
7271SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7272{
7273 unsigned short temp, temp1, resinfo = 0;
7274 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7275
7276 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7277 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7278
7279 if(SiS_Pr->ChipType >= XGI_20) return;
7280
7281 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7282 if(!(ROMAddr[0x61] & 0x04)) return;
7283 }
7284
7285 if(ModeNo > 0x13) {
7286 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7287 }
7288
7289 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7290 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7291 if(!(temp & 0x01)) {
7292 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7293 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7294 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7295 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7296 }
7297 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7298 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7299 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7300 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7301 else temp = 0x0402;
7302 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7303 temp1 = 0;
7304 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7305 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7306 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7307 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7308 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7309 if(ModeNo > 0x13) {
7310 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7311 }
7312 } else {
7313 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7314 if(temp1 == 0x01) temp |= 0x01;
7315 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7316 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7317 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7318 if(ModeNo > 0x13) {
7319 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7320 }
7321 }
7322
7323#if 0
7324 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7325 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7326 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7327 if(resinfo == SIS_RI_1024x768) {
7328 SiS_ShiftXPos(SiS_Pr, 97);
7329 } else {
7330 SiS_ShiftXPos(SiS_Pr, 111);
7331 }
7332 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7333 SiS_ShiftXPos(SiS_Pr, 136);
7334 }
7335 }
7336 }
7337#endif
7338
7339 }
7340
7341}
7342#endif
7343
7344static void
7345SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7346 unsigned short RefreshRateTableIndex)
7347{
7348 unsigned short vclkindex, temp, reg1, reg2;
7349
7350 if(SiS_Pr->UseCustomMode) {
7351 reg1 = SiS_Pr->CSR2B;
7352 reg2 = SiS_Pr->CSR2C;
7353 } else {
7354 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7355 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7356 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7357 }
7358
7359 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7360 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7361 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7362 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7363 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7364 } else {
7365 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7366 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7367 }
7368 } else {
7369 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7370 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7371 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7372 }
7373 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7374 temp = 0x08;
7375 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7376 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7377}
7378
7379static void
7380SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7381{
7382 if(SiS_Pr->ChipType >= SIS_315H) {
7383 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7384 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7385 (SiS_IsVAMode(SiS_Pr))) {
7386 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7387 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7388 } else {
7389 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7390 }
7391 }
7392 }
7393 }
7394 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7395 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7396#ifdef SET_EMI
7397 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7398#endif
7399 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7400 }
7401}
7402
7403static void
7404SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7405 unsigned short RefreshRateTableIndex)
7406{
7407 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7408 unsigned int tempebx, tempeax, templong;
7409
7410 if(ModeNo <= 0x13) {
7411 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7412 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7413 } else if(SiS_Pr->UseCustomMode) {
7414 modeflag = SiS_Pr->CModeFlag;
7415 resinfo = 0;
7416 } else {
7417 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7418 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7419 }
7420
7421 if(SiS_Pr->ChipType >= SIS_315H) {
7422 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7423 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7424 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7425 }
7426 }
7427 }
7428
7429 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7430 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7431 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7432 }
7433 }
7434
7435 if(SiS_Pr->ChipType >= SIS_315H) {
7436 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7437 SiS_SetDualLinkEtc(SiS_Pr);
7438 return;
7439 }
7440 }
7441
7442 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7443
7444 tempbx = SiS_Pr->SiS_RVBHCMAX;
7445 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7446
7447 temp = (tempbx >> 1) & 0x80;
7448
7449 tempcx = SiS_Pr->SiS_VGAHT - 1;
7450 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7451
7452 temp |= ((tempcx >> 5) & 0x78);
7453
7454 tempcx = SiS_Pr->SiS_VGAVT - 1;
7455 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7456 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7457
7458 temp |= ((tempcx >> 8) & 0x07);
7459 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7460
7461 tempbx = SiS_Pr->SiS_VGAHDE;
7462 if(modeflag & HalfDCLK) tempbx >>= 1;
7463 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7464
7465 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7466 temp = 0;
7467 if(tempbx > 800) temp = 0x60;
7468 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7469 temp = 0;
7470 if(tempbx > 1024) temp = 0xC0;
7471 else if(tempbx >= 960) temp = 0xA0;
7472 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7473 temp = 0;
7474 if(tempbx >= 1280) temp = 0x40;
7475 else if(tempbx >= 1024) temp = 0x20;
7476 } else {
7477 temp = 0x80;
7478 if(tempbx >= 1024) temp = 0xA0;
7479 }
7480
7481 temp |= SiS_Pr->Init_P4_0E;
7482
7483 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7484 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7485 temp &= 0xf0;
7486 temp |= 0x0A;
7487 }
7488 }
7489
7490 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7491
7492 tempeax = SiS_Pr->SiS_VGAVDE;
7493 tempebx = SiS_Pr->SiS_VDE;
7494 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7495 if(!(temp & 0xE0)) tempebx >>=1;
7496 }
7497
7498 tempcx = SiS_Pr->SiS_RVBHRS;
7499 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7500 tempcx >>= 8;
7501 tempcx |= 0x40;
7502
7503 if(tempeax <= tempebx) {
7504 tempcx ^= 0x40;
7505 } else {
7506 tempeax -= tempebx;
7507 }
7508
7509 tempeax *= (256 * 1024);
7510 templong = tempeax % tempebx;
7511 tempeax /= tempebx;
7512 if(templong) tempeax++;
7513
7514 temp = (unsigned short)(tempeax & 0x000000FF);
7515 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7516 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7517 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7518 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7519 temp |= (tempcx & 0x4F);
7520 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7521
7522 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7523
7524 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7525
7526 /* Calc Linebuffer max address and set/clear decimode */
7527 tempbx = 0;
7528 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7529 tempax = SiS_Pr->SiS_VGAHDE;
7530 if(modeflag & HalfDCLK) tempax >>= 1;
7531 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7532 if(tempax > 800) {
7533 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7534 tempax -= 800;
7535 } else {
7536 tempbx = 0x08;
7537 if(tempax == 960) tempax *= 25; /* Correct */
7538 else if(tempax == 1024) tempax *= 25;
7539 else tempax *= 20;
7540 temp = tempax % 32;
7541 tempax /= 32;
7542 if(temp) tempax++;
7543 tempax++;
7544 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7545 if(resinfo == SIS_RI_1024x768 ||
7546 resinfo == SIS_RI_1024x576 ||
7547 resinfo == SIS_RI_1280x1024 ||
7548 resinfo == SIS_RI_1280x720) {
7549 /* Otherwise white line or garbage at right edge */
7550 tempax = (tempax & 0xff00) | 0x20;
7551 }
7552 }
7553 }
7554 }
7555 tempax--;
7556 temp = ((tempax >> 4) & 0x30) | tempbx;
7557 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7558 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7559
7560 temp = 0x0036; tempbx = 0xD0;
7561 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7562 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7563 }
7564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7565 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7566 temp |= 0x01;
7567 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7568 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7569 temp &= ~0x01;
7570 }
7571 }
7572 }
7573 }
7574 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7575
7576 tempbx = SiS_Pr->SiS_HT >> 1;
7577 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7578 tempbx -= 2;
7579 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7580 temp = (tempbx >> 5) & 0x38;
7581 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7582
7583 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7585 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7586 /* LCD-too-dark-error-source, see FinalizeLCD() */
7587 }
7588 }
7589
7590 SiS_SetDualLinkEtc(SiS_Pr);
7591
7592 } /* 301B */
7593
7594 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7595}
7596
7597/*********************************************/
7598/* SET PART 5 REGISTER GROUP */
7599/*********************************************/
7600
7601static void
7602SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7603{
7604
7605 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7606
7607 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7608 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7609 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7610 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7611 }
7612 }
7613}
7614
7615/*********************************************/
7616/* MODIFY CRT1 GROUP FOR SLAVE MODE */
7617/*********************************************/
7618
7619static bool
7620SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7621 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7622 unsigned short *DisplayType)
7623 {
7624 unsigned short modeflag = 0;
7625 bool checkhd = true;
7626
7627 /* Pass 1:1 not supported here */
7628
7629 if(ModeNo <= 0x13) {
7630 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7631 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7632 } else {
7633 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7634 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7635 }
7636
7637 (*ResIndex) &= 0x3F;
7638
7639 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7640
7641 (*DisplayType) = 80;
7642 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7643 (*DisplayType) = 82;
7644 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7645 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7646 }
7647 }
7648 if((*DisplayType) != 84) {
7649 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7650 }
7651
7652 } else {
7653
7654 (*DisplayType = 0);
7655 switch(SiS_Pr->SiS_LCDResInfo) {
7656 case Panel_320x240_1: (*DisplayType) = 50;
7657 checkhd = false;
7658 break;
7659 case Panel_320x240_2: (*DisplayType) = 14;
7660 break;
7661 case Panel_320x240_3: (*DisplayType) = 18;
7662 break;
7663 case Panel_640x480: (*DisplayType) = 10;
7664 break;
7665 case Panel_1024x600: (*DisplayType) = 26;
7666 break;
7667 default: return true;
7668 }
7669
7670 if(checkhd) {
7671 if(modeflag & HalfDCLK) (*DisplayType)++;
7672 }
7673
7674 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7675 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7676 }
7677
7678 }
7679
7680 return true;
7681}
7682
7683static void
7684SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7685 unsigned short RefreshRateTableIndex)
7686{
7687 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7688 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7689 static const unsigned short CRIdx[] = {
7690 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7691 0x07, 0x10, 0x11, 0x15, 0x16
7692 };
7693
7694 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7695 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7696 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7697 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7698 return;
7699
7700 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7701 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7702 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7703 }
7704 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7705 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7706 } else return;
7707
7708 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7709
7710 if(SiS_Pr->ChipType < SIS_315H) {
7711 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7712 }
7713
7714 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7715 &ResIndex, &DisplayType))) {
7716 return;
7717 }
7718
7719 switch(DisplayType) {
7720 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7721 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7722 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7723 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7724 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7725 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7726 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7727#if 0 /* Works better with calculated numbers */
7728 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7729 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7730 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7731 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7732#endif
7733 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7734 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7735 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7736 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7737 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7738 }
7739
7740 if(LVDSCRT1Ptr) {
7741
7742 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7743
7744 for(i = 0; i <= 10; i++) {
7745 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7746 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7747 }
7748
7749 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7750 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7751 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7752 }
7753
7754 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7755 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7756
7757 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7758 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7759
7760 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7761 if(modeflag & DoubleScanMode) tempah |= 0x80;
7762 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7763
7764 } else {
7765
7766 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7767
7768 }
7769}
7770
7771/*********************************************/
7772/* SET CRT2 ECLK */
7773/*********************************************/
7774
7775static void
7776SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7777 unsigned short RefreshRateTableIndex)
7778{
7779 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7780 unsigned short clkbase, vclkindex = 0;
7781 unsigned char sr2b, sr2c;
7782
7783 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7784 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7785 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7786 RefreshRateTableIndex--;
7787 }
7788 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7789 RefreshRateTableIndex);
7790 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7791 } else {
7792 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7793 RefreshRateTableIndex);
7794 }
7795
7796 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7797 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7798
7799 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7800 if(SiS_Pr->SiS_UseROM) {
7801 if(ROMAddr[0x220] & 0x01) {
7802 sr2b = ROMAddr[0x227];
7803 sr2c = ROMAddr[0x228];
7804 }
7805 }
7806 }
7807
7808 clkbase = 0x02B;
7809 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7810 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7811 clkbase += 3;
7812 }
7813 }
7814
7815 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7816 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7817 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7818 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7819 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7820 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7821 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7822 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7823 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7824}
7825
7826/*********************************************/
7827/* SET UP CHRONTEL CHIPS */
7828/*********************************************/
7829
7830static void
7831SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7832 unsigned short RefreshRateTableIndex)
7833{
7834 unsigned short TVType, resindex;
7835 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7836
7837 if(ModeNo <= 0x13)
7838 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7839 else
7840 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7841
7842 resindex &= 0x3F;
7843
7844 TVType = 0;
7845 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7846 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7847 TVType += 2;
7848 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7849 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7850 }
7851 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7852 TVType = 4;
7853 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7854 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7855 TVType = 6;
7856 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7857 }
7858 }
7859
7860 switch(TVType) {
7861 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7862 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7863 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7864 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7865 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7866 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7867 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7868 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7869 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7870 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7871 }
7872
7873
7874 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7875
7876#ifdef CONFIG_FB_SIS_300
7877
7878 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7879
7880 /* We don't support modes >800x600 */
7881 if (resindex > 5) return;
7882
7883 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7884 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7885 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
7886 } else {
7887 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7888 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
7889 }
7890
7891 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
7892 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
7893 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
7894 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
7895 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
7896
7897 /* Set minimum flicker filter for Luma channel (SR1-0=00),
7898 minimum text enhancement (S3-2=10),
7899 maximum flicker filter for Chroma channel (S5-4=10)
7900 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7901 */
7902 SiS_SetCH700x(SiS_Pr,0x01,0x28);
7903
7904 /* Set video bandwidth
7905 High bandwidth Luma composite video filter(S0=1)
7906 low bandwidth Luma S-video filter (S2-1=00)
7907 disable peak filter in S-video channel (S3=0)
7908 high bandwidth Chroma Filter (S5-4=11)
7909 =00110001=0x31
7910 */
7911 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
7912
7913 /* Register 0x3D does not exist in non-macrovision register map
7914 (Maybe this is a macrovision register?)
7915 */
7916#ifndef SIS_CP
7917 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7918#endif
7919
7920 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7921 all other bits a read-only. Macrovision?
7922 */
7923 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7924
7925 /* Register 0x11 only contains 3 writable bits (S0-S2) for
7926 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7927 */
7928 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7929
7930 /* Clear DSEN
7931 */
7932 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7933
7934 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
7935 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7936 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
7937 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7938 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
7939 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
7940 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
7941 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7942 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7943 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7944 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7945 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7946 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7947 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7948 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
7949 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
7950 }
7951 } else {
7952 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
7953 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7954 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7955 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
7956#if 0
7957 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7958 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
7959 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
7960 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7961 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7962 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7963 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7964 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7965 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
7966 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
7967#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7968 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7969 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7970 }
7971 }
7972 } else { /* ---- PAL ---- */
7973 /* We don't play around with FSCI in PAL mode */
7974 if(resindex == 0x04) {
7975 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7976 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
7977 } else {
7978 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
7979 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
7980 }
7981 }
7982
7983#endif /* 300 */
7984
7985 } else {
7986
7987 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
7988
7989#ifdef CONFIG_FB_SIS_315
7990
7991 unsigned short temp;
7992
7993 /* We don't support modes >1024x768 */
7994 if (resindex > 6) return;
7995
7996 temp = CHTVRegData[resindex].Reg[0];
7997 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
7998 SiS_SetCH701x(SiS_Pr,0x00,temp);
7999
8000 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8001 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8002 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8003 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8004 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8005 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8006
8007 temp = CHTVRegData[resindex].Reg[7];
8008 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8009 SiS_SetCH701x(SiS_Pr,0x07,temp);
8010
8011 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8012 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8013 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8014 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8015 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8016 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8017 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8018 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8019
8020 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8021 /* D1 should be set for PAL, PAL-N and NTSC-J,
8022 but I won't do that for PAL unless somebody
8023 tells me to do so. Since the BIOS uses
8024 non-default CIV values and blacklevels,
8025 this might be compensated anyway.
8026 */
8027 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8028 SiS_SetCH701x(SiS_Pr,0x21,temp);
8029
8030#endif /* 315 */
8031
8032 }
8033
8034#ifdef SIS_CP
8035 SIS_CP_INIT301_CP3
8036#endif
8037
8038}
8039
8040#ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8041
8042void
8043SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8044{
8045 unsigned short temp;
8046
8047 /* Enable Chrontel 7019 LCD panel backlight */
8048 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8049 if(SiS_Pr->ChipType == SIS_740) {
8050 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8051 } else {
8052 temp = SiS_GetCH701x(SiS_Pr,0x66);
8053 temp |= 0x20;
8054 SiS_SetCH701x(SiS_Pr,0x66,temp);
8055 }
8056 }
8057}
8058
8059void
8060SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8061{
8062 unsigned short temp;
8063
8064 /* Disable Chrontel 7019 LCD panel backlight */
8065 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8066 temp = SiS_GetCH701x(SiS_Pr,0x66);
8067 temp &= 0xDF;
8068 SiS_SetCH701x(SiS_Pr,0x66,temp);
8069 }
8070}
8071
8072static void
8073SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8074{
8075 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8076 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8077 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8078 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8079 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8080 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8081 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8082 const unsigned char *tableptr = NULL;
8083 int i;
8084
8085 /* Set up Power up/down timing */
8086
8087 if(SiS_Pr->ChipType == SIS_740) {
8088 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8089 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8090 else tableptr = table1024_740;
8091 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8092 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8093 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8094 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8095 else tableptr = table1400_740;
8096 } else return;
8097 } else {
8098 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8099 tableptr = table1024_650;
8100 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8101 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8102 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8103 tableptr = table1400_650;
8104 } else return;
8105 }
8106
8107 for(i=0; i<5; i++) {
8108 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8109 }
8110}
8111
8112static void
8113SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8114{
8115 const unsigned char *tableptr = NULL;
8116 unsigned short tempbh;
8117 int i;
8118 static const unsigned char regtable[] = {
8119 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8120 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8121 };
8122 static const unsigned char table1024_740[] = {
8123 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8124 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8125 };
8126 static const unsigned char table1280_740[] = {
8127 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8128 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8129 };
8130 static const unsigned char table1400_740[] = {
8131 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8132 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8133 };
8134 static const unsigned char table1600_740[] = {
8135 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8136 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8137 };
8138 static const unsigned char table1024_650[] = {
8139 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8140 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8141 };
8142 static const unsigned char table1280_650[] = {
8143 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8144 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8145 };
8146 static const unsigned char table1400_650[] = {
8147 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8148 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8149 };
8150 static const unsigned char table1600_650[] = {
8151 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8152 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8153 };
8154
8155 if(SiS_Pr->ChipType == SIS_740) {
8156 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8157 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8158 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8159 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8160 else return;
8161 } else {
8162 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8163 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8164 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8165 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8166 else return;
8167 }
8168
8169 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8170 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8171 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8172 if(tempbh == 0xc8) {
8173 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8174 } else if(tempbh == 0xdb) {
8175 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8176 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8177 } else if(tempbh == 0xde) {
8178 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8179 }
8180 }
8181
8182 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8183 else tempbh = 0x0c;
8184
8185 for(i = 0; i < tempbh; i++) {
8186 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8187 }
8188 SiS_ChrontelPowerSequencing(SiS_Pr);
8189 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8190 tempbh |= 0xc0;
8191 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8192
8193 if(SiS_Pr->ChipType == SIS_740) {
8194 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8195 tempbh &= 0xfb;
8196 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8198 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8199 tempbh |= 0x40;
8200 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8201 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8202 tempbh &= 0x3f;
8203 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8204 }
8205}
8206
8207static void
8208SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8209{
8210 unsigned char temp, temp1;
8211
8212 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8213 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8214 temp = SiS_GetCH701x(SiS_Pr,0x47);
8215 temp &= 0x7f; /* Use external VSYNC */
8216 SiS_SetCH701x(SiS_Pr,0x47,temp);
8217 SiS_LongDelay(SiS_Pr, 3);
8218 temp = SiS_GetCH701x(SiS_Pr,0x47);
8219 temp |= 0x80; /* Use internal VSYNC */
8220 SiS_SetCH701x(SiS_Pr,0x47,temp);
8221 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8222}
8223
8224static void
8225SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8226{
8227 unsigned short temp;
8228
8229 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8230 if(SiS_Pr->ChipType == SIS_740) {
8231 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8232 temp |= 0x04; /* Invert XCLK phase */
8233 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8234 }
8235 if(SiS_IsYPbPr(SiS_Pr)) {
8236 temp = SiS_GetCH701x(SiS_Pr,0x01);
8237 temp &= 0x3f;
8238 temp |= 0x80; /* Enable YPrPb (HDTV) */
8239 SiS_SetCH701x(SiS_Pr,0x01,temp);
8240 }
8241 if(SiS_IsChScart(SiS_Pr)) {
8242 temp = SiS_GetCH701x(SiS_Pr,0x01);
8243 temp &= 0x3f;
8244 temp |= 0xc0; /* Enable SCART + CVBS */
8245 SiS_SetCH701x(SiS_Pr,0x01,temp);
8246 }
8247 if(SiS_Pr->ChipType == SIS_740) {
8248 SiS_ChrontelResetVSync(SiS_Pr);
8249 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8250 } else {
8251 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8252 temp = SiS_GetCH701x(SiS_Pr,0x49);
8253 if(SiS_IsYPbPr(SiS_Pr)) {
8254 temp = SiS_GetCH701x(SiS_Pr,0x73);
8255 temp |= 0x60;
8256 SiS_SetCH701x(SiS_Pr,0x73,temp);
8257 }
8258 temp = SiS_GetCH701x(SiS_Pr,0x47);
8259 temp &= 0x7f;
8260 SiS_SetCH701x(SiS_Pr,0x47,temp);
8261 SiS_LongDelay(SiS_Pr, 2);
8262 temp = SiS_GetCH701x(SiS_Pr,0x47);
8263 temp |= 0x80;
8264 SiS_SetCH701x(SiS_Pr,0x47,temp);
8265 }
8266 }
8267}
8268
8269static void
8270SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8271{
8272 unsigned short temp;
8273
8274 /* Complete power down of LVDS */
8275 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8276 if(SiS_Pr->ChipType == SIS_740) {
8277 SiS_LongDelay(SiS_Pr, 1);
8278 SiS_GenericDelay(SiS_Pr, 5887);
8279 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8280 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8281 } else {
8282 SiS_LongDelay(SiS_Pr, 2);
8283 temp = SiS_GetCH701x(SiS_Pr,0x76);
8284 temp &= 0xfc;
8285 SiS_SetCH701x(SiS_Pr,0x76,temp);
8286 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8287 }
8288 }
8289}
8290
8291static void
8292SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8293{
8294 unsigned short temp;
8295
8296 if(SiS_Pr->ChipType == SIS_740) {
8297
8298 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8299 temp &= 0x01;
8300 if(!temp) {
8301
8302 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8303 temp = SiS_GetCH701x(SiS_Pr,0x49);
8304 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8305 }
8306
8307 /* Reset Chrontel 7019 datapath */
8308 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8309 SiS_LongDelay(SiS_Pr, 1);
8310 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8311
8312 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8313 SiS_ChrontelResetVSync(SiS_Pr);
8314 SiS_SetCH701x(SiS_Pr,0x49,temp);
8315 }
8316
8317 } else {
8318
8319 /* Clear/set/clear GPIO */
8320 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8321 temp &= 0xef;
8322 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8323 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8324 temp |= 0x10;
8325 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8326 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8327 temp &= 0xef;
8328 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8329 temp = SiS_GetCH701x(SiS_Pr,0x61);
8330 if(!temp) {
8331 SiS_SetCH701xForLCD(SiS_Pr);
8332 }
8333 }
8334
8335 } else { /* 650 */
8336 /* Reset Chrontel 7019 datapath */
8337 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8338 SiS_LongDelay(SiS_Pr, 1);
8339 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8340 }
8341}
8342
8343static void
8344SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8345{
8346 unsigned short temp;
8347
8348 if(SiS_Pr->ChipType == SIS_740) {
8349
8350 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8351 SiS_ChrontelResetVSync(SiS_Pr);
8352 }
8353
8354 } else {
8355
8356 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8357 temp = SiS_GetCH701x(SiS_Pr,0x49);
8358 temp &= 1;
8359 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8360 temp = SiS_GetCH701x(SiS_Pr,0x47);
8361 temp &= 0x70;
8362 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8363 SiS_LongDelay(SiS_Pr, 3);
8364 temp = SiS_GetCH701x(SiS_Pr,0x47);
8365 temp |= 0x80;
8366 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8367 }
8368
8369 }
8370}
8371
8372static void
8373SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8374{
8375 unsigned short temp,temp1;
8376
8377 if(SiS_Pr->ChipType == SIS_740) {
8378
8379 temp = SiS_GetCH701x(SiS_Pr,0x61);
8380 if(temp < 1) {
8381 temp++;
8382 SiS_SetCH701x(SiS_Pr,0x61,temp);
8383 }
8384 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8385 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8386 SiS_LongDelay(SiS_Pr, 1);
8387 SiS_GenericDelay(SiS_Pr, 5887);
8388
8389 } else { /* 650 */
8390
8391 temp1 = 0;
8392 temp = SiS_GetCH701x(SiS_Pr,0x61);
8393 if(temp < 2) {
8394 temp++;
8395 SiS_SetCH701x(SiS_Pr,0x61,temp);
8396 temp1 = 1;
8397 }
8398 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8399 temp = SiS_GetCH701x(SiS_Pr,0x66);
8400 temp |= 0x5f;
8401 SiS_SetCH701x(SiS_Pr,0x66,temp);
8402 if(ModeNo > 0x13) {
8403 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8404 SiS_GenericDelay(SiS_Pr, 1023);
8405 } else {
8406 SiS_GenericDelay(SiS_Pr, 767);
8407 }
8408 } else {
8409 if(!temp1)
8410 SiS_GenericDelay(SiS_Pr, 767);
8411 }
8412 temp = SiS_GetCH701x(SiS_Pr,0x76);
8413 temp |= 0x03;
8414 SiS_SetCH701x(SiS_Pr,0x76,temp);
8415 temp = SiS_GetCH701x(SiS_Pr,0x66);
8416 temp &= 0x7f;
8417 SiS_SetCH701x(SiS_Pr,0x66,temp);
8418 SiS_LongDelay(SiS_Pr, 1);
8419
8420 }
8421}
8422
8423static void
8424SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8425{
8426 unsigned short temp;
8427
8428 SiS_LongDelay(SiS_Pr, 1);
8429
8430 do {
8431 temp = SiS_GetCH701x(SiS_Pr,0x66);
8432 temp &= 0x04; /* PLL stable? -> bail out */
8433 if(temp == 0x04) break;
8434
8435 if(SiS_Pr->ChipType == SIS_740) {
8436 /* Power down LVDS output, PLL normal operation */
8437 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8438 }
8439
8440 SiS_SetCH701xForLCD(SiS_Pr);
8441
8442 temp = SiS_GetCH701x(SiS_Pr,0x76);
8443 temp &= 0xfb; /* Reset PLL */
8444 SiS_SetCH701x(SiS_Pr,0x76,temp);
8445 SiS_LongDelay(SiS_Pr, 2);
8446 temp = SiS_GetCH701x(SiS_Pr,0x76);
8447 temp |= 0x04; /* PLL normal operation */
8448 SiS_SetCH701x(SiS_Pr,0x76,temp);
8449 if(SiS_Pr->ChipType == SIS_740) {
8450 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8451 } else {
8452 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8453 }
8454 SiS_LongDelay(SiS_Pr, 2);
8455 } while(0);
8456
8457 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8458}
8459
8460static void
8461SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8462{
8463 unsigned short temp;
8464
8465 temp = SiS_GetCH701x(SiS_Pr,0x03);
8466 temp |= 0x80; /* Set datapath 1 to TV */
8467 temp &= 0xbf; /* Set datapath 2 to LVDS */
8468 SiS_SetCH701x(SiS_Pr,0x03,temp);
8469
8470 if(SiS_Pr->ChipType == SIS_740) {
8471
8472 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8473 temp &= 0xfb; /* Normal XCLK phase */
8474 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8475
8476 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8477
8478 temp = SiS_GetCH701x(SiS_Pr,0x64);
8479 temp |= 0x40; /* ? Bit not defined */
8480 SiS_SetCH701x(SiS_Pr,0x64,temp);
8481
8482 temp = SiS_GetCH701x(SiS_Pr,0x03);
8483 temp &= 0x3f; /* D1 input to both LVDS and TV */
8484 SiS_SetCH701x(SiS_Pr,0x03,temp);
8485
8486 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8487 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8488 SiS_LongDelay(SiS_Pr, 1);
8489 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8490 SiS_ChrontelResetDB(SiS_Pr);
8491 SiS_ChrontelDoSomething2(SiS_Pr);
8492 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8493 } else {
8494 temp = SiS_GetCH701x(SiS_Pr,0x66);
8495 if(temp != 0x45) {
8496 SiS_ChrontelResetDB(SiS_Pr);
8497 SiS_ChrontelDoSomething2(SiS_Pr);
8498 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8499 }
8500 }
8501
8502 } else { /* 650 */
8503
8504 SiS_ChrontelResetDB(SiS_Pr);
8505 SiS_ChrontelDoSomething2(SiS_Pr);
8506 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8507 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8508 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8509
8510 }
8511
8512}
8513#endif /* 315 series */
8514
8515/*********************************************/
8516/* MAIN: SET CRT2 REGISTER GROUP */
8517/*********************************************/
8518
8519bool
8520SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8521{
8522#ifdef CONFIG_FB_SIS_300
8523 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8524#endif
8525 unsigned short ModeIdIndex, RefreshRateTableIndex;
8526
8527 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8528
8529 if(!SiS_Pr->UseCustomMode) {
8530 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8531 } else {
8532 ModeIdIndex = 0;
8533 }
8534
8535 /* Used for shifting CR33 */
8536 SiS_Pr->SiS_SelectCRT2Rate = 4;
8537
8538 SiS_UnLockCRT2(SiS_Pr);
8539
8540 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8541
8542 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8543
8544 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8545 SiS_DisableBridge(SiS_Pr);
8546 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8547 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8548 }
8549 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8550 }
8551
8552 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8553 SiS_LockCRT2(SiS_Pr);
8554 SiS_DisplayOn(SiS_Pr);
8555 return true;
8556 }
8557
8558 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8559
8560 /* Set up Panel Link for LVDS and LCDA */
8561 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8562 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8563 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8564 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8565 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8566 }
8567
8568 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8569 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8570 }
8571
8572 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8573
8574 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8575
8576 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8577#ifdef CONFIG_FB_SIS_315
8578 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8579#endif
8580 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8581 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8582#ifdef CONFIG_FB_SIS_315
8583 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8584#endif
8585 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8586
8587 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8588
8589 /* For 301BDH (Panel link initialization): */
8590 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8591
8592 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8593 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8594 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8595 }
8596 }
8597 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8598 }
8599 }
8600
8601 } else {
8602
8603 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8604
8605 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8606
8607 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8608
8609 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8610 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8611 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8612 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8613#ifdef CONFIG_FB_SIS_315
8614 SiS_SetCH701xForLCD(SiS_Pr);
8615#endif
8616 }
8617 }
8618 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8619 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8620 }
8621 }
8622 }
8623
8624 }
8625
8626#ifdef CONFIG_FB_SIS_300
8627 if(SiS_Pr->ChipType < SIS_315H) {
8628 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8629 if(SiS_Pr->SiS_UseOEM) {
8630 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8631 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8632 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8633 }
8634 } else {
8635 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8636 }
8637 }
8638 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8639 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8640 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8641 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8642 }
8643 SiS_DisplayOn(SiS_Pr);
8644 }
8645 }
8646 }
8647#endif
8648
8649#ifdef CONFIG_FB_SIS_315
8650 if(SiS_Pr->ChipType >= SIS_315H) {
8651 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8652 if(SiS_Pr->ChipType < SIS_661) {
8653 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8654 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8655 } else {
8656 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8657 }
8658 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8659 }
8660 }
8661#endif
8662
8663 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8664 SiS_EnableBridge(SiS_Pr);
8665 }
8666
8667 SiS_DisplayOn(SiS_Pr);
8668
8669 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8670 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8671 /* Disable LCD panel when using TV */
8672 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8673 } else {
8674 /* Disable TV when using LCD */
8675 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8676 }
8677 }
8678
8679 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8680 SiS_LockCRT2(SiS_Pr);
8681 }
8682
8683 return true;
8684}
8685
8686
8687/*********************************************/
8688/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8689/*********************************************/
8690
8691void
8692SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8693{
8694 /* Switch on LCD backlight on SiS30xLV */
8695 SiS_DDC2Delay(SiS_Pr,0xff00);
8696 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8697 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8698 SiS_WaitVBRetrace(SiS_Pr);
8699 }
8700 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8701 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8702 }
8703}
8704
8705void
8706SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8707{
8708 /* Switch off LCD backlight on SiS30xLV */
8709 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8710 SiS_DDC2Delay(SiS_Pr,0xff00);
8711}
8712
8713/*********************************************/
8714/* DDC RELATED FUNCTIONS */
8715/*********************************************/
8716
8717static void
8718SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8719{
8720 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8721 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8722 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8723 SiS_Pr->SiS_DDC_NData &= 0x0f;
8724 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8725 }
8726}
8727
8728#ifdef CONFIG_FB_SIS_300
8729static unsigned char *
8730SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8731{
8732 int i, j, num;
8733 unsigned short tempah,temp;
8734 unsigned char *mydataptr;
8735
8736 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8737 mydataptr = dataptr;
8738 num = *mydataptr++;
8739 if(!num) return mydataptr;
8740 if(i) {
8741 SiS_SetStop(SiS_Pr);
8742 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8743 }
8744 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8745 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8746 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8747 if(temp) continue; /* (ERROR: no ack) */
8748 tempah = *mydataptr++;
8749 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8750 if(temp) continue; /* (ERROR: no ack) */
8751 for(j=0; j<num; j++) {
8752 tempah = *mydataptr++;
8753 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8754 if(temp) break;
8755 }
8756 if(temp) continue;
8757 if(SiS_SetStop(SiS_Pr)) continue;
8758 return mydataptr;
8759 }
8760 return NULL;
8761}
8762
8763static bool
8764SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8765{
8766 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8767 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8768 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8769 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8770 SiS_SetupDDCN(SiS_Pr);
8771
8772 SiS_SetSwitchDDC2(SiS_Pr);
8773
8774 while(*dataptr) {
8775 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8776 if(!dataptr) return false;
8777 }
8778 return true;
8779}
8780#endif
8781
8782/* The Chrontel 700x is connected to the 630/730 via
8783 * the 630/730's DDC/I2C port.
8784 *
8785 * On 630(S)T chipset, the index changed from 0x11 to
8786 * 0x0a, possibly for working around the DDC problems
8787 */
8788
8789static bool
8790SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8791{
8792 unsigned short temp, i;
8793
8794 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8795 if(i) {
8796 SiS_SetStop(SiS_Pr);
8797 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8798 }
8799 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8800 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8801 if(temp) continue; /* (ERROR: no ack) */
8802 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8803 if(temp) continue; /* (ERROR: no ack) */
8804 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8805 if(temp) continue; /* (ERROR: no ack) */
8806 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8807 SiS_Pr->SiS_ChrontelInit = 1;
8808 return true;
8809 }
8810 return false;
8811}
8812
8813/* Write to Chrontel 700x */
8814void
8815SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8816{
8817 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8818
8819 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8820
8821 if(!(SiS_Pr->SiS_ChrontelInit)) {
8822 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8823 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8824 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8825 SiS_SetupDDCN(SiS_Pr);
8826 }
8827
8828 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8829 (!(SiS_Pr->SiS_ChrontelInit)) ) {
8830 SiS_Pr->SiS_DDC_Index = 0x0a;
8831 SiS_Pr->SiS_DDC_Data = 0x80;
8832 SiS_Pr->SiS_DDC_Clk = 0x40;
8833 SiS_SetupDDCN(SiS_Pr);
8834
8835 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8836 }
8837}
8838
8839/* Write to Chrontel 701x */
8840/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8841void
8842SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8843{
8844 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8845 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8846 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8847 SiS_SetupDDCN(SiS_Pr);
8848 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
8849 SiS_SetChReg(SiS_Pr, reg, val, 0);
8850}
8851
8852static
8853void
8854SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8855{
8856 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8857 SiS_SetCH700x(SiS_Pr, reg, val);
8858 else
8859 SiS_SetCH701x(SiS_Pr, reg, val);
8860}
8861
8862static unsigned short
8863SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8864{
8865 unsigned short tempah, temp, i;
8866
8867 for(i=0; i<20; i++) { /* Do 20 attempts to read */
8868 if(i) {
8869 SiS_SetStop(SiS_Pr);
8870 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8871 }
8872 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8873 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8874 if(temp) continue; /* (ERROR: no ack) */
8875 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
8876 if(temp) continue; /* (ERROR: no ack) */
8877 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
8878 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8879 if(temp) continue; /* (ERROR: no ack) */
8880 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
8881 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
8882 SiS_Pr->SiS_ChrontelInit = 1;
8883 return tempah;
8884 }
8885 return 0xFFFF;
8886}
8887
8888/* Read from Chrontel 700x */
8889/* Parameter is [Register no (S7-S0)] */
8890unsigned short
8891SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8892{
8893 unsigned short result;
8894
8895 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8896
8897 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8898
8899 if(!(SiS_Pr->SiS_ChrontelInit)) {
8900 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8901 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8902 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8903 SiS_SetupDDCN(SiS_Pr);
8904 }
8905
8906 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8907
8908 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8909 (!SiS_Pr->SiS_ChrontelInit) ) {
8910
8911 SiS_Pr->SiS_DDC_Index = 0x0a;
8912 SiS_Pr->SiS_DDC_Data = 0x80;
8913 SiS_Pr->SiS_DDC_Clk = 0x40;
8914 SiS_SetupDDCN(SiS_Pr);
8915
8916 result = SiS_GetChReg(SiS_Pr,0x80);
8917 }
8918 return result;
8919}
8920
8921/* Read from Chrontel 701x */
8922/* Parameter is [Register no (S7-S0)] */
8923unsigned short
8924SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8925{
8926 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8927 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
8928 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
8929 SiS_SetupDDCN(SiS_Pr);
8930 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
8931
8932 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8933
8934 return SiS_GetChReg(SiS_Pr,0);
8935}
8936
8937/* Read from Chrontel 70xx */
8938/* Parameter is [Register no (S7-S0)] */
8939static
8940unsigned short
8941SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8942{
8943 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8944 return SiS_GetCH700x(SiS_Pr, tempbx);
8945 else
8946 return SiS_GetCH701x(SiS_Pr, tempbx);
8947}
8948
8949void
8950SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8951 unsigned char myor, unsigned short myand)
8952{
8953 unsigned short tempbl;
8954
8955 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8956 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8957}
8958
8959/* Our own DDC functions */
8960static
8961unsigned short
8962SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8963 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8964 unsigned int VBFlags2)
8965{
8966 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8967 unsigned char flag, cr32;
8968 unsigned short temp = 0, myadaptnum = adaptnum;
8969
8970 if(adaptnum != 0) {
8971 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8972 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
8973 }
8974
8975 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
8976
8977 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
8978
8979 SiS_Pr->SiS_DDC_SecAddr = 0;
8980 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
8981 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
8982 SiS_Pr->SiS_DDC_Index = 0x11;
8983 flag = 0xff;
8984
8985 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
8986
8987#if 0
8988 if(VBFlags2 & VB2_SISBRIDGE) {
8989 if(myadaptnum == 0) {
8990 if(!(cr32 & 0x20)) {
8991 myadaptnum = 2;
8992 if(!(cr32 & 0x10)) {
8993 myadaptnum = 1;
8994 if(!(cr32 & 0x08)) {
8995 myadaptnum = 0;
8996 }
8997 }
8998 }
8999 }
9000 }
9001#endif
9002
9003 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9004
9005 if(myadaptnum != 0) {
9006 flag = 0;
9007 if(VBFlags2 & VB2_SISBRIDGE) {
9008 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9009 SiS_Pr->SiS_DDC_Index = 0x0f;
9010 }
9011 }
9012
9013 if(!(VBFlags2 & VB2_301)) {
9014 if((cr32 & 0x80) && (checkcr32)) {
9015 if(myadaptnum >= 1) {
9016 if(!(cr32 & 0x08)) {
9017 myadaptnum = 1;
9018 if(!(cr32 & 0x10)) return 0xFFFF;
9019 }
9020 }
9021 }
9022 }
9023
9024 temp = 4 - (myadaptnum * 2);
9025 if(flag) temp = 0;
9026
9027 } else { /* 315/330 series */
9028
9029 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9030
9031 if(VBFlags2 & VB2_SISBRIDGE) {
9032 if(myadaptnum == 2) {
9033 myadaptnum = 1;
9034 }
9035 }
9036
9037 if(myadaptnum == 1) {
9038 flag = 0;
9039 if(VBFlags2 & VB2_SISBRIDGE) {
9040 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9041 SiS_Pr->SiS_DDC_Index = 0x0f;
9042 }
9043 }
9044
9045 if((cr32 & 0x80) && (checkcr32)) {
9046 if(myadaptnum >= 1) {
9047 if(!(cr32 & 0x08)) {
9048 myadaptnum = 1;
9049 if(!(cr32 & 0x10)) return 0xFFFF;
9050 }
9051 }
9052 }
9053
9054 temp = myadaptnum;
9055 if(myadaptnum == 1) {
9056 temp = 0;
9057 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9058 }
9059
9060 if(flag) temp = 0;
9061 }
9062
9063 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9064 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9065
9066 SiS_SetupDDCN(SiS_Pr);
9067
9068 return 0;
9069}
9070
9071static unsigned short
9072SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9073{
9074 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9075 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9076 return 0xFFFF;
9077 }
9078 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9079 return 0xFFFF;
9080 }
9081 return 0;
9082}
9083
9084static unsigned short
9085SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9086{
9087 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9088 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9089 return 0xFFFF;
9090 }
9091 return 0;
9092}
9093
9094static unsigned short
9095SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9096{
9097 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9098 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9099 return 0;
9100}
9101
9102static void
9103SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9104{
9105 SiS_SetSCLKLow(SiS_Pr);
9106 if(yesno) {
9107 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9108 SiS_Pr->SiS_DDC_Index,
9109 SiS_Pr->SiS_DDC_NData,
9110 SiS_Pr->SiS_DDC_Data);
9111 } else {
9112 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9113 SiS_Pr->SiS_DDC_Index,
9114 SiS_Pr->SiS_DDC_NData,
9115 0);
9116 }
9117 SiS_SetSCLKHigh(SiS_Pr);
9118}
9119
9120static unsigned short
9121SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9122{
9123 unsigned char mask, value;
9124 unsigned short temp, ret=0;
9125 bool failed = false;
9126
9127 SiS_SetSwitchDDC2(SiS_Pr);
9128 if(SiS_PrepareDDC(SiS_Pr)) {
9129 SiS_SetStop(SiS_Pr);
9130 return 0xFFFF;
9131 }
9132 mask = 0xf0;
9133 value = 0x20;
9134 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9135 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9136 SiS_SendACK(SiS_Pr, 0);
9137 if(temp == 0) {
9138 mask = 0xff;
9139 value = 0xff;
9140 } else {
9141 failed = true;
9142 ret = 0xFFFF;
9143 }
9144 }
9145 if(!failed) {
9146 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9147 SiS_SendACK(SiS_Pr, 1);
9148 temp &= mask;
9149 if(temp == value) ret = 0;
9150 else {
9151 ret = 0xFFFF;
9152 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9153 if(temp == 0x30) ret = 0;
9154 }
9155 }
9156 }
9157 SiS_SetStop(SiS_Pr);
9158 return ret;
9159}
9160
9161static
9162unsigned short
9163SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9164{
9165 unsigned short flag;
9166
9167 flag = 0x180;
9168 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9169 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9170 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9171 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9172 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9173 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9174 if(!(flag & 0x1a)) flag = 0;
9175 return flag;
9176}
9177
9178static
9179unsigned short
9180SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9181{
9182 unsigned short flag, length, i;
9183 unsigned char chksum,gotcha;
9184
9185 if(DDCdatatype > 4) return 0xFFFF;
9186
9187 flag = 0;
9188 SiS_SetSwitchDDC2(SiS_Pr);
9189 if(!(SiS_PrepareDDC(SiS_Pr))) {
9190 length = 127;
9191 if(DDCdatatype != 1) length = 255;
9192 chksum = 0;
9193 gotcha = 0;
9194 for(i=0; i<length; i++) {
9195 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9196 chksum += buffer[i];
9197 gotcha |= buffer[i];
9198 SiS_SendACK(SiS_Pr, 0);
9199 }
9200 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9201 chksum += buffer[i];
9202 SiS_SendACK(SiS_Pr, 1);
9203 if(gotcha) flag = (unsigned short)chksum;
9204 else flag = 0xFFFF;
9205 } else {
9206 flag = 0xFFFF;
9207 }
9208 SiS_SetStop(SiS_Pr);
9209 return flag;
9210}
9211
9212/* Our private DDC functions
9213
9214 It complies somewhat with the corresponding VESA function
9215 in arguments and return values.
9216
9217 Since this is probably called before the mode is changed,
9218 we use our pre-detected pSiS-values instead of SiS_Pr as
9219 regards chipset and video bridge type.
9220
9221 Arguments:
9222 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9223 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9224 LCDA is CRT1, but DDC is read from CRT2 port.
9225 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9226 buffer: ptr to 256 data bytes which will be filled with read data.
9227
9228 Returns 0xFFFF if error, otherwise
9229 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9230 if DDCdatatype = 0: Returns supported DDC modes
9231
9232 */
9233unsigned short
9234SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9235 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9236 unsigned int VBFlags2)
9237{
9238 unsigned char sr1f, cr17=1;
9239 unsigned short result;
9240
9241 if(adaptnum > 2)
9242 return 0xFFFF;
9243
9244 if(DDCdatatype > 4)
9245 return 0xFFFF;
9246
9247 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9248 return 0xFFFF;
9249
9250 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9251 return 0xFFFF;
9252
9253 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9254 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9255 if(VGAEngine == SIS_300_VGA) {
9256 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9257 if(!cr17) {
9258 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9259 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9260 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9261 }
9262 }
9263 if((sr1f) || (!cr17)) {
9264 SiS_WaitRetrace1(SiS_Pr);
9265 SiS_WaitRetrace1(SiS_Pr);
9266 SiS_WaitRetrace1(SiS_Pr);
9267 SiS_WaitRetrace1(SiS_Pr);
9268 }
9269
9270 if(DDCdatatype == 0) {
9271 result = SiS_ProbeDDC(SiS_Pr);
9272 } else {
9273 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9274 if((!result) && (DDCdatatype == 1)) {
9275 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9276 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9277 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9278 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9279 (buffer[0x12] == 1)) {
9280 if(!SiS_Pr->DDCPortMixup) {
9281 if(adaptnum == 1) {
9282 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9283 } else {
9284 if(buffer[0x14] & 0x80) result = 0xFFFE;
9285 }
9286 }
9287 }
9288 }
9289 }
9290 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9291 if(VGAEngine == SIS_300_VGA) {
9292 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9293 }
9294 return result;
9295}
9296
9297/* Generic I2C functions for Chrontel & DDC --------- */
9298
9299static void
9300SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9301{
9302 SiS_SetSCLKHigh(SiS_Pr);
9303 SiS_WaitRetrace1(SiS_Pr);
9304
9305 SiS_SetSCLKLow(SiS_Pr);
9306 SiS_WaitRetrace1(SiS_Pr);
9307}
9308
9309unsigned short
9310SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9311{
9312 SiS_WaitRetrace1(SiS_Pr);
9313 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9314}
9315
9316/* Set I2C start condition */
9317/* This is done by a SD high-to-low transition while SC is high */
9318static unsigned short
9319SiS_SetStart(struct SiS_Private *SiS_Pr)
9320{
9321 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9322 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9323 SiS_Pr->SiS_DDC_Index,
9324 SiS_Pr->SiS_DDC_NData,
9325 SiS_Pr->SiS_DDC_Data); /* SD->high */
9326 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9327 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9328 SiS_Pr->SiS_DDC_Index,
9329 SiS_Pr->SiS_DDC_NData,
9330 0x00); /* SD->low = start condition */
9331 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9332 return 0;
9333}
9334
9335/* Set I2C stop condition */
9336/* This is done by a SD low-to-high transition while SC is high */
9337static unsigned short
9338SiS_SetStop(struct SiS_Private *SiS_Pr)
9339{
9340 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9341 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9342 SiS_Pr->SiS_DDC_Index,
9343 SiS_Pr->SiS_DDC_NData,
9344 0x00); /* SD->low */
9345 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9346 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9347 SiS_Pr->SiS_DDC_Index,
9348 SiS_Pr->SiS_DDC_NData,
9349 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9350 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9351 return 0;
9352}
9353
9354/* Write 8 bits of data */
9355static unsigned short
9356SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9357{
9358 unsigned short i,flag,temp;
9359
9360 flag = 0x80;
9361 for(i = 0; i < 8; i++) {
9362 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9363 if(tempax & flag) {
9364 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9365 SiS_Pr->SiS_DDC_Index,
9366 SiS_Pr->SiS_DDC_NData,
9367 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9368 } else {
9369 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9370 SiS_Pr->SiS_DDC_Index,
9371 SiS_Pr->SiS_DDC_NData,
9372 0x00); /* Write bit (0) to SD */
9373 }
9374 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9375 flag >>= 1;
9376 }
9377 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9378 return temp;
9379}
9380
9381static unsigned short
9382SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9383{
9384 unsigned short i, temp, getdata;
9385
9386 getdata = 0;
9387 for(i = 0; i < 8; i++) {
9388 getdata <<= 1;
9389 SiS_SetSCLKLow(SiS_Pr);
9390 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9391 SiS_Pr->SiS_DDC_Index,
9392 SiS_Pr->SiS_DDC_NData,
9393 SiS_Pr->SiS_DDC_Data);
9394 SiS_SetSCLKHigh(SiS_Pr);
9395 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9396 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9397 }
9398 return getdata;
9399}
9400
9401static unsigned short
9402SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9403{
9404 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9405 SiS_Pr->SiS_DDC_Index,
9406 SiS_Pr->SiS_DDC_NClk,
9407 0x00); /* SetSCLKLow() */
9408 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9409 return 0;
9410}
9411
9412static unsigned short
9413SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9414{
9415 unsigned short temp, watchdog=1000;
9416
9417 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418 SiS_Pr->SiS_DDC_Index,
9419 SiS_Pr->SiS_DDC_NClk,
9420 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9421 do {
9422 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9423 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9424 if (!watchdog) {
9425 return 0xFFFF;
9426 }
9427 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9428 return 0;
9429}
9430
9431/* Check I2C acknowledge */
9432/* Returns 0 if ack ok, non-0 if ack not ok */
9433static unsigned short
9434SiS_CheckACK(struct SiS_Private *SiS_Pr)
9435{
9436 unsigned short tempah;
9437
9438 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9439 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9440 SiS_Pr->SiS_DDC_Index,
9441 SiS_Pr->SiS_DDC_NData,
9442 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9443 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9444 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9445 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9446 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9447 return 0;
9448}
9449
9450/* End of I2C functions ----------------------- */
9451
9452
9453/* =============== SiS 315/330 O.E.M. ================= */
9454
9455#ifdef CONFIG_FB_SIS_315
9456
9457static unsigned short
9458GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9459{
9460 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9461 unsigned short romptr;
9462
9463 if(SiS_Pr->ChipType < SIS_330) {
9464 romptr = SISGETROMW(0x128);
9465 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9466 romptr = SISGETROMW(0x12a);
9467 } else {
9468 romptr = SISGETROMW(0x1a8);
9469 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9470 romptr = SISGETROMW(0x1aa);
9471 }
9472 return romptr;
9473}
9474
9475static unsigned short
9476GetLCDromptr(struct SiS_Private *SiS_Pr)
9477{
9478 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9479 unsigned short romptr;
9480
9481 if(SiS_Pr->ChipType < SIS_330) {
9482 romptr = SISGETROMW(0x120);
9483 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9484 romptr = SISGETROMW(0x122);
9485 } else {
9486 romptr = SISGETROMW(0x1a0);
9487 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9488 romptr = SISGETROMW(0x1a2);
9489 }
9490 return romptr;
9491}
9492
9493static unsigned short
9494GetTVromptr(struct SiS_Private *SiS_Pr)
9495{
9496 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9497 unsigned short romptr;
9498
9499 if(SiS_Pr->ChipType < SIS_330) {
9500 romptr = SISGETROMW(0x114);
9501 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9502 romptr = SISGETROMW(0x11a);
9503 } else {
9504 romptr = SISGETROMW(0x194);
9505 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9506 romptr = SISGETROMW(0x19a);
9507 }
9508 return romptr;
9509}
9510
9511static unsigned short
9512GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9513{
9514 unsigned short index;
9515
9516 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9517 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9518 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9519 index >>= 4;
9520 index *= 3;
9521 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9522 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9523 return index;
9524 }
9525 }
9526 }
9527
9528 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9529 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9530 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9531 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9532 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9533 } else {
9534 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9535 }
9536 index--;
9537 index *= 3;
9538 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9539 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9540 return index;
9541}
9542
9543static unsigned short
9544GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9545{
9546 unsigned short index;
9547
9548 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9549 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9550 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9551 return index;
9552}
9553
9554static unsigned short
9555GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9556{
9557 unsigned short index;
9558
9559 index = 0;
9560 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9561 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9562
9563 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9564
9565 index <<= 1;
9566
9567 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9568 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9569 index++;
9570 }
9571
9572 return index;
9573}
9574
9575static unsigned int
9576GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9577{
9578 unsigned short index = 0, temp = 0;
9579
9580 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9581 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9582 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9583 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9584 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9585 index = 4;
9586 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9587 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9588 }
9589
9590 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9591 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9592 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9593 index += addme;
9594 temp++;
9595 }
9596 temp += 0x0100;
9597 }
9598 return (unsigned int)(index | (temp << 16));
9599}
9600
9601static unsigned int
9602GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9603{
9604 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9605}
9606
9607#if 0
9608static unsigned int
9609GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9610{
9611 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9612}
9613#endif
9614
9615static int
9616GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9617{
9618 int index = 0;
9619
9620 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9621 if(SiS_Pr->SiS_ROMNew) {
9622 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9623 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9624 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9625 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9626 } else {
9627 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9628 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9629 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9630 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9631 }
9632
9633 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9634
9635 return index;
9636}
9637
9638static void
9639SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9640{
9641 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9642 unsigned short delay=0,index,myindex,temp,romptr=0;
9643 bool dochiptest = true;
9644
9645 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9646 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9647 } else {
9648 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9649 }
9650
9651 /* Find delay (from ROM, internal tables, PCI subsystem) */
9652
9653 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9654
9655 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9656 romptr = GetRAMDACromptr(SiS_Pr);
9657 }
9658 if(romptr) delay = ROMAddr[romptr];
9659 else {
9660 delay = 0x04;
9661 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9662 if(IS_SIS650) {
9663 delay = 0x0a;
9664 } else if(IS_SIS740) {
9665 delay = 0x00;
9666 } else if(SiS_Pr->ChipType < SIS_330) {
9667 delay = 0x0c;
9668 } else {
9669 delay = 0x0c;
9670 }
9671 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9672 delay = 0x00;
9673 }
9674 }
9675
9676 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9677
9678 bool gotitfrompci = false;
9679
9680 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9681
9682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9683 if(SiS_Pr->PDC != -1) {
9684 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9685 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9686 return;
9687 }
9688 } else {
9689 if(SiS_Pr->PDCA != -1) {
9690 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9691 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9692 return;
9693 }
9694 }
9695
9696 /* Custom Panel? */
9697
9698 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9699 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9700 delay = 0x00;
9701 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9702 delay = 0x20;
9703 }
9704 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9705 } else {
9706 delay = 0x0c;
9707 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9708 delay = 0x03;
9709 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9710 delay = 0x00;
9711 }
9712 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9713 if(IS_SIS740) delay = 0x01;
9714 else delay = 0x03;
9715 }
9716 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9717 }
9718 return;
9719 }
9720
9721 /* This is a piece of typical SiS crap: They code the OEM LCD
9722 * delay into the code, at no defined place in the BIOS.
9723 * We now have to start doing a PCI subsystem check here.
9724 */
9725
9726 switch(SiS_Pr->SiS_CustomT) {
9727 case CUT_COMPAQ1280:
9728 case CUT_COMPAQ12802:
9729 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9730 gotitfrompci = true;
9731 dochiptest = false;
9732 delay = 0x03;
9733 }
9734 break;
9735 case CUT_CLEVO1400:
9736 case CUT_CLEVO14002:
9737 gotitfrompci = true;
9738 dochiptest = false;
9739 delay = 0x02;
9740 break;
9741 case CUT_CLEVO1024:
9742 case CUT_CLEVO10242:
9743 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9744 gotitfrompci = true;
9745 dochiptest = false;
9746 delay = 0x33;
9747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9748 delay &= 0x0f;
9749 }
9750 break;
9751 }
9752
9753 /* Could we find it through the PCI ID? If no, use ROM or table */
9754
9755 if(!gotitfrompci) {
9756
9757 index = GetLCDPtrIndexBIOS(SiS_Pr);
9758 myindex = GetLCDPtrIndex(SiS_Pr);
9759
9760 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9761
9762 if(SiS_IsNotM650orLater(SiS_Pr)) {
9763
9764 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9765 /* Always use the second pointer on 650; some BIOSes */
9766 /* still carry old 301 data at the first location */
9767 /* romptr = SISGETROMW(0x120); */
9768 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9769 romptr = SISGETROMW(0x122);
9770 if(!romptr) return;
9771 delay = ROMAddr[(romptr + index)];
9772 } else {
9773 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9774 }
9775
9776 } else {
9777
9778 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9779 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9780 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9781
9782 }
9783
9784 } else if(SiS_Pr->SiS_UseROM &&
9785 (!(SiS_Pr->SiS_ROMNew)) &&
9786 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9787 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
9788 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9789 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9790 ((romptr = GetLCDromptr(SiS_Pr)))) {
9791
9792 /* Data for 1280x1024 wrong in 301B BIOS */
9793 /* Data for 1600x1200 wrong in 301C BIOS */
9794 delay = ROMAddr[(romptr + index)];
9795
9796 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9797
9798 if(IS_SIS740) delay = 0x03;
9799 else delay = 0x00;
9800
9801 } else {
9802
9803 delay = SiS310_LCDDelayCompensation_301[myindex];
9804 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9805 if(IS_SIS740) delay = 0x01;
9806 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9807 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9808 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9809 if(IS_SIS740) delay = 0x01; /* ? */
9810 else delay = 0x03;
9811 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9812 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9813 if(IS_SIS740) delay = 0x01;
9814 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9815 }
9816
9817 }
9818
9819 } /* got it from PCI */
9820
9821 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9822 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9823 dochiptest = false;
9824 }
9825
9826 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
9827
9828 index = GetTVPtrIndex(SiS_Pr);
9829
9830 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9831
9832 if(SiS_IsNotM650orLater(SiS_Pr)) {
9833
9834 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9835 /* Always use the second pointer on 650; some BIOSes */
9836 /* still carry old 301 data at the first location */
9837 /* romptr = SISGETROMW(0x114); */
9838 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9839 romptr = SISGETROMW(0x11a);
9840 if(!romptr) return;
9841 delay = ROMAddr[romptr + index];
9842
9843 } else {
9844
9845 delay = SiS310_TVDelayCompensation_301B[index];
9846
9847 }
9848
9849 } else {
9850
9851 switch(SiS_Pr->SiS_CustomT) {
9852 case CUT_COMPAQ1280:
9853 case CUT_COMPAQ12802:
9854 case CUT_CLEVO1400:
9855 case CUT_CLEVO14002:
9856 delay = 0x02;
9857 dochiptest = false;
9858 break;
9859 case CUT_CLEVO1024:
9860 case CUT_CLEVO10242:
9861 delay = 0x03;
9862 dochiptest = false;
9863 break;
9864 default:
9865 delay = SiS310_TVDelayCompensation_651301LV[index];
9866 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9867 delay = SiS310_TVDelayCompensation_651302LV[index];
9868 }
9869 }
9870 }
9871
9872 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9873
9874 romptr = GetTVromptr(SiS_Pr);
9875 if(!romptr) return;
9876 delay = ROMAddr[romptr + index];
9877
9878 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9879
9880 delay = SiS310_TVDelayCompensation_LVDS[index];
9881
9882 } else {
9883
9884 delay = SiS310_TVDelayCompensation_301[index];
9885 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9886 if(IS_SIS740) {
9887 delay = SiS310_TVDelayCompensation_740301B[index];
9888 /* LV: use 301 data? BIOS bug? */
9889 } else {
9890 delay = SiS310_TVDelayCompensation_301B[index];
9891 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9892 }
9893 }
9894
9895 }
9896
9897 if(SiS_LCDAEnabled(SiS_Pr)) {
9898 delay &= 0x0f;
9899 dochiptest = false;
9900 }
9901
9902 } else return;
9903
9904 /* Write delay */
9905
9906 if(SiS_Pr->SiS_VBType & VB_SISVB) {
9907
9908 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9909
9910 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9911 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
9912 delay &= 0x0f;
9913 delay |= 0xb0;
9914 } else if(temp == 6) {
9915 delay &= 0x0f;
9916 delay |= 0xc0;
9917 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
9918 delay = 0x35;
9919 }
9920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9921
9922 } else {
9923
9924 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9925
9926 }
9927
9928 } else { /* LVDS */
9929
9930 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9932 } else {
9933 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9934 delay <<= 4;
9935 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9936 } else {
9937 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9938 }
9939 }
9940
9941 }
9942
9943}
9944
9945static void
9946SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9947{
9948 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9949 unsigned short index,temp,temp1,romptr=0;
9950
9951 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9952
9953 if(ModeNo<=0x13)
9954 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9955 else
9956 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9957
9958 temp = GetTVPtrIndex(SiS_Pr);
9959 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9960 temp1 = temp;
9961
9962 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9963 if(SiS_Pr->ChipType >= SIS_661) {
9964 temp1 = GetOEMTVPtr661(SiS_Pr);
9965 temp1 >>= 1;
9966 romptr = SISGETROMW(0x260);
9967 if(SiS_Pr->ChipType >= SIS_760) {
9968 romptr = SISGETROMW(0x360);
9969 }
9970 } else if(SiS_Pr->ChipType >= SIS_330) {
9971 romptr = SISGETROMW(0x192);
9972 } else {
9973 romptr = SISGETROMW(0x112);
9974 }
9975 }
9976
9977 if(romptr) {
9978 temp1 <<= 1;
9979 temp = ROMAddr[romptr + temp1 + index];
9980 } else {
9981 temp = SiS310_TVAntiFlick1[temp][index];
9982 }
9983 temp <<= 4;
9984
9985 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
9986}
9987
9988static void
9989SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
9990{
9991 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9992 unsigned short index,temp,temp1,romptr=0;
9993
9994 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9995
9996 if(ModeNo <= 0x13)
9997 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
9998 else
9999 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10000
10001 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10002 if(SiS_Pr->ChipType >= SIS_661) {
10003 romptr = SISGETROMW(0x26c);
10004 if(SiS_Pr->ChipType >= SIS_760) {
10005 romptr = SISGETROMW(0x36c);
10006 }
10007 temp1 = GetOEMTVPtr661(SiS_Pr);
10008 temp1 >>= 1;
10009 } else if(SiS_Pr->ChipType >= SIS_330) {
10010 romptr = SISGETROMW(0x1a4);
10011 } else {
10012 romptr = SISGETROMW(0x124);
10013 }
10014 }
10015
10016 if(romptr) {
10017 temp1 <<= 1;
10018 temp = ROMAddr[romptr + temp1 + index];
10019 } else {
10020 temp = SiS310_TVEdge1[temp][index];
10021 }
10022 temp <<= 5;
10023 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10024}
10025
10026static void
10027SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10028{
10029 unsigned short index, temp, i, j;
10030
10031 if(ModeNo <= 0x13) {
10032 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10033 } else {
10034 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10035 }
10036
10037 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10038
10039 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10040 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10041 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10042 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10043
10044 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10045 for(i=0x35, j=0; i<=0x38; i++, j++) {
10046 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10047 }
10048 for(i=0x48; i<=0x4A; i++, j++) {
10049 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10050 }
10051 } else {
10052 for(i=0x35, j=0; i<=0x38; i++, j++) {
10053 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10054 }
10055 }
10056}
10057
10058static void
10059SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10060{
10061 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10062 unsigned short index,temp,i,j,resinfo,romptr=0;
10063 unsigned int lindex;
10064
10065 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10066
10067 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10068 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10069
10070 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10071 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10072 lindex <<= 2;
10073 for(j=0, i=0x31; i<=0x34; i++, j++) {
10074 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10075 }
10076 return;
10077 }
10078
10079 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10080 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10081
10082 if(ModeNo<=0x13) {
10083 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10084 } else {
10085 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10086 }
10087
10088 temp = GetTVPtrIndex(SiS_Pr);
10089 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10090 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10091 */
10092 if(SiS_Pr->SiS_UseROM) {
10093 romptr = SISGETROMW(0x116);
10094 if(SiS_Pr->ChipType >= SIS_330) {
10095 romptr = SISGETROMW(0x196);
10096 }
10097 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10098 romptr = SISGETROMW(0x11c);
10099 if(SiS_Pr->ChipType >= SIS_330) {
10100 romptr = SISGETROMW(0x19c);
10101 }
10102 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10103 romptr = SISGETROMW(0x116);
10104 if(SiS_Pr->ChipType >= SIS_330) {
10105 romptr = SISGETROMW(0x196);
10106 }
10107 }
10108 }
10109 }
10110 if(romptr) {
10111 romptr += (temp << 2);
10112 for(j=0, i=0x31; i<=0x34; i++, j++) {
10113 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10114 }
10115 } else {
10116 index = temp % 2;
10117 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10118 for(j=0, i=0x31; i<=0x34; i++, j++) {
10119 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10120 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10121 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10122 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10123 else
10124 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10125 }
10126 }
10127
10128 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10129 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10130 if((resinfo == SIS_RI_640x480) ||
10131 (resinfo == SIS_RI_800x600)) {
10132 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10133 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10134 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10135 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10136 } else if(resinfo == SIS_RI_1024x768) {
10137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10138 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10140 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10141 }
10142 }
10143 }
10144}
10145
10146static void
10147SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10148 unsigned short ModeIdIndex, unsigned short RTI)
10149{
10150 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10151 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10152
10153 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10154 return;
10155
10156 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10157 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10158
10159 if(SiS_Pr->SiS_ROMNew) {
10160 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10161 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10162 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10163 index = 25;
10164 if(SiS_Pr->UseCustomMode) {
10165 index = SiS_Pr->CSRClock;
10166 } else if(ModeNo > 0x13) {
10167 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10168 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10169 }
10170 if(index < 25) index = 25;
10171 index = ((index / 25) - 1) << 1;
10172 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10173 index++;
10174 }
10175 romptr = SISGETROMW(0x104);
10176 delay = ROMAddr[romptr + index];
10177 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10178 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10179 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10180 } else {
10181 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10182 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10183 }
10184 return;
10185 }
10186 }
10187
10188 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10189
10190 if(SiS_Pr->UseCustomMode) delay = 0x04;
10191 else if(ModeNo <= 0x13) delay = 0x04;
10192 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10193 delay |= (delay << 8);
10194
10195 if(SiS_Pr->ChipType >= XGI_20) {
10196
10197 delay = 0x0606;
10198 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10199
10200 delay = 0x0404;
10201 if(SiS_Pr->SiS_XGIROM) {
10202 index = GetTVPtrIndex(SiS_Pr);
10203 if((romptr = SISGETROMW(0x35e))) {
10204 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10205 delay |= (delay << 8);
10206 }
10207 }
10208
10209 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10210 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10211 delay -= 0x0404;
10212 }
10213 }
10214 }
10215
10216 } else if(SiS_Pr->ChipType >= SIS_340) {
10217
10218 delay = 0x0606;
10219 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10220 delay = 0x0404;
10221 }
10222 /* TODO (eventually) */
10223
10224 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10225
10226 /* 3. TV */
10227
10228 index = GetOEMTVPtr661(SiS_Pr);
10229 if(SiS_Pr->SiS_ROMNew) {
10230 romptr = SISGETROMW(0x106);
10231 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10232 delay = ROMAddr[romptr + index];
10233 } else {
10234 delay = 0x04;
10235 if(index > 3) delay = 0;
10236 }
10237
10238 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10239
10240 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10241
10242 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10243 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10244
10245 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10246
10247 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10248 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10249 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10250
10251 } else {
10252
10253 /* TMDS: Set our own, since BIOS has no idea */
10254 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10255 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10256 switch(SiS_Pr->SiS_LCDResInfo) {
10257 case Panel_1024x768: delay = 0x0008; break;
10258 case Panel_1280x720: delay = 0x0004; break;
10259 case Panel_1280x768:
10260 case Panel_1280x768_2:delay = 0x0004; break;
10261 case Panel_1280x800:
10262 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10263 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10264 case Panel_1280x1024: delay = 0x1e04; break;
10265 case Panel_1400x1050: delay = 0x0004; break;
10266 case Panel_1600x1200: delay = 0x0400; break;
10267 case Panel_1680x1050: delay = 0x0e04; break;
10268 default:
10269 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10270 delay = 0x0008;
10271 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10272 delay = 0x1e04;
10273 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10274 delay = 0x0004;
10275 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10276 delay = 0x0400;
10277 } else
10278 delay = 0x0e04;
10279 break;
10280 }
10281 }
10282
10283 /* Override by detected or user-set values */
10284 /* (but only if, for some reason, we can't read value from BIOS) */
10285 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10286 delay = SiS_Pr->PDC & 0x1f;
10287 }
10288 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10289 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10290 }
10291
10292 }
10293
10294 }
10295
10296 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10297 delay >>= 8;
10298 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10299 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10300 } else {
10301 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10302 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10303 }
10304}
10305
10306static void
10307SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10308{
10309 unsigned short infoflag;
10310 unsigned char temp;
10311
10312 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10313
10314 if(ModeNo <= 0x13) {
10315 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10316 } else if(SiS_Pr->UseCustomMode) {
10317 infoflag = SiS_Pr->CInfoFlag;
10318 } else {
10319 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10320 }
10321
10322 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10323 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10324 }
10325
10326 infoflag &= 0xc0;
10327
10328 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10329 temp = (infoflag >> 6) | 0x0c;
10330 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10331 temp ^= 0x04;
10332 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10333 }
10334 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10335 } else {
10336 temp = 0x30;
10337 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10338 temp |= infoflag;
10339 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10340 temp = 0;
10341 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10342 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10343 }
10344 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10345 }
10346
10347 }
10348}
10349
10350static void
10351SetPanelParms661(struct SiS_Private *SiS_Pr)
10352{
10353 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10354 unsigned short romptr, temp1, temp2;
10355
10356 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10357 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10358 }
10359
10360 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10361 if(SiS_Pr->LVDSHL != -1) {
10362 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10363 }
10364 }
10365
10366 if(SiS_Pr->SiS_ROMNew) {
10367
10368 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10369 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10370 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10371 temp2 = 0xfc;
10372 if(SiS_Pr->LVDSHL != -1) {
10373 temp1 &= 0xfc;
10374 temp2 = 0xf3;
10375 }
10376 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10377 }
10378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10379 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10380 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10381 }
10382 }
10383
10384 }
10385}
10386
10387static void
10388SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10389{
10390 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10391 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10392 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10393 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10394 SetPanelParms661(SiS_Pr);
10395 }
10396 } else {
10397 SetDelayComp(SiS_Pr,ModeNo);
10398 }
10399
10400 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10401 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10402 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10403 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10404 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10405 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10406 }
10407 }
10408}
10409
10410static void
10411SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10412 unsigned short ModeIdIndex, unsigned short RRTI)
10413{
10414 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10415
10416 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10417
10418 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10419 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10420 SetPanelParms661(SiS_Pr);
10421 }
10422
10423 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10424 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10425 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10426 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10427 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10428 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10429 }
10430 }
10431 }
10432}
10433
10434/* FinalizeLCD
10435 * This finalizes some CRT2 registers for the very panel used.
10436 * If we have a backup if these registers, we use it; otherwise
10437 * we set the register according to most BIOSes. However, this
10438 * function looks quite different in every BIOS, so you better
10439 * pray that we have a backup...
10440 */
10441static void
10442SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10443{
10444 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10445 unsigned short resinfo,modeflag;
10446
10447 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10448 if(SiS_Pr->SiS_ROMNew) return;
10449
10450 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10451 if(SiS_Pr->LVDSHL != -1) {
10452 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10453 }
10454 }
10455
10456 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10457 if(SiS_Pr->UseCustomMode) return;
10458
10459 switch(SiS_Pr->SiS_CustomT) {
10460 case CUT_COMPAQ1280:
10461 case CUT_COMPAQ12802:
10462 case CUT_CLEVO1400:
10463 case CUT_CLEVO14002:
10464 return;
10465 }
10466
10467 if(ModeNo <= 0x13) {
10468 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10469 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10470 } else {
10471 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10472 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10473 }
10474
10475 if(IS_SIS650) {
10476 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10477 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10479 } else {
10480 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10481 }
10482 }
10483 }
10484
10485 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10486 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10487 /* Maybe all panels? */
10488 if(SiS_Pr->LVDSHL == -1) {
10489 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10490 }
10491 return;
10492 }
10493 }
10494
10495 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10496 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10497 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10498 if(SiS_Pr->LVDSHL == -1) {
10499 /* Maybe all panels? */
10500 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10501 }
10502 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10503 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10504 if(tempch == 3) {
10505 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10506 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10507 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10508 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10509 }
10510 }
10511 return;
10512 }
10513 }
10514 }
10515
10516 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10517 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10518 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10519 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10520#ifdef SET_EMI
10521 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10522#endif
10523 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10524 }
10525 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10526 if(SiS_Pr->LVDSHL == -1) {
10527 /* Maybe ACER only? */
10528 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10529 }
10530 }
10531 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10532 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10533 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10534 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10535 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10536 if(tempch == 0x03) {
10537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10538 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10539 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10540 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10541 }
10542 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10543 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10544 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10545 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10546 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10547 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10548 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10549 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10550 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10551 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10552 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10553 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10554 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10555 if(ModeNo <= 0x13) {
10556 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10557 if((resinfo == 0) || (resinfo == 2)) return;
10558 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10559 if((resinfo == 1) || (resinfo == 3)) return;
10560 }
10561 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10562 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10563 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10564#if 0
10565 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10566 tempbx--;
10567 temp = tempbx & 0xff;
10568 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10569 temp = (tempbx >> 8) & 0x03;
10570 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10571#endif
10572 }
10573 } else if(ModeNo <= 0x13) {
10574 if(ModeNo <= 1) {
10575 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10576 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10577 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10578 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10579 }
10580 if(!(modeflag & HalfDCLK)) {
10581 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10582 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10584 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10585 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10586 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10587 if(ModeNo == 0x12) {
10588 switch(tempch) {
10589 case 0:
10590 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10591 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10592 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10593 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10594 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10595 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10596 break;
10597 case 2:
10598 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10599 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10600 break;
10601 case 3:
10602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10603 break;
10604 }
10605 }
10606 }
10607 }
10608 }
10609 } else {
10610 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10611 tempcl &= 0x0f;
10612 tempbh &= 0x70;
10613 tempbh >>= 4;
10614 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10615 tempbx = (tempbh << 8) | tempbl;
10616 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10617 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10618 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10619 tempbx = 770;
10620 } else {
10621 if(tempbx > 770) tempbx = 770;
10622 if(SiS_Pr->SiS_VGAVDE < 600) {
10623 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10624 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10625 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10626 tempbx -= tempax;
10627 }
10628 }
10629 } else return;
10630 }
10631 temp = tempbx & 0xff;
10632 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10633 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10634 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10635 }
10636 }
10637}
10638
10639#endif
10640
10641/* ================= SiS 300 O.E.M. ================== */
10642
10643#ifdef CONFIG_FB_SIS_300
10644
10645static void
10646SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10647 unsigned short RefTabIndex)
10648{
10649 unsigned short crt2crtc=0, modeflag, myindex=0;
10650 unsigned char temp;
10651 int i;
10652
10653 if(ModeNo <= 0x13) {
10654 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10655 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10656 } else {
10657 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10658 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10659 }
10660
10661 crt2crtc &= 0x3f;
10662
10663 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10664 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10665 }
10666
10667 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10668 if(modeflag & HalfDCLK) myindex = 1;
10669
10670 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10671 for(i=0; i<7; i++) {
10672 if(barco_p1[myindex][crt2crtc][i][0]) {
10673 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10674 barco_p1[myindex][crt2crtc][i][0],
10675 barco_p1[myindex][crt2crtc][i][2],
10676 barco_p1[myindex][crt2crtc][i][1]);
10677 }
10678 }
10679 }
10680 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10681 if(temp & 0x80) {
10682 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10683 temp++;
10684 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10685 }
10686 }
10687}
10688
10689static unsigned short
10690GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10691{
10692 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10693 unsigned short tempbx=0,romptr=0;
10694 static const unsigned char customtable300[] = {
10695 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10696 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10697 };
10698 static const unsigned char customtable630[] = {
10699 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10700 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10701 };
10702
10703 if(SiS_Pr->ChipType == SIS_300) {
10704
10705 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10706 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10707 tempbx -= 2;
10708 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10709 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10710 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10711 }
10712 if(SiS_Pr->SiS_UseROM) {
10713 if(ROMAddr[0x235] & 0x80) {
10714 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10715 if(Flag) {
10716 romptr = SISGETROMW(0x255);
10717 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10718 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10719 if(tempbx == 0xFF) return 0xFFFF;
10720 }
10721 tempbx <<= 1;
10722 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10723 }
10724 }
10725
10726 } else {
10727
10728 if(Flag) {
10729 if(SiS_Pr->SiS_UseROM) {
10730 romptr = SISGETROMW(0x255);
10731 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10732 else tempbx = 0xff;
10733 } else {
10734 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10735 }
10736 if(tempbx == 0xFF) return 0xFFFF;
10737 tempbx <<= 2;
10738 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10739 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10740 return tempbx;
10741 }
10742 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10743 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10744 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10745
10746 }
10747
10748 return tempbx;
10749}
10750
10751static void
10752SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10753{
10754 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10755 unsigned short index,temp,romptr=0;
10756
10757 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10758
10759 if(SiS_Pr->SiS_UseROM) {
10760 if(!(ROMAddr[0x237] & 0x01)) return;
10761 if(!(ROMAddr[0x237] & 0x02)) return;
10762 romptr = SISGETROMW(0x24b);
10763 }
10764
10765 /* The Panel Compensation Delay should be set according to tables
10766 * here. Unfortunately, various BIOS versions don't care about
10767 * a uniform way using eg. ROM byte 0x220, but use different
10768 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10769 * Thus we don't set this if the user selected a custom pdc or if
10770 * we otherwise detected a valid pdc.
10771 */
10772 if(SiS_Pr->PDC != -1) return;
10773
10774 temp = GetOEMLCDPtr(SiS_Pr, 0);
10775
10776 if(SiS_Pr->UseCustomMode)
10777 index = 0;
10778 else
10779 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10780
10781 if(SiS_Pr->ChipType != SIS_300) {
10782 if(romptr) {
10783 romptr += (temp * 2);
10784 romptr = SISGETROMW(romptr);
10785 romptr += index;
10786 temp = ROMAddr[romptr];
10787 } else {
10788 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10789 temp = SiS300_OEMLCDDelay2[temp][index];
10790 } else {
10791 temp = SiS300_OEMLCDDelay3[temp][index];
10792 }
10793 }
10794 } else {
10795 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10796 if(romptr) {
10797 romptr += (temp * 2);
10798 romptr = SISGETROMW(romptr);
10799 romptr += index;
10800 temp = ROMAddr[romptr];
10801 } else {
10802 temp = SiS300_OEMLCDDelay5[temp][index];
10803 }
10804 } else {
10805 if(SiS_Pr->SiS_UseROM) {
10806 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10807 if(romptr) {
10808 romptr += (temp * 2);
10809 romptr = SISGETROMW(romptr);
10810 romptr += index;
10811 temp = ROMAddr[romptr];
10812 } else {
10813 temp = SiS300_OEMLCDDelay4[temp][index];
10814 }
10815 } else {
10816 temp = SiS300_OEMLCDDelay4[temp][index];
10817 }
10818 }
10819 }
10820 temp &= 0x3c;
10821 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
10822}
10823
10824static void
10825SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10826{
10827#if 0 /* Unfinished; Data table missing */
10828 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10829 unsigned short index,temp;
10830
10831 if((SiS_Pr->SiS_UseROM) {
10832 if(!(ROMAddr[0x237] & 0x01)) return;
10833 if(!(ROMAddr[0x237] & 0x04)) return;
10834 /* No rom pointer in BIOS header! */
10835 }
10836
10837 temp = GetOEMLCDPtr(SiS_Pr, 1);
10838 if(temp == 0xFFFF) return;
10839
10840 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10841 for(i=0x14, j=0; i<=0x17; i++, j++) {
10842 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10843 }
10844 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10845
10846 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10847 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10848 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10849 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10850 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10851 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10852 }
10853#endif
10854}
10855
10856static unsigned short
10857GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10858{
10859 unsigned short index;
10860
10861 index = 0;
10862 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
10863 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10864 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
10865 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10866 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10867 } else {
10868 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10869 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
10870 }
10871 return index;
10872}
10873
10874static void
10875SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10876{
10877 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10878 unsigned short index,temp,romptr=0;
10879
10880 if(SiS_Pr->SiS_UseROM) {
10881 if(!(ROMAddr[0x238] & 0x01)) return;
10882 if(!(ROMAddr[0x238] & 0x02)) return;
10883 romptr = SISGETROMW(0x241);
10884 }
10885
10886 temp = GetOEMTVPtr(SiS_Pr);
10887
10888 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10889
10890 if(romptr) {
10891 romptr += (temp * 2);
10892 romptr = SISGETROMW(romptr);
10893 romptr += index;
10894 temp = ROMAddr[romptr];
10895 } else {
10896 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10897 temp = SiS300_OEMTVDelay301[temp][index];
10898 } else {
10899 temp = SiS300_OEMTVDelayLVDS[temp][index];
10900 }
10901 }
10902 temp &= 0x3c;
10903 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10904}
10905
10906static void
10907SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10908{
10909 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10910 unsigned short index,temp,romptr=0;
10911
10912 if(SiS_Pr->SiS_UseROM) {
10913 if(!(ROMAddr[0x238] & 0x01)) return;
10914 if(!(ROMAddr[0x238] & 0x04)) return;
10915 romptr = SISGETROMW(0x243);
10916 }
10917
10918 temp = GetOEMTVPtr(SiS_Pr);
10919
10920 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10921
10922 if(romptr) {
10923 romptr += (temp * 2);
10924 romptr = SISGETROMW(romptr);
10925 romptr += index;
10926 temp = ROMAddr[romptr];
10927 } else {
10928 temp = SiS300_OEMTVFlicker[temp][index];
10929 }
10930 temp &= 0x70;
10931 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10932}
10933
10934static void
10935SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10936{
10937 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10938 unsigned short index,i,j,temp,romptr=0;
10939
10940 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10941
10942 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10943
10944 if(SiS_Pr->SiS_UseROM) {
10945 if(!(ROMAddr[0x238] & 0x01)) return;
10946 if(!(ROMAddr[0x238] & 0x08)) return;
10947 romptr = SISGETROMW(0x245);
10948 }
10949
10950 temp = GetOEMTVPtr(SiS_Pr);
10951
10952 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10953
10954 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10955 for(i=0x31, j=0; i<=0x34; i++, j++) {
10956 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10957 }
10958 } else {
10959 if(romptr) {
10960 romptr += (temp * 2);
10961 romptr = SISGETROMW(romptr);
10962 romptr += (index * 4);
10963 for(i=0x31, j=0; i<=0x34; i++, j++) {
10964 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10965 }
10966 } else {
10967 for(i=0x31, j=0; i<=0x34; i++, j++) {
10968 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
10969 }
10970 }
10971 }
10972}
10973
10974static void
10975SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10976{
10977 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10978 unsigned short index,temp,i,j,romptr=0;
10979
10980 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
10981
10982 if(SiS_Pr->SiS_UseROM) {
10983 if(!(ROMAddr[0x238] & 0x01)) return;
10984 if(!(ROMAddr[0x238] & 0x10)) return;
10985 romptr = SISGETROMW(0x247);
10986 }
10987
10988 temp = GetOEMTVPtr(SiS_Pr);
10989
10990 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
10991 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
10992 /* NTSCJ uses NTSC filters */
10993
10994 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
10995
10996 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10997 for(i=0x35, j=0; i<=0x38; i++, j++) {
10998 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10999 }
11000 for(i=0x48; i<=0x4A; i++, j++) {
11001 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11002 }
11003 } else {
11004 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11005 romptr += (temp * 2);
11006 romptr = SISGETROMW(romptr);
11007 romptr += (index * 4);
11008 for(i=0x35, j=0; i<=0x38; i++, j++) {
11009 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11010 }
11011 } else {
11012 for(i=0x35, j=0; i<=0x38; i++, j++) {
11013 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11014 }
11015 }
11016 }
11017}
11018
11019static unsigned short
11020SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11021{
11022 unsigned short ModeIdIndex;
11023 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11024
11025 if(*ModeNo <= 5) *ModeNo |= 1;
11026
11027 for(ModeIdIndex=0; ; ModeIdIndex++) {
11028 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11029 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11030 }
11031
11032 if(*ModeNo != 0x07) {
11033 if(*ModeNo > 0x03) return ModeIdIndex;
11034 if(VGAINFO & 0x80) return ModeIdIndex;
11035 ModeIdIndex++;
11036 }
11037
11038 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11039 /* else 350 lines */
11040 return ModeIdIndex;
11041}
11042
11043static void
11044SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11045 unsigned short RefTableIndex)
11046{
11047 unsigned short OEMModeIdIndex = 0;
11048
11049 if(!SiS_Pr->UseCustomMode) {
11050 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11051 if(!(OEMModeIdIndex)) return;
11052 }
11053
11054 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11055 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11056 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11057 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11058 }
11059 }
11060 if(SiS_Pr->UseCustomMode) return;
11061 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11062 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11063 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11064 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11065 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11066 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11067 }
11068 }
11069}
11070#endif
11071
diff --git a/drivers/video/fbdev/sis/init301.h b/drivers/video/fbdev/sis/init301.h
new file mode 100644
index 000000000000..2112d6d7feda
--- /dev/null
+++ b/drivers/video/fbdev/sis/init301.h
@@ -0,0 +1,456 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Data and prototypes for init301.c
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INIT301_H_
54#define _INIT301_H_
55
56#include "initdef.h"
57
58#include "vgatypes.h"
59#include "vstruct.h"
60#ifdef SIS_CP
61#undef SIS_CP
62#endif
63#include <linux/types.h>
64#include <asm/io.h>
65#include <linux/fb.h>
66#include "sis.h"
67#include <video/sisfb.h>
68
69static const unsigned char SiS_YPbPrTable[3][64] = {
70 {
71 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
72 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
73 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
74 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
75 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
76 0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
77 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
78 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
79 },
80 {
81 0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
82 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
83 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
84 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
85 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
86 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
87 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
88 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
89 },
90 {
91#if 0 /* OK, but sticks to left edge */
92 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
93 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
94 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
95 0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
96 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
97 0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
98 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
99 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
100#endif
101#if 1 /* Perfect */
102 0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
103 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
104 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
105 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
106 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
107 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
108 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
109 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
110#endif
111 }
112};
113
114static const unsigned char SiS_TVPhase[] =
115{
116 0x21,0xED,0xBA,0x08, /* 0x00 SiS_NTSCPhase */
117 0x2A,0x05,0xE3,0x00, /* 0x01 SiS_PALPhase */
118 0x21,0xE4,0x2E,0x9B, /* 0x02 SiS_PALMPhase */
119 0x21,0xF4,0x3E,0xBA, /* 0x03 SiS_PALNPhase */
120 0x1E,0x8B,0xA2,0xA7,
121 0x1E,0x83,0x0A,0xE0, /* 0x05 SiS_SpecialPhaseM */
122 0x00,0x00,0x00,0x00,
123 0x00,0x00,0x00,0x00,
124 0x21,0xF0,0x7B,0xD6, /* 0x08 SiS_NTSCPhase2 */
125 0x2A,0x09,0x86,0xE9, /* 0x09 SiS_PALPhase2 */
126 0x21,0xE6,0xEF,0xA4, /* 0x0a SiS_PALMPhase2 */
127 0x21,0xF6,0x94,0x46, /* 0x0b SiS_PALNPhase2 */
128 0x1E,0x8B,0xA2,0xA7,
129 0x1E,0x83,0x0A,0xE0, /* 0x0d SiS_SpecialPhaseM */
130 0x00,0x00,0x00,0x00,
131 0x00,0x00,0x00,0x00,
132 0x1e,0x8c,0x5c,0x7a, /* 0x10 SiS_SpecialPhase */
133 0x25,0xd4,0xfd,0x5e /* 0x11 SiS_SpecialPhaseJ */
134};
135
136static const unsigned char SiS_HiTVGroup3_1[] = {
137 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
138 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
139 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
140 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
141 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
142 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
143 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
144 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
145};
146
147static const unsigned char SiS_HiTVGroup3_2[] = {
148 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
149 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
150 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
151 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
152 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
153 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
154 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
155 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
156};
157
158/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
159
160static const unsigned char SiS_Part2CLVX_1[] = {
161 0x00,0x00,
162 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
163 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
164 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
165 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
166};
167
168static const unsigned char SiS_Part2CLVX_2[] = {
169 0x00,0x00,
170 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
171 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
172 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
173 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
174};
175
176static const unsigned char SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
177 0xE0,0x01,
178 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
179 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
180 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
181 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
182 0x58,0x02,
183 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
184 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
185 0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
186 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
187 0x00,0x03,
188 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
189 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
190 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
191 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
192 0xFF,0xFF
193};
194
195static const unsigned char SiS_Part2CLVX_4[] = { /* PAL */
196 0x58,0x02,
197 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
198 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
199 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
200 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
201 0x00,0x03,
202 0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
203 0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
204 0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
205 0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
206 0x40,0x02,
207 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
208 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
209 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
210 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
211 0xFF,0xFF
212};
213
214static const unsigned char SiS_Part2CLVX_5[] = { /* 750p */
215 0x00,0x03,
216 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
217 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
218 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
219 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
220 0xFF,0xFF
221};
222
223static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
224 0x00,0x04,
225 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
226 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
227 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
228 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
229 0xFF,0xFF,
230};
231
232#ifdef CONFIG_FB_SIS_315
233/* 661 et al LCD data structure (2.03.00) */
234static const unsigned char SiS_LCDStruct661[] = {
235 /* 1024x768 */
236/* type|CR37| HDE | VDE | HT | VT | hss | hse */
237 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
238 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
239 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
240 /* VESA non-VESA noscale */
241 /* 1280x1024 */
242 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
243 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
244 /* 1400x1050 */
245 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
246 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
247 /* 1600x1200 */
248 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
249 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
250 /* 1280x768 (_2) */
251 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
252 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
253 /* 1280x720 */
254 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
255 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
256 /* 1280x800 (_2) */
257 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
258 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
259 /* 1680x1050 */
260 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
261 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
262 /* 1280x800_3 */
263 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
264 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
265 /* 800x600 */
266 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
267 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
268 /* 1280x854 */
269 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
270 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
271};
272#endif
273
274#ifdef CONFIG_FB_SIS_300
275static unsigned char SiS300_TrumpionData[14][80] = {
276 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
277 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
278 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
279 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
280 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
281 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
282 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
283 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
284 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
285 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
286 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
287 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
288 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
289 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
290 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
291 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
292 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
293 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
294 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
295 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
296 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
297 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
298 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
299 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
300 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
301 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
302 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
303 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
304 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
305 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
306 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
307 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
308 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
309 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
310 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
311 /* variant 2 */
312 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
313 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
314 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
315 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
316 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
317 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
318 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
319 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
320 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
321 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
322 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
323 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
324 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
325 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
326 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
327 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
328 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
329 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
330 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
331 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
332 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
333 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
334 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
335 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
336 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
337 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
338 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
339 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
340 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
341 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
342 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
343 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
344 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
345 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
346 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
347};
348#endif
349
350void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
351void SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
352unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
353void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
354bool SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
355bool SiS_IsVAMode(struct SiS_Private *SiS_Pr);
356void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
357 unsigned short ModeIdIndex, int checkcrt2mode);
358void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
359void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
360 unsigned short ModeIdIndex);
361void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
362 unsigned short ModeIdIndex);
363unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
364 unsigned short RefreshRateTableIndex);
365unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
366void SiS_DisableBridge(struct SiS_Private *SiS_Pr);
367bool SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
368void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
369void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
370
371void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
372unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
373void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
374unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
375void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
376 unsigned char orval,unsigned short andval);
377#ifdef CONFIG_FB_SIS_315
378static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
379static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
380static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
381static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
382void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
383void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
384#endif /* 315 */
385
386#ifdef CONFIG_FB_SIS_300
387static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
388void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
389#endif
390
391void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
392unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
393unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
394 unsigned short adaptnum, unsigned short DDCdatatype,
395 unsigned char *buffer, unsigned int VBFlags2);
396
397static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
398 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
399 bool checkcr32, unsigned int VBFlags2);
400static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
401static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
402 unsigned char *buffer);
403static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
404static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
405static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
406static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
407static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
408static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
409static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
410static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
411static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
412static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
413static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
414static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
415static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
416
417#ifdef CONFIG_FB_SIS_300
418static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
419 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
420static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
421 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
422#endif
423#ifdef CONFIG_FB_SIS_315
424static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
425 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
426static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
427 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
428static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
429#endif
430
431extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
432extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
433extern bool SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
434extern unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
435 unsigned short ModeIdIndex);
436extern unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
437extern unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
438extern unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
439 unsigned short RefreshRateTableIndex);
440extern void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
441 unsigned short ModeIdIndex);
442extern void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
443 unsigned short ModeIdIndex);
444extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
445extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
446extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
447#ifdef CONFIG_FB_SIS_300
448extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
449 unsigned short *tempcl);
450extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
451extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
452extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
453extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
454#endif
455
456#endif
diff --git a/drivers/video/fbdev/sis/initdef.h b/drivers/video/fbdev/sis/initdef.h
new file mode 100644
index 000000000000..264b55a5947b
--- /dev/null
+++ b/drivers/video/fbdev/sis/initdef.h
@@ -0,0 +1,708 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Global definitions for init.c and init301.c
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INITDEF_
54#define _INITDEF_
55
56#define IS_SIS330 (SiS_Pr->ChipType == SIS_330)
57#define IS_SIS550 (SiS_Pr->ChipType == SIS_550)
58#define IS_SIS650 (SiS_Pr->ChipType == SIS_650) /* All versions, incl 651, M65x */
59#define IS_SIS740 (SiS_Pr->ChipType == SIS_740)
60#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
61#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
62#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */
63#define IS_SIS661 (SiS_Pr->ChipType == SIS_661)
64#define IS_SIS741 (SiS_Pr->ChipType == SIS_741)
65#define IS_SIS660 (SiS_Pr->ChipType == SIS_660)
66#define IS_SIS760 (SiS_Pr->ChipType == SIS_760)
67#define IS_SIS761 (SiS_Pr->ChipType == SIS_761)
68#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760 || IS_SIS761)
69#define IS_SIS650740 ((SiS_Pr->ChipType >= SIS_650) && (SiS_Pr->ChipType < SIS_330))
70#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740)
71#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
72#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
73
74#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
75
76/* SiS_VBType */
77#define VB_SIS301 0x0001
78#define VB_SIS301B 0x0002
79#define VB_SIS302B 0x0004
80#define VB_SIS301LV 0x0008
81#define VB_SIS302LV 0x0010
82#define VB_SIS302ELV 0x0020
83#define VB_SIS301C 0x0040
84#define VB_SIS307T 0x0080
85#define VB_SIS307LV 0x0100
86#define VB_UMC 0x4000
87#define VB_NoLCD 0x8000
88#define VB_SIS30xB (VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
89#define VB_SIS30xC (VB_SIS301C | VB_SIS307T)
90#define VB_SISTMDS (VB_SIS301 | VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
91#define VB_SISLVDS (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
92#define VB_SIS30xBLV (VB_SIS30xB | VB_SISLVDS)
93#define VB_SIS30xCLV (VB_SIS30xC | VB_SIS302ELV | VB_SIS307LV)
94#define VB_SISVB (VB_SIS301 | VB_SIS30xBLV)
95#define VB_SISLCDA (VB_SIS302B | VB_SIS301C | VB_SIS307T | VB_SISLVDS)
96#define VB_SISTMDSLCDA (VB_SIS301C | VB_SIS307T)
97#define VB_SISPART4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
98#define VB_SISHIVISION (VB_SIS301 | VB_SIS301B | VB_SIS302B)
99#define VB_SISYPBPR (VB_SIS301C | VB_SIS307T | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
100#define VB_SISTAP4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
101#define VB_SISPART4OVERFLOW (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
102#define VB_SISPWD (VB_SIS301C | VB_SIS307T | VB_SISLVDS)
103#define VB_SISEMI (VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
104#define VB_SISPOWER (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
105#define VB_SISDUALLINK (VB_SIS302LV | VB_SIS302ELV | VB_SIS307T | VB_SIS307LV)
106#define VB_SISVGA2 VB_SISTMDS
107#define VB_SISRAMDAC202 (VB_SIS301C | VB_SIS307T)
108
109/* VBInfo */
110#define SetSimuScanMode 0x0001 /* CR 30 */
111#define SwitchCRT2 0x0002
112#define SetCRT2ToAVIDEO 0x0004
113#define SetCRT2ToSVIDEO 0x0008
114#define SetCRT2ToSCART 0x0010
115#define SetCRT2ToLCD 0x0020
116#define SetCRT2ToRAMDAC 0x0040
117#define SetCRT2ToHiVision 0x0080 /* for SiS bridge */
118#define SetCRT2ToCHYPbPr SetCRT2ToHiVision /* for Chrontel */
119#define SetNTSCTV 0x0000 /* CR 31 */
120#define SetPALTV 0x0100 /* Deprecated here, now in TVMode */
121#define SetInSlaveMode 0x0200
122#define SetNotSimuMode 0x0400
123#define SetNotSimuTVMode SetNotSimuMode
124#define SetDispDevSwitch 0x0800
125#define SetCRT2ToYPbPr525750 0x0800
126#define LoadDACFlag 0x1000
127#define DisableCRT2Display 0x2000
128#define DriverMode 0x4000
129#define HotKeySwitch 0x8000
130#define SetCRT2ToLCDA 0x8000
131
132/* v-- Needs change in sis_vga.c if changed (GPIO) --v */
133#define SetCRT2ToTV (SetCRT2ToYPbPr525750|SetCRT2ToHiVision|SetCRT2ToSCART|SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)
134#define SetCRT2ToTVNoYPbPrHiVision (SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
135#define SetCRT2ToTVNoHiVision (SetCRT2ToYPbPr525750 | SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
136
137/* SiS_ModeType */
138#define ModeText 0x00
139#define ModeCGA 0x01
140#define ModeEGA 0x02
141#define ModeVGA 0x03
142#define Mode15Bpp 0x04
143#define Mode16Bpp 0x05
144#define Mode24Bpp 0x06
145#define Mode32Bpp 0x07
146
147#define ModeTypeMask 0x07
148#define IsTextMode 0x07
149
150#define DACInfoFlag 0x0018
151#define MemoryInfoFlag 0x01E0
152#define MemorySizeShift 5
153
154/* modeflag */
155#define Charx8Dot 0x0200
156#define LineCompareOff 0x0400
157#define CRT2Mode 0x0800
158#define HalfDCLK 0x1000
159#define NoSupportSimuTV 0x2000
160#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
161#define DoubleScanMode 0x8000
162
163/* Infoflag */
164#define SupportTV 0x0008
165#define SupportTV1024 0x0800
166#define SupportCHTV 0x0800
167#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
168#define SupportHiVision 0x0010
169#define SupportYPbPr750p 0x1000
170#define SupportLCD 0x0020
171#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
172#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
173#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */
174#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
175#define InterlaceMode 0x0080
176#define SyncPP 0x0000
177#define HaveWideTiming 0x2000 /* Have specific wide- and non-wide timing */
178#define SyncPN 0x4000
179#define SyncNP 0x8000
180#define SyncNN 0xc000
181
182/* SetFlag */
183#define ProgrammingCRT2 0x0001
184#define LowModeTests 0x0002
185/* #define TVSimuMode 0x0002 - deprecated */
186/* #define RPLLDIV2XO 0x0004 - deprecated */
187#define LCDVESATiming 0x0008
188#define EnableLVDSDDA 0x0010
189#define SetDispDevSwitchFlag 0x0020
190#define CheckWinDos 0x0040
191#define SetDOSMode 0x0080
192
193/* TVMode flag */
194#define TVSetPAL 0x0001
195#define TVSetNTSCJ 0x0002
196#define TVSetPALM 0x0004
197#define TVSetPALN 0x0008
198#define TVSetCHOverScan 0x0010
199#define TVSetYPbPr525i 0x0020 /* new 0x10 */
200#define TVSetYPbPr525p 0x0040 /* new 0x20 */
201#define TVSetYPbPr750p 0x0080 /* new 0x40 */
202#define TVSetHiVision 0x0100 /* new 0x80; = 1080i, software-wise identical */
203#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
204#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
205#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
206#define TVSet525p1024 0x1000 /* TW */
207#define TVAspect43 0x2000
208#define TVAspect169 0x4000
209#define TVAspect43LB 0x8000
210
211/* YPbPr flag (>=315, <661; converted to TVMode) */
212#define YPbPr525p 0x0001
213#define YPbPr750p 0x0002
214#define YPbPr525i 0x0004
215#define YPbPrHiVision 0x0008
216#define YPbPrModeMask (YPbPr750p | YPbPr525p | YPbPr525i | YPbPrHiVision)
217
218/* SysFlags (to identify special versions) */
219#define SF_Is651 0x0001
220#define SF_IsM650 0x0002
221#define SF_Is652 0x0004
222#define SF_IsM652 0x0008
223#define SF_IsM653 0x0010
224#define SF_IsM661 0x0020
225#define SF_IsM741 0x0040
226#define SF_IsM760 0x0080
227#define SF_760UMA 0x4000 /* 76x: We have UMA */
228#define SF_760LFB 0x8000 /* 76x: We have LFB */
229
230/* CR32 (Newer 630, and 315 series)
231
232 [0] VB connected with CVBS
233 [1] VB connected with SVHS
234 [2] VB connected with SCART
235 [3] VB connected with LCD
236 [4] VB connected with CRT2 (secondary VGA)
237 [5] CRT1 monitor is connected
238 [6] VB connected with Hi-Vision TV
239 [7] <= 330: VB connected with DVI combo connector
240 >= 661: VB connected to YPbPr
241*/
242
243/* CR35 (300 series only) */
244#define TVOverScan 0x10
245#define TVOverScanShift 4
246
247/* CR35 (661 series only)
248 [0] 1 = PAL, 0 = NTSC
249 [1] 1 = NTSC-J (if D0 = 0)
250 [2] 1 = PALM (if D0 = 1)
251 [3] 1 = PALN (if D0 = 1)
252 [4] 1 = Overscan (Chrontel only)
253 [7:5] (only if D2 in CR38 is set)
254 000 525i
255 001 525p
256 010 750p
257 011 1080i (or HiVision on 301, 301B)
258*/
259
260/* CR37
261 [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
262 [3:1] External chip
263 300 series:
264 001 SiS301 (never seen)
265 010 LVDS
266 011 LVDS + Tumpion Zurac
267 100 LVDS + Chrontel 7005
268 110 Chrontel 7005
269 315/330 series
270 001 SiS30x (never seen)
271 010 LVDS
272 011 LVDS + Chrontel 7019
273 660 series [2:1] only:
274 reserved (chip type now in CR38)
275 All other combinations reserved
276 [3] 661 only: Pass 1:1 data
277 [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand
278 30x: 0: Bridge scales / 1: Bridge does not scale = Panel scales (if possible)
279 [5] LCD polarity select
280 0: VESA DMT Standard
281 1: EDID 2.x defined
282 [6] LCD horizontal polarity select
283 0: High active
284 1: Low active
285 [7] LCD vertical polarity select
286 0: High active
287 1: Low active
288*/
289
290/* CR37: LCDInfo */
291#define LCDRGB18Bit 0x0001
292#define LCDNonExpanding 0x0010
293#define LCDSync 0x0020
294#define LCDPass11 0x0100 /* 0: center screen, 1: Pass 1:1 data */
295#define LCDDualLink 0x0200
296
297#define DontExpandLCD LCDNonExpanding
298#define LCDNonExpandingShift 4
299#define DontExpandLCDShift LCDNonExpandingShift
300#define LCDSyncBit 0x00e0
301#define LCDSyncShift 6
302
303/* CR38 (315 series) */
304#define EnableDualEdge 0x01
305#define SetToLCDA 0x02 /* LCD channel A (301C/302B/30x(E)LV and 650+LVDS only) */
306#define EnableCHScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */
307#define EnableCHYPbPr 0x08 /* YPbPr on Ch7019 (480i HDTV); only on 650/Ch7019 systems */
308#define EnableSiSYPbPr 0x08 /* Enable YPbPr mode (30xLV/301C only) */
309#define EnableYPbPr525i 0x00 /* Enable 525i YPbPr mode (30xLV/301C only) (mask 0x30) */
310#define EnableYPbPr525p 0x10 /* Enable 525p YPbPr mode (30xLV/301C only) (mask 0x30) */
311#define EnableYPbPr750p 0x20 /* Enable 750p YPbPr mode (30xLV/301C only) (mask 0x30) */
312#define EnableYPbPr1080i 0x30 /* Enable 1080i YPbPr mode (30xLV/301C only) (mask 0x30) */
313#define EnablePALM 0x40 /* 1 = Set PALM */
314#define EnablePALN 0x80 /* 1 = Set PALN */
315#define EnableNTSCJ EnablePALM /* Not BIOS */
316
317/* CR38 (661 and later)
318 D[7:5] 000 No VB
319 001 301 series VB
320 010 LVDS
321 011 Chrontel 7019
322 100 Conexant
323 D2 Enable YPbPr output (see CR35)
324 D[1:0] LCDA (like before)
325*/
326
327#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */
328
329/* CR39 (650 only) */
330#define LCDPass1_1 0x01 /* 0: center screen, 1: pass 1:1 data output */
331#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
332
333/* CR39 (661 and later)
334 D[7] LVDS (SiS or third party)
335 D[1:0] YPbPr Aspect Ratio
336 00 4:3 letterbox
337 01 4:3
338 10 16:9
339 11 4:3
340*/
341
342/* CR3B (651+301C)
343 D[1:0] YPbPr Aspect Ratio
344 ?
345*/
346
347/* CR79 (315/330 series only; not 661 and later)
348 [3-0] Notify driver
349 0001 Mode Switch event (set by BIOS)
350 0010 Epansion On/Off event
351 0011 TV UnderScan/OverScan event
352 0100 Set Brightness event
353 0101 Set Contrast event
354 0110 Set Mute event
355 0111 Set Volume Up/Down event
356 [4] Enable Backlight Control by BIOS/driver
357 (set by driver; set means that the BIOS should
358 not touch the backlight registers because eg.
359 the driver already switched off the backlight)
360 [5] PAL/NTSC (set by BIOS)
361 [6] Expansion On/Off (set by BIOS; copied to CR32[4])
362 [7] TV UnderScan/OverScan (set by BIOS)
363*/
364
365/* CR7C - 661 and later
366 [7] DualEdge enabled (or: to be enabled)
367 [6] CRT2 = TV/LCD/VGA enabled (or: to be enabled)
368 [5] Init done (set at end of SiS_Init)
369 {4] LVDS LCD capabilities
370 [3] LVDS LCD capabilities
371 [2] LVDS LCD capabilities (PWD)
372 [1] LVDS LCD capabilities (PWD)
373 [0] LVDS=1, TMDS=0 (SiS or third party)
374*/
375
376/* CR7E - 661 and later
377 VBType:
378 [7] LVDS (third party)
379 [3] 301C
380 [2] 302LV
381 [1] 301LV
382 [0] 301B
383*/
384
385/* LCDResInfo */
386#define Panel300_800x600 0x01 /* CR36 */
387#define Panel300_1024x768 0x02
388#define Panel300_1280x1024 0x03
389#define Panel300_1280x960 0x04
390#define Panel300_640x480 0x05
391#define Panel300_1024x600 0x06
392#define Panel300_1152x768 0x07
393#define Panel300_1280x768 0x0a
394#define Panel300_Custom 0x0f
395#define Panel300_Barco1366 0x10
396
397#define Panel310_800x600 0x01
398#define Panel310_1024x768 0x02
399#define Panel310_1280x1024 0x03
400#define Panel310_640x480 0x04
401#define Panel310_1024x600 0x05
402#define Panel310_1152x864 0x06
403#define Panel310_1280x960 0x07
404#define Panel310_1152x768 0x08 /* LVDS only */
405#define Panel310_1400x1050 0x09
406#define Panel310_1280x768 0x0a
407#define Panel310_1600x1200 0x0b
408#define Panel310_320x240_2 0x0c /* xSTN */
409#define Panel310_320x240_3 0x0d /* xSTN */
410#define Panel310_320x240_1 0x0e /* xSTN - This is fake, can be any */
411#define Panel310_Custom 0x0f
412
413#define Panel661_800x600 0x01
414#define Panel661_1024x768 0x02
415#define Panel661_1280x1024 0x03
416#define Panel661_640x480 0x04
417#define Panel661_1024x600 0x05
418#define Panel661_1152x864 0x06
419#define Panel661_1280x960 0x07
420#define Panel661_1280x854 0x08
421#define Panel661_1400x1050 0x09
422#define Panel661_1280x768 0x0a
423#define Panel661_1600x1200 0x0b
424#define Panel661_1280x800 0x0c
425#define Panel661_1680x1050 0x0d
426#define Panel661_1280x720 0x0e
427#define Panel661_Custom 0x0f
428
429#define Panel_800x600 0x01 /* Unified values */
430#define Panel_1024x768 0x02 /* MUST match BIOS values from 0-e */
431#define Panel_1280x1024 0x03
432#define Panel_640x480 0x04
433#define Panel_1024x600 0x05
434#define Panel_1152x864 0x06
435#define Panel_1280x960 0x07
436#define Panel_1152x768 0x08 /* LVDS only */
437#define Panel_1400x1050 0x09
438#define Panel_1280x768 0x0a /* 30xB/C and LVDS only (BIOS: all) */
439#define Panel_1600x1200 0x0b
440#define Panel_1280x800 0x0c /* 661etc (TMDS) */
441#define Panel_1680x1050 0x0d /* 661etc */
442#define Panel_1280x720 0x0e /* 661etc */
443#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */
444#define Panel_320x240_1 0x10 /* SiS 550 xSTN */
445#define Panel_Barco1366 0x11
446#define Panel_848x480 0x12
447#define Panel_320x240_2 0x13 /* SiS 550 xSTN */
448#define Panel_320x240_3 0x14 /* SiS 550 xSTN */
449#define Panel_1280x768_2 0x15 /* 30xLV */
450#define Panel_1280x768_3 0x16 /* (unused) */
451#define Panel_1280x800_2 0x17 /* 30xLV */
452#define Panel_856x480 0x18
453#define Panel_1280x854 0x19 /* 661etc */
454
455/* Index in ModeResInfo table */
456#define SIS_RI_320x200 0
457#define SIS_RI_320x240 1
458#define SIS_RI_320x400 2
459#define SIS_RI_400x300 3
460#define SIS_RI_512x384 4
461#define SIS_RI_640x400 5
462#define SIS_RI_640x480 6
463#define SIS_RI_800x600 7
464#define SIS_RI_1024x768 8
465#define SIS_RI_1280x1024 9
466#define SIS_RI_1600x1200 10
467#define SIS_RI_1920x1440 11
468#define SIS_RI_2048x1536 12
469#define SIS_RI_720x480 13
470#define SIS_RI_720x576 14
471#define SIS_RI_1280x960 15
472#define SIS_RI_800x480 16
473#define SIS_RI_1024x576 17
474#define SIS_RI_1280x720 18
475#define SIS_RI_856x480 19
476#define SIS_RI_1280x768 20
477#define SIS_RI_1400x1050 21
478#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
479#define SIS_RI_848x480 23
480#define SIS_RI_1360x768 24
481#define SIS_RI_1024x600 25
482#define SIS_RI_1152x768 26
483#define SIS_RI_768x576 27
484#define SIS_RI_1360x1024 28
485#define SIS_RI_1680x1050 29
486#define SIS_RI_1280x800 30
487#define SIS_RI_1920x1080 31
488#define SIS_RI_960x540 32
489#define SIS_RI_960x600 33
490#define SIS_RI_1280x854 34
491
492/* CR5F */
493#define IsM650 0x80
494
495/* Timing data */
496#define NTSCHT 1716
497#define NTSC2HT 1920
498#define NTSCVT 525
499#define PALHT 1728
500#define PALVT 625
501#define StHiTVHT 892
502#define StHiTVVT 1126
503#define StHiTextTVHT 1000
504#define StHiTextTVVT 1126
505#define ExtHiTVHT 2100
506#define ExtHiTVVT 1125
507
508/* Indices in (VB)VCLKData tables */
509
510#define VCLK28 0x00 /* Index in VCLKData table (300 and 315) */
511#define VCLK40 0x04 /* Index in VCLKData table (300 and 315) */
512#define VCLK65_300 0x09 /* Index in VCLKData table (300) */
513#define VCLK108_2_300 0x14 /* Index in VCLKData table (300) */
514#define VCLK81_300 0x3f /* Index in VCLKData table (300) */
515#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */
516#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
517#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
518#define VCLK_CUSTOM_300 0x47
519
520#define VCLK65_315 0x0b /* Indices in (VB)VCLKData table (315) */
521#define VCLK108_2_315 0x19
522#define VCLK81_315 0x5b
523#define VCLK162_315 0x5e
524#define VCLK108_3_315 0x45
525#define VCLK100_315 0x46
526#define VCLK34_315 0x55
527#define VCLK68_315 0x0d
528#define VCLK_1280x800_315_2 0x5c
529#define VCLK121_315 0x5d
530#define VCLK130_315 0x72
531#define VCLK_1280x720 0x5f
532#define VCLK_1280x768_2 0x60
533#define VCLK_1280x768_3 0x61 /* (unused?) */
534#define VCLK_CUSTOM_315 0x62
535#define VCLK_1280x720_2 0x63
536#define VCLK_720x480 0x67
537#define VCLK_720x576 0x68
538#define VCLK_768x576 0x68
539#define VCLK_848x480 0x65
540#define VCLK_856x480 0x66
541#define VCLK_800x480 0x65
542#define VCLK_1024x576 0x51
543#define VCLK_1152x864 0x64
544#define VCLK_1360x768 0x58
545#define VCLK_1280x800_315 0x6c
546#define VCLK_1280x854 0x76
547
548#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
549#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
550#define TVVCLKDIV2 0x00 /* Index relative to TVCLKBASE */
551#define TVVCLK 0x01 /* Index relative to TVCLKBASE */
552#define HiTVVCLKDIV2 0x02 /* Index relative to TVCLKBASE */
553#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */
554#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */
555#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */
556#define YPbPr750pVCLK 0x25 /* Index relative to TVCLKBASE; was 0x0f NOT relative */
557
558/* ------------------------------ */
559
560#define SetSCARTOutput 0x01
561
562#define HotPlugFunction 0x08
563
564#define StStructSize 0x06
565
566#define SIS_VIDEO_CAPTURE 0x00 - 0x30
567#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
568#define SIS_CRT2_PORT_04 0x04 - 0x30
569#define SIS_CRT2_PORT_10 0x10 - 0x30
570#define SIS_CRT2_PORT_12 0x12 - 0x30
571#define SIS_CRT2_PORT_14 0x14 - 0x30
572
573#define ADR_CRT2PtrData 0x20E
574#define offset_Zurac 0x210 /* TW: Trumpion Zurac data pointer */
575#define ADR_LVDSDesPtrData 0x212
576#define ADR_LVDSCRT1DataPtr 0x214
577#define ADR_CHTVVCLKPtr 0x216
578#define ADR_CHTVRegDataPtr 0x218
579
580#define LCDDataLen 8
581#define HiTVDataLen 12
582#define TVDataLen 16
583
584#define LVDSDataLen 6
585#define LVDSDesDataLen 3
586#define ActiveNonExpanding 0x40
587#define ActiveNonExpandingShift 6
588#define ActivePAL 0x20
589#define ActivePALShift 5
590#define ModeSwitchStatus 0x0F
591#define SoftTVType 0x40
592#define SoftSettingAddr 0x52
593#define ModeSettingAddr 0x53
594
595#define _PanelType00 0x00
596#define _PanelType01 0x08
597#define _PanelType02 0x10
598#define _PanelType03 0x18
599#define _PanelType04 0x20
600#define _PanelType05 0x28
601#define _PanelType06 0x30
602#define _PanelType07 0x38
603#define _PanelType08 0x40
604#define _PanelType09 0x48
605#define _PanelType0A 0x50
606#define _PanelType0B 0x58
607#define _PanelType0C 0x60
608#define _PanelType0D 0x68
609#define _PanelType0E 0x70
610#define _PanelType0F 0x78
611
612#define PRIMARY_VGA 0 /* 1: SiS is primary vga 0:SiS is secondary vga */
613
614#define BIOSIDCodeAddr 0x235 /* Offsets to ptrs in BIOS image */
615#define OEMUtilIDCodeAddr 0x237
616#define VBModeIDTableAddr 0x239
617#define OEMTVPtrAddr 0x241
618#define PhaseTableAddr 0x243
619#define NTSCFilterTableAddr 0x245
620#define PALFilterTableAddr 0x247
621#define OEMLCDPtr_1Addr 0x249
622#define OEMLCDPtr_2Addr 0x24B
623#define LCDHPosTable_1Addr 0x24D
624#define LCDHPosTable_2Addr 0x24F
625#define LCDVPosTable_1Addr 0x251
626#define LCDVPosTable_2Addr 0x253
627#define OEMLCDPIDTableAddr 0x255
628
629#define VBModeStructSize 5
630#define PhaseTableSize 4
631#define FilterTableSize 4
632#define LCDHPosTableSize 7
633#define LCDVPosTableSize 5
634#define OEMLVDSPIDTableSize 4
635#define LVDSHPosTableSize 4
636#define LVDSVPosTableSize 6
637
638#define VB_ModeID 0
639#define VB_TVTableIndex 1
640#define VB_LCDTableIndex 2
641#define VB_LCDHIndex 3
642#define VB_LCDVIndex 4
643
644#define OEMLCDEnable 0x0001
645#define OEMLCDDelayEnable 0x0002
646#define OEMLCDPOSEnable 0x0004
647#define OEMTVEnable 0x0100
648#define OEMTVDelayEnable 0x0200
649#define OEMTVFlickerEnable 0x0400
650#define OEMTVPhaseEnable 0x0800
651#define OEMTVFilterEnable 0x1000
652
653#define OEMLCDPanelIDSupport 0x0080
654
655/*
656 =============================================================
657 for 315 series (old data layout)
658 =============================================================
659*/
660#define SoftDRAMType 0x80
661#define SoftSetting_OFFSET 0x52
662#define SR07_OFFSET 0x7C
663#define SR15_OFFSET 0x7D
664#define SR16_OFFSET 0x81
665#define SR17_OFFSET 0x85
666#define SR19_OFFSET 0x8D
667#define SR1F_OFFSET 0x99
668#define SR21_OFFSET 0x9A
669#define SR22_OFFSET 0x9B
670#define SR23_OFFSET 0x9C
671#define SR24_OFFSET 0x9D
672#define SR25_OFFSET 0x9E
673#define SR31_OFFSET 0x9F
674#define SR32_OFFSET 0xA0
675#define SR33_OFFSET 0xA1
676
677#define CR40_OFFSET 0xA2
678#define SR25_1_OFFSET 0xF6
679#define CR49_OFFSET 0xF7
680
681#define VB310Data_1_2_Offset 0xB6
682#define VB310Data_4_D_Offset 0xB7
683#define VB310Data_4_E_Offset 0xB8
684#define VB310Data_4_10_Offset 0xBB
685
686#define RGBSenseDataOffset 0xBD
687#define YCSenseDataOffset 0xBF
688#define VideoSenseDataOffset 0xC1
689#define OutputSelectOffset 0xF3
690
691#define ECLK_MCLK_DISTANCE 0x14
692#define VBIOSTablePointerStart 0x100
693#define StandTablePtrOffset VBIOSTablePointerStart+0x02
694#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04
695#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06
696#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08
697#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A
698#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E
699#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10
700#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12
701#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14
702#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16
703#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18
704#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20
705#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24
706#define CRT2Delay1Offset VBIOSTablePointerStart+0x28
707
708#endif
diff --git a/drivers/video/fbdev/sis/initextlfb.c b/drivers/video/fbdev/sis/initextlfb.c
new file mode 100644
index 000000000000..3ab18f5a3759
--- /dev/null
+++ b/drivers/video/fbdev/sis/initextlfb.c
@@ -0,0 +1,231 @@
1/*
2 * SiS 300/540/630[S]/730[S]
3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX]
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
6 *
7 * Linux kernel specific extensions to init.c/init301.c
8 *
9 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the named License,
14 * or any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Author: Thomas Winischhofer <thomas@winischhofer.net>
26 */
27
28#include "initdef.h"
29#include "vgatypes.h"
30#include "vstruct.h"
31
32#include <linux/types.h>
33#include <linux/fb.h>
34
35int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
36 unsigned char modeno, unsigned char rateindex);
37int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
38 unsigned char rateindex, struct fb_var_screeninfo *var);
39bool sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
40 int *htotal, int *vtotal, unsigned char rateindex);
41
42extern bool SiSInitPtr(struct SiS_Private *SiS_Pr);
43extern bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
44 unsigned short *ModeIdIndex);
45extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
46 int xres, int yres, struct fb_var_screeninfo *var, bool writeres);
47
48int
49sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
50 unsigned char rateindex)
51{
52 unsigned short ModeNo = modeno;
53 unsigned short ModeIdIndex = 0, ClockIndex = 0;
54 unsigned short RRTI = 0;
55 int Clock;
56
57 if(!SiSInitPtr(SiS_Pr)) return 65000;
58
59 if(rateindex > 0) rateindex--;
60
61#ifdef CONFIG_FB_SIS_315
62 switch(ModeNo) {
63 case 0x5a: ModeNo = 0x50; break;
64 case 0x5b: ModeNo = 0x56;
65 }
66#endif
67
68 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {
69 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
70 return 65000;
71 }
72
73 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
74
75 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
76 if(SiS_Pr->SiS_UseWide == 1) {
77 /* Wide screen: Ignore rateindex */
78 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_WIDE;
79 } else {
80 RRTI += rateindex;
81 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_NORM;
82 }
83 } else {
84 RRTI += rateindex;
85 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK;
86 }
87
88 Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
89
90 return Clock;
91}
92
93int
94sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
95 unsigned char rateindex, struct fb_var_screeninfo *var)
96{
97 unsigned short ModeNo = modeno;
98 unsigned short ModeIdIndex = 0, index = 0, RRTI = 0;
99 int j;
100
101 if(!SiSInitPtr(SiS_Pr)) return 0;
102
103 if(rateindex > 0) rateindex--;
104
105#ifdef CONFIG_FB_SIS_315
106 switch(ModeNo) {
107 case 0x5a: ModeNo = 0x50; break;
108 case 0x5b: ModeNo = 0x56;
109 }
110#endif
111
112 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
113
114 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
115 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
116 if(SiS_Pr->SiS_UseWide == 1) {
117 /* Wide screen: Ignore rateindex */
118 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
119 } else {
120 RRTI += rateindex;
121 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
122 }
123 } else {
124 RRTI += rateindex;
125 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
126 }
127
128 SiS_Generic_ConvertCRData(SiS_Pr,
129 (unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
130 SiS_Pr->SiS_RefIndex[RRTI].XRes,
131 SiS_Pr->SiS_RefIndex[RRTI].YRes,
132 var, false);
133
134 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
135 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
136 else
137 var->sync |= FB_SYNC_VERT_HIGH_ACT;
138
139 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x4000)
140 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
141 else
142 var->sync |= FB_SYNC_HOR_HIGH_ACT;
143
144 var->vmode = FB_VMODE_NONINTERLACED;
145 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x0080)
146 var->vmode = FB_VMODE_INTERLACED;
147 else {
148 j = 0;
149 while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
150 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
151 SiS_Pr->SiS_RefIndex[RRTI].ModeID) {
152 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
153 var->vmode = FB_VMODE_DOUBLE;
154 }
155 break;
156 }
157 j++;
158 }
159 }
160
161 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
162#if 0 /* Do this? */
163 var->upper_margin <<= 1;
164 var->lower_margin <<= 1;
165 var->vsync_len <<= 1;
166#endif
167 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
168 var->upper_margin >>= 1;
169 var->lower_margin >>= 1;
170 var->vsync_len >>= 1;
171 }
172
173 return 1;
174}
175
176bool
177sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
178 int *vtotal, unsigned char rateindex)
179{
180 unsigned short ModeNo = modeno;
181 unsigned short ModeIdIndex = 0, CRT1Index = 0;
182 unsigned short RRTI = 0;
183 unsigned char sr_data, cr_data, cr_data2;
184
185 if(!SiSInitPtr(SiS_Pr)) return false;
186
187 if(rateindex > 0) rateindex--;
188
189#ifdef CONFIG_FB_SIS_315
190 switch(ModeNo) {
191 case 0x5a: ModeNo = 0x50; break;
192 case 0x5b: ModeNo = 0x56;
193 }
194#endif
195
196 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
197
198 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
199 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
200 if(SiS_Pr->SiS_UseWide == 1) {
201 /* Wide screen: Ignore rateindex */
202 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
203 } else {
204 RRTI += rateindex;
205 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
206 }
207 } else {
208 RRTI += rateindex;
209 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
210 }
211
212 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
213 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
214 *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
215
216 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
217 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
218 cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
219 *vtotal = ((cr_data & 0xFF) |
220 ((unsigned short)(cr_data2 & 0x01) << 8) |
221 ((unsigned short)(cr_data2 & 0x20) << 4) |
222 ((unsigned short)(sr_data & 0x01) << 10)) + 2;
223
224 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
225 *vtotal *= 2;
226
227 return true;
228}
229
230
231
diff --git a/drivers/video/fbdev/sis/oem300.h b/drivers/video/fbdev/sis/oem300.h
new file mode 100644
index 000000000000..b73f26840143
--- /dev/null
+++ b/drivers/video/fbdev/sis/oem300.h
@@ -0,0 +1,840 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * OEM Data for 300 series
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const unsigned char SiS300_OEMTVDelay301[8][4] =
54{
55 {0x08,0x08,0x08,0x08},
56 {0x08,0x08,0x08,0x08},
57 {0x08,0x08,0x08,0x08},
58 {0x2c,0x2c,0x2c,0x2c},
59 {0x08,0x08,0x08,0x08},
60 {0x08,0x08,0x08,0x08},
61 {0x08,0x08,0x08,0x08},
62 {0x20,0x20,0x20,0x20}
63};
64
65static const unsigned char SiS300_OEMTVDelayLVDS[8][4] =
66{
67 {0x20,0x20,0x20,0x20},
68 {0x20,0x20,0x20,0x20},
69 {0x20,0x20,0x20,0x20},
70 {0x20,0x20,0x20,0x20},
71 {0x20,0x20,0x20,0x20},
72 {0x20,0x20,0x20,0x20},
73 {0x20,0x20,0x20,0x20},
74 {0x20,0x20,0x20,0x20}
75};
76
77static const unsigned char SiS300_OEMTVFlicker[8][4] =
78{
79 {0x00,0x00,0x00,0x00},
80 {0x00,0x00,0x00,0x00},
81 {0x00,0x00,0x00,0x00},
82 {0x00,0x00,0x00,0x00},
83 {0x00,0x00,0x00,0x00},
84 {0x00,0x00,0x00,0x00},
85 {0x00,0x00,0x00,0x00},
86 {0x00,0x00,0x00,0x00}
87};
88
89static const unsigned char SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
90{
91 {0x20,0x20,0x20,0x20},
92 {0x20,0x20,0x20,0x20},
93 {0x20,0x20,0x20,0x20},
94 {0x20,0x20,0x20,0x20},
95 {0x20,0x20,0x20,0x20},
96 {0x20,0x20,0x20,0x20},
97 {0x20,0x20,0x20,0x20},
98 {0x20,0x20,0x20,0x20},
99 {0x20,0x20,0x20,0x20},
100 {0x20,0x20,0x20,0x20},
101 {0x20,0x20,0x20,0x20},
102 {0x20,0x20,0x20,0x20},
103 {0x20,0x20,0x20,0x20},
104 {0x20,0x20,0x20,0x20},
105 {0x20,0x20,0x20,0x20},
106 {0x20,0x20,0x20,0x20},
107 {0x20,0x20,0x20,0x20},
108 {0x20,0x20,0x20,0x20},
109 {0x20,0x20,0x20,0x20},
110 {0x20,0x20,0x20,0x20},
111 {0x20,0x20,0x20,0x20},
112 {0x20,0x20,0x20,0x20},
113 {0x20,0x20,0x20,0x20},
114 {0x20,0x20,0x20,0x20},
115 {0x20,0x20,0x20,0x20},
116 {0x20,0x20,0x20,0x20},
117 {0x20,0x20,0x20,0x20},
118 {0x20,0x20,0x20,0x20},
119 {0x20,0x20,0x20,0x20},
120 {0x20,0x20,0x20,0x20},
121 {0x20,0x20,0x20,0x20},
122 {0x20,0x20,0x20,0x20},
123 {0x20,0x20,0x20,0x20},
124 {0x20,0x20,0x20,0x20},
125 {0x20,0x20,0x20,0x20},
126 {0x20,0x20,0x20,0x20},
127 {0x20,0x20,0x20,0x20},
128 {0x20,0x20,0x20,0x20},
129 {0x20,0x20,0x20,0x20},
130 {0x20,0x20,0x20,0x20},
131 {0x20,0x20,0x20,0x20},
132 {0x20,0x20,0x20,0x20},
133 {0x20,0x20,0x20,0x20},
134 {0x20,0x20,0x20,0x20},
135 {0x20,0x20,0x20,0x20},
136 {0x20,0x20,0x20,0x20},
137 {0x20,0x20,0x20,0x20},
138 {0x20,0x20,0x20,0x20},
139 {0x20,0x20,0x20,0x20},
140 {0x20,0x20,0x20,0x20},
141 {0x20,0x20,0x20,0x20},
142 {0x20,0x20,0x20,0x20},
143 {0x20,0x20,0x20,0x20},
144 {0x20,0x20,0x20,0x20},
145 {0x20,0x20,0x20,0x20},
146 {0x20,0x20,0x20,0x20},
147 {0x20,0x20,0x20,0x20},
148 {0x20,0x20,0x20,0x20},
149 {0x20,0x20,0x20,0x20},
150 {0x20,0x20,0x20,0x20},
151 {0x20,0x20,0x20,0x20},
152 {0x20,0x20,0x20,0x20},
153 {0x20,0x20,0x20,0x20},
154 {0x20,0x20,0x20,0x20}
155};
156
157static const unsigned char SiS300_OEMLCDDelay4[12][4] =
158{
159 {0x2c,0x2c,0x2c,0x2c},
160 {0x20,0x20,0x20,0x20},
161 {0x20,0x20,0x20,0x20},
162 {0x2c,0x2c,0x2c,0x2c},
163 {0x2c,0x2c,0x2c,0x2c},
164 {0x20,0x20,0x20,0x20},
165 {0x20,0x20,0x20,0x20},
166 {0x24,0x24,0x24,0x24},
167 {0x24,0x24,0x24,0x24},
168 {0x20,0x20,0x20,0x20},
169 {0x20,0x20,0x20,0x20},
170 {0x24,0x24,0x24,0x24}
171};
172
173static const unsigned char SiS300_OEMLCDDelay5[32][4] =
174{
175 {0x20,0x20,0x20,0x20},
176 {0x20,0x20,0x20,0x20},
177 {0x20,0x20,0x20,0x20},
178 {0x20,0x20,0x20,0x20},
179 {0x20,0x20,0x20,0x20},
180 {0x20,0x20,0x20,0x20},
181 {0x20,0x20,0x20,0x20},
182 {0x20,0x20,0x20,0x20},
183 {0x20,0x20,0x20,0x20},
184 {0x20,0x20,0x20,0x20},
185 {0x20,0x20,0x20,0x20},
186 {0x20,0x20,0x20,0x20},
187 {0x20,0x20,0x20,0x20},
188 {0x20,0x20,0x20,0x20},
189 {0x20,0x20,0x20,0x20},
190 {0x20,0x20,0x20,0x20},
191 {0x20,0x20,0x20,0x20},
192 {0x20,0x20,0x20,0x20},
193 {0x20,0x20,0x20,0x20},
194 {0x20,0x20,0x20,0x20},
195 {0x20,0x20,0x20,0x20},
196 {0x20,0x20,0x20,0x20},
197 {0x20,0x20,0x20,0x20},
198 {0x20,0x20,0x20,0x20},
199 {0x20,0x20,0x20,0x20},
200 {0x20,0x20,0x20,0x20},
201 {0x20,0x20,0x20,0x20},
202 {0x20,0x20,0x20,0x20},
203 {0x20,0x20,0x20,0x20},
204 {0x20,0x20,0x20,0x20},
205 {0x20,0x20,0x20,0x20},
206 {0x20,0x20,0x20,0x20},
207};
208
209static const unsigned char SiS300_OEMLCDDelay3[64][4] = /* For LVDS */
210{
211 {0x20,0x20,0x20,0x20},
212 {0x20,0x20,0x20,0x20},
213 {0x20,0x20,0x20,0x20},
214 {0x20,0x20,0x20,0x20},
215 {0x20,0x20,0x20,0x20},
216 {0x20,0x20,0x20,0x20},
217 {0x20,0x20,0x20,0x20},
218 {0x20,0x20,0x20,0x20},
219 {0x20,0x20,0x20,0x20},
220 {0x20,0x20,0x20,0x20},
221 {0x20,0x20,0x20,0x20},
222 {0x20,0x20,0x20,0x20},
223 {0x20,0x20,0x20,0x20},
224 {0x20,0x20,0x20,0x20},
225 {0x20,0x20,0x20,0x20},
226 {0x20,0x20,0x20,0x20},
227 {0x20,0x20,0x20,0x20},
228 {0x20,0x20,0x20,0x20},
229 {0x20,0x20,0x20,0x20},
230 {0x20,0x20,0x20,0x20},
231 {0x20,0x20,0x20,0x20},
232 {0x20,0x20,0x20,0x20},
233 {0x20,0x20,0x20,0x20},
234 {0x20,0x20,0x20,0x20},
235 {0x20,0x20,0x20,0x20},
236 {0x20,0x20,0x20,0x20},
237 {0x20,0x20,0x20,0x20},
238 {0x20,0x20,0x20,0x20},
239 {0x20,0x20,0x20,0x20},
240 {0x20,0x20,0x20,0x20},
241 {0x20,0x20,0x20,0x20},
242 {0x20,0x20,0x20,0x20},
243 {0x20,0x20,0x20,0x20},
244 {0x20,0x20,0x20,0x20},
245 {0x20,0x20,0x20,0x20},
246 {0x20,0x20,0x20,0x20},
247 {0x20,0x20,0x20,0x20},
248 {0x20,0x20,0x20,0x20},
249 {0x20,0x20,0x20,0x20},
250 {0x20,0x20,0x20,0x20},
251 {0x20,0x20,0x20,0x20},
252 {0x20,0x20,0x20,0x20},
253 {0x20,0x20,0x20,0x20},
254 {0x20,0x20,0x20,0x20},
255 {0x20,0x20,0x20,0x20},
256 {0x20,0x20,0x20,0x20},
257 {0x20,0x20,0x20,0x20},
258 {0x20,0x20,0x20,0x20},
259 {0x20,0x20,0x20,0x20},
260 {0x20,0x20,0x20,0x20},
261 {0x20,0x20,0x20,0x20},
262 {0x20,0x20,0x20,0x20},
263 {0x20,0x20,0x20,0x20},
264 {0x20,0x20,0x20,0x20},
265 {0x20,0x20,0x20,0x20},
266 {0x20,0x20,0x20,0x20},
267 {0x20,0x20,0x20,0x20},
268 {0x20,0x20,0x20,0x20},
269 {0x20,0x20,0x20,0x20},
270 {0x20,0x20,0x20,0x20},
271 {0x20,0x20,0x20,0x20},
272 {0x20,0x20,0x20,0x20},
273 {0x20,0x20,0x20,0x20},
274 {0x20,0x20,0x20,0x20}
275};
276
277static const unsigned char SiS300_Phase1[8][5][4] =
278{
279 {
280 {0x21,0xed,0x00,0x08},
281 {0x21,0xed,0x8a,0x08},
282 {0x21,0xed,0x8a,0x08},
283 {0x21,0xed,0x8a,0x08},
284 {0x21,0xed,0x8a,0x08}
285 },
286 {
287 {0x2a,0x05,0xd3,0x00},
288 {0x2a,0x05,0xd3,0x00},
289 {0x2a,0x05,0xd3,0x00},
290 {0x2a,0x05,0xd3,0x00},
291 {0x2a,0x05,0xd3,0x00}
292 },
293 {
294 {0x2a,0x05,0xd3,0x00},
295 {0x2a,0x05,0xd3,0x00},
296 {0x2a,0x05,0xd3,0x00},
297 {0x2a,0x05,0xd3,0x00},
298 {0x2a,0x05,0xd3,0x00}
299 },
300 {
301 {0x2a,0x05,0xd3,0x00},
302 {0x2a,0x05,0xd3,0x00},
303 {0x2a,0x05,0xd3,0x00},
304 {0x2a,0x05,0xd3,0x00},
305 {0x2a,0x05,0xd3,0x00}
306 },
307 {
308 {0x21,0xed,0x00,0x08},
309 {0x21,0xed,0x8a,0x08},
310 {0x21,0xed,0x8a,0x08},
311 {0x21,0xed,0x8a,0x08},
312 {0x21,0xed,0x8a,0x08}
313 },
314 {
315 {0x2a,0x05,0xd3,0x00},
316 {0x2a,0x05,0xd3,0x00},
317 {0x2a,0x05,0xd3,0x00},
318 {0x2a,0x05,0xd3,0x00},
319 {0x2a,0x05,0xd3,0x00}
320 },
321 {
322 {0x2a,0x05,0xd3,0x00},
323 {0x2a,0x05,0xd3,0x00},
324 {0x2a,0x05,0xd3,0x00},
325 {0x2a,0x05,0xd3,0x00},
326 {0x2a,0x05,0xd3,0x00}
327 },
328 {
329 {0x2a,0x05,0xd3,0x00},
330 {0x2a,0x05,0xd3,0x00},
331 {0x2a,0x05,0xd3,0x00},
332 {0x2a,0x05,0xd3,0x00},
333 {0x2a,0x05,0xd3,0x00}
334 }
335};
336
337static const unsigned char SiS300_Phase2[8][5][4] =
338{
339 {
340 {0x21,0xed,0x00,0x08},
341 {0x21,0xed,0x8a,0x08},
342 {0x21,0xed,0x8a,0x08},
343 {0x21,0xed,0x8a,0x08},
344 {0x21,0xed,0x8a,0x08}
345 },
346 {
347 {0x2a,0x05,0xd3,0x00},
348 {0x2a,0x05,0xd3,0x00},
349 {0x2a,0x05,0xd3,0x00},
350 {0x2a,0x05,0xd3,0x00},
351 {0x2a,0x05,0xd3,0x00}
352 },
353 {
354 {0x2a,0x05,0xd3,0x00},
355 {0x2a,0x05,0xd3,0x00},
356 {0x2a,0x05,0xd3,0x00},
357 {0x2a,0x05,0xd3,0x00},
358 {0x2a,0x05,0xd3,0x00}
359 },
360 {
361 {0x2a,0x05,0xd3,0x00},
362 {0x2a,0x05,0xd3,0x00},
363 {0x2a,0x05,0xd3,0x00},
364 {0x2a,0x05,0xd3,0x00},
365 {0x2a,0x05,0xd3,0x00}
366 },
367 {
368 {0x21,0xed,0x00,0x08},
369 {0x21,0xed,0x8a,0x08},
370 {0x21,0xed,0x8a,0x08},
371 {0x21,0xed,0x8a,0x08},
372 {0x21,0xed,0x8a,0x08}
373 },
374 {
375 {0x2a,0x05,0xd3,0x00},
376 {0x2a,0x05,0xd3,0x00},
377 {0x2a,0x05,0xd3,0x00},
378 {0x2a,0x05,0xd3,0x00},
379 {0x2a,0x05,0xd3,0x00}
380 },
381 {
382 {0x2a,0x05,0xd3,0x00},
383 {0x2a,0x05,0xd3,0x00},
384 {0x2a,0x05,0xd3,0x00},
385 {0x2a,0x05,0xd3,0x00},
386 {0x2a,0x05,0xd3,0x00}
387 },
388 {
389 {0x2a,0x05,0xd3,0x00},
390 {0x2a,0x05,0xd3,0x00},
391 {0x2a,0x05,0xd3,0x00},
392 {0x2a,0x05,0xd3,0x00},
393 {0x2a,0x05,0xd3,0x00}
394 }
395};
396
397static const unsigned char SiS300_Filter1[10][16][4] =
398{
399 {
400 {0x00,0xf4,0x10,0x38},
401 {0x00,0xf4,0x10,0x38},
402 {0xeb,0x04,0x10,0x18},
403 {0xf7,0x06,0x19,0x14},
404 {0x00,0xf4,0x10,0x38},
405 {0xeb,0x04,0x25,0x18},
406 {0xeb,0x04,0x25,0x18},
407 {0xeb,0x15,0x25,0xf6},
408 {0xeb,0x04,0x25,0x18},
409 {0xeb,0x04,0x25,0x18},
410 {0xeb,0x04,0x25,0x18},
411 {0xeb,0x04,0x25,0x18},
412 {0xeb,0x04,0x25,0x18},
413 {0xeb,0x04,0x25,0x18},
414 {0xeb,0x04,0x25,0x18},
415 {0xeb,0x04,0x25,0x18}
416 },
417 {
418 {0x00,0xf4,0x10,0x38},
419 {0x00,0xf4,0x10,0x38},
420 {0xf1,0xf7,0x10,0x32},
421 {0xf3,0x00,0x1d,0x20},
422 {0x00,0xf4,0x10,0x38},
423 {0xf1,0xf7,0x1f,0x32},
424 {0xf1,0xf7,0x1f,0x32},
425 {0xfc,0xfb,0x14,0x2a},
426 {0xf1,0xf7,0x1f,0x32},
427 {0xf1,0xf7,0x1f,0x32},
428 {0xf1,0xf7,0x1f,0x32},
429 {0xf1,0xf7,0x1f,0x32},
430 {0xf1,0xf7,0x1f,0x32},
431 {0xf1,0xf7,0x1f,0x32},
432 {0xf1,0xf7,0x1f,0x32},
433 {0xf1,0xf7,0x1f,0x32}
434 },
435 {
436 {0x00,0xf4,0x10,0x38},
437 {0x00,0xf4,0x10,0x38},
438 {0xf1,0xf7,0x10,0x32},
439 {0xf3,0x00,0x1d,0x20},
440 {0x00,0xf4,0x10,0x38},
441 {0xf1,0xf7,0x1f,0x32},
442 {0xf1,0xf7,0x1f,0x32},
443 {0xfc,0xfb,0x14,0x2a},
444 {0xf1,0xf7,0x1f,0x32},
445 {0xf1,0xf7,0x1f,0x32},
446 {0xf1,0xf7,0x1f,0x32},
447 {0xf1,0xf7,0x1f,0x32},
448 {0xf1,0xf7,0x1f,0x32},
449 {0xf1,0xf7,0x1f,0x32},
450 {0xf1,0xf7,0x1f,0x32},
451 {0xf1,0xf7,0x1f,0x32}
452 },
453 {
454 {0x00,0xf4,0x10,0x38},
455 {0x00,0xf4,0x10,0x38},
456 {0xf1,0xf7,0x10,0x32},
457 {0xf3,0x00,0x1d,0x20},
458 {0x00,0xf4,0x10,0x38},
459 {0xf1,0xf7,0x1f,0x32},
460 {0xf1,0xf7,0x1f,0x32},
461 {0xfc,0xfb,0x14,0x2a},
462 {0xf1,0xf7,0x1f,0x32},
463 {0xf1,0xf7,0x1f,0x32},
464 {0xf1,0xf7,0x1f,0x32},
465 {0xf1,0xf7,0x1f,0x32},
466 {0xf1,0xf7,0x1f,0x32},
467 {0xf1,0xf7,0x1f,0x32},
468 {0xf1,0xf7,0x1f,0x32},
469 {0xf1,0xf7,0x1f,0x32}
470 },
471 {
472 {0x00,0xf4,0x10,0x38},
473 {0x00,0xf4,0x10,0x38},
474 {0xeb,0x04,0x10,0x18},
475 {0xf7,0x06,0x19,0x14},
476 {0x00,0xf4,0x10,0x38},
477 {0xeb,0x04,0x25,0x18},
478 {0xeb,0x04,0x25,0x18},
479 {0xeb,0x15,0x25,0xf6},
480 {0xeb,0x04,0x25,0x18},
481 {0xeb,0x04,0x25,0x18},
482 {0xeb,0x04,0x25,0x18},
483 {0xeb,0x04,0x25,0x18},
484 {0xeb,0x04,0x25,0x18},
485 {0xeb,0x04,0x25,0x18},
486 {0xeb,0x04,0x25,0x18},
487 {0xeb,0x04,0x25,0x18}
488 },
489 {
490 {0x00,0xf4,0x10,0x38},
491 {0x00,0xf4,0x10,0x38},
492 {0xf1,0xf7,0x10,0x32},
493 {0xf3,0x00,0x1d,0x20},
494 {0x00,0xf4,0x10,0x38},
495 {0xf1,0xf7,0x1f,0x32},
496 {0xf1,0xf7,0x1f,0x32},
497 {0xfc,0xfb,0x14,0x2a},
498 {0xf1,0xf7,0x1f,0x32},
499 {0xf1,0xf7,0x1f,0x32},
500 {0xf1,0xf7,0x1f,0x32},
501 {0xf1,0xf7,0x1f,0x32},
502 {0xf1,0xf7,0x1f,0x32},
503 {0xf1,0xf7,0x1f,0x32},
504 {0xf1,0xf7,0x1f,0x32},
505 {0xf1,0xf7,0x1f,0x32}
506 },
507 {
508 {0x00,0xf4,0x10,0x38},
509 {0x00,0xf4,0x10,0x38},
510 {0xf1,0xf7,0x10,0x32},
511 {0xf3,0x00,0x1d,0x20},
512 {0x00,0xf4,0x10,0x38},
513 {0xf1,0xf7,0x1f,0x32},
514 {0xf1,0xf7,0x1f,0x32},
515 {0xfc,0xfb,0x14,0x2a},
516 {0xf1,0xf7,0x1f,0x32},
517 {0xf1,0xf7,0x1f,0x32},
518 {0xf1,0xf7,0x1f,0x32},
519 {0xf1,0xf7,0x1f,0x32},
520 {0xf1,0xf7,0x1f,0x32},
521 {0xf1,0xf7,0x1f,0x32},
522 {0xf1,0xf7,0x1f,0x32},
523 {0xf1,0xf7,0x1f,0x32}
524 },
525 {
526 {0x00,0xf4,0x10,0x38},
527 {0x00,0xf4,0x10,0x38},
528 {0xf1,0xf7,0x10,0x32},
529 {0xf3,0x00,0x1d,0x20},
530 {0x00,0xf4,0x10,0x38},
531 {0xf1,0xf7,0x1f,0x32},
532 {0xf1,0xf7,0x1f,0x32},
533 {0xfc,0xfb,0x14,0x2a},
534 {0xf1,0xf7,0x1f,0x32},
535 {0xf1,0xf7,0x1f,0x32},
536 {0xf1,0xf7,0x1f,0x32},
537 {0xf1,0xf7,0x1f,0x32},
538 {0xf1,0xf7,0x1f,0x32},
539 {0xf1,0xf7,0x1f,0x32},
540 {0xf1,0xf7,0x1f,0x32},
541 {0xf1,0xf7,0x1f,0x32}
542 },
543 {
544 {0x00,0xf4,0x10,0x38},
545 {0x00,0xf4,0x10,0x38},
546 {0xeb,0x04,0x10,0x18},
547 {0xf7,0x06,0x19,0x14},
548 {0x00,0xf4,0x10,0x38},
549 {0xeb,0x04,0x25,0x18},
550 {0xeb,0x04,0x25,0x18},
551 {0xeb,0x15,0x25,0xf6},
552 {0xeb,0x04,0x25,0x18},
553 {0xeb,0x04,0x25,0x18},
554 {0xeb,0x04,0x25,0x18},
555 {0xeb,0x04,0x25,0x18},
556 {0xeb,0x04,0x25,0x18},
557 {0xeb,0x04,0x25,0x18},
558 {0xeb,0x04,0x25,0x18},
559 {0xeb,0x04,0x25,0x18}
560 },
561 {
562 {0x00,0xf4,0x10,0x38},
563 {0x00,0xf4,0x10,0x38},
564 {0xeb,0x04,0x10,0x18},
565 {0xf7,0x06,0x19,0x14},
566 {0x00,0xf4,0x10,0x38},
567 {0xeb,0x04,0x25,0x18},
568 {0xeb,0x04,0x25,0x18},
569 {0xeb,0x15,0x25,0xf6},
570 {0xeb,0x04,0x25,0x18},
571 {0xeb,0x04,0x25,0x18},
572 {0xeb,0x04,0x25,0x18},
573 {0xeb,0x04,0x25,0x18},
574 {0xeb,0x04,0x25,0x18},
575 {0xeb,0x04,0x25,0x18},
576 {0xeb,0x04,0x25,0x18},
577 {0xeb,0x04,0x25,0x18}
578 },
579};
580
581static const unsigned char SiS300_Filter2[10][9][7] =
582{
583 {
584 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
585 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
586 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
587 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
588 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
589 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
590 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
591 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
592 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
593 },
594 {
595 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
596 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
597 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
598 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
599 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
600 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
601 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
602 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
603 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
604 },
605 {
606 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
607 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
608 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
609 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
610 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
611 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
612 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
613 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
614 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
615 },
616 {
617 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
618 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
619 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
620 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
621 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
622 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
623 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
624 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
625 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
626 },
627 {
628 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
629 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
630 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
631 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
632 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
633 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
634 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
635 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
636 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
637 },
638 {
639 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
640 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
641 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
642 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
643 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
644 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
645 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
646 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
647 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
648 },
649 {
650 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
651 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
652 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
653 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
654 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
655 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
656 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
657 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
658 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
659 },
660 {
661 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
662 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
663 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
664 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
665 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
666 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
667 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
668 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
669 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
670 },
671 {
672 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
673 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
674 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
675 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
676 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
677 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
678 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
679 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
680 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
681 },
682 {
683 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
684 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
685 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
686 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
687 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
688 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
689 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
690 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
691 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
692 }
693};
694
695/* Custom data for Barco iQ Pro R300 */
696static const unsigned char barco_p1[2][9][7][3] =
697{
698 {
699 {
700 { 0x16, 0xcf, 0x00 },
701 { 0x18, 0x00, 0x00 },
702 { 0x1a, 0xe7, 0x00 },
703 { 0x1b, 0x26, 0x00 },
704 { 0x1c, 0xff, 0x00 },
705 { 0x1d, 0x1c, 0x00 },
706 { 0x1e, 0x19, 0x00 }
707 },
708 {
709 { 0x16, 0xcf, 0x00 },
710 { 0x18, 0x00, 0x00 },
711 { 0x1a, 0xe7, 0x00 },
712 { 0x1b, 0x1e, 0x00 },
713 { 0x1c, 0xff, 0x00 },
714 { 0x1d, 0x1c, 0x00 },
715 { 0x1e, 0x16, 0x00 }
716 },
717 {
718 { 0x16, 0xcf, 0x00 },
719 { 0x1a, 0xe7, 0x00 },
720 { 0x1b, 0x26, 0x00 },
721 { 0x1c, 0xff, 0x00 },
722 { 0x1d, 0x1c, 0x00 },
723 { 0x1e, 0x19, 0x00 },
724 { 0, 0, 0 }
725 },
726 {
727 { 0, 0, 0 }
728 },
729 {
730 { 0x16, 0xcf, 0x00 },
731 { 0x1a, 0xe7, 0x00 },
732 { 0x1b, 0x26, 0x00 },
733 { 0x1c, 0xff, 0x00 },
734 { 0x1d, 0x1c, 0x00 },
735 { 0x1e, 0x1e, 0x00 },
736 { 0, 0, 0 }
737 },
738 {
739 { 0x16, 0xd1, 0x00 },
740 { 0x18, 0x00, 0x00 },
741 { 0x1a, 0xe7, 0x00 },
742 { 0x1b, 0x11, 0x00 },
743 { 0x1c, 0xff, 0x00 },
744 { 0x1d, 0x1c, 0x00 },
745 { 0x1e, 0x26, 0x00 }
746 },
747 {
748 { 0x16, 0xd1, 0x00 },
749 { 0x1a, 0xe7, 0x00 },
750 { 0x1b, 0x26, 0x00 },
751 { 0x1c, 0xff, 0x00 },
752 { 0x1d, 0x1c, 0x00 },
753 { 0x1e, 0x30, 0x00 },
754 { 0, 0, 0 }
755 },
756 {
757 { 0x16, 0x00, 0x00 },
758 { 0x17, 0xa0, 0x00 },
759 { 0x1a, 0xa0, 0x00 },
760 { 0x1b, 0x2a, 0x00 },
761 { 0x1c, 0xff, 0x00 },
762 { 0x1d, 0x1c, 0x00 },
763 { 0, 0, 0 }
764 },
765 {
766 { 0x16, 0x00, 0x00 },
767 { 0x17, 0xaa, 0x00 },
768 { 0x1a, 0xa0, 0x00 },
769 { 0x1b, 0x2a, 0x00 },
770 { 0x1c, 0xff, 0x00 },
771 { 0x1d, 0x1c, 0x00 },
772 { 0, 0, 0 }
773 }
774 },
775 {
776 {
777 { 0x16, 0xcf, 0x00 },
778 { 0x18, 0x00, 0x00 },
779 { 0x1a, 0xe7, 0x00 },
780 { 0x1b, 0x26, 0x00 },
781 { 0x1c, 0xff, 0x00 },
782 { 0x1d, 0x1c, 0x00 },
783 { 0x1e, 0x19, 0x00 }
784 },
785 {
786 { 0, 0, 0 }
787 },
788 {
789 { 0x16, 0xcf, 0x00 },
790 { 0x18, 0x00, 0x00 },
791 { 0x1a, 0xe7, 0x00 },
792 { 0x1b, 0x26, 0x00 },
793 { 0x1c, 0xff, 0x00 },
794 { 0x1d, 0x1c, 0x00 },
795 { 0x1e, 0x19, 0x00 },
796 },
797 {
798 { 0, 0, 0 }
799 },
800 {
801 { 0x16, 0xcf, 0x00 },
802 { 0x18, 0x00, 0x00 },
803 { 0x1a, 0xe7, 0x00 },
804 { 0x1b, 0x26, 0x00 },
805 { 0x1c, 0xff, 0x00 },
806 { 0x1d, 0x1c, 0x00 },
807 { 0x1e, 0x1e, 0x00 }
808 },
809 {
810 { 0x16, 0xd1, 0x00 },
811 { 0x18, 0x00, 0x00 },
812 { 0x1a, 0xe6, 0x00 },
813 { 0x1b, 0x11, 0x00 },
814 { 0x1c, 0xff, 0x00 },
815 { 0x1d, 0x1c, 0x00 },
816 { 0x1e, 0x26, 0x00 }
817 },
818 {
819 { 0x18, 0x00, 0x00 },
820 { 0x1a, 0xe0, 0x00 },
821 { 0x1b, 0x26, 0x00 },
822 { 0x1c, 0xff, 0x00 },
823 { 0x1d, 0x1c, 0x00 },
824 { 0x1e, 0x30, 0x00 },
825 { 0, 0, 0 }
826 },
827 {
828 { 0, 0, 0 }
829 },
830 {
831 { 0, 0, 0 }
832 }
833 }
834};
835
836
837
838
839
840
diff --git a/drivers/video/fbdev/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h
new file mode 100644
index 000000000000..8fce56e4482c
--- /dev/null
+++ b/drivers/video/fbdev/sis/oem310.h
@@ -0,0 +1,430 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * OEM Data for 315/330/340 series
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const unsigned char SiS310_LCDDelayCompensation_301[] = /* 301 */
54{
55 0x00,0x00,0x00, /* 800x600 */
56 0x0b,0x0b,0x0b, /* 1024x768 */
57 0x08,0x08,0x08, /* 1280x1024 */
58 0x00,0x00,0x00, /* 640x480 (unknown) */
59 0x00,0x00,0x00, /* 1024x600 (unknown) */
60 0x00,0x00,0x00, /* 1152x864 (unknown) */
61 0x08,0x08,0x08, /* 1280x960 (guessed) */
62 0x00,0x00,0x00, /* 1152x768 (unknown) */
63 0x08,0x08,0x08, /* 1400x1050 */
64 0x08,0x08,0x08, /* 1280x768 (guessed) */
65 0x00,0x00,0x00, /* 1600x1200 */
66 0x00,0x00,0x00, /* 320x480 (unknown) */
67 0x00,0x00,0x00,
68 0x00,0x00,0x00,
69 0x00,0x00,0x00
70};
71
72/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
73static const unsigned char SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */
74{
75 0x01,0x01,0x01, /* 800x600 */
76 0x01,0x01,0x01, /* 1024x768 */
77 0x01,0x01,0x01, /* 1280x1024 */
78 0x01,0x01,0x01, /* 640x480 (unknown) */
79 0x01,0x01,0x01, /* 1024x600 (unknown) */
80 0x01,0x01,0x01, /* 1152x864 (unknown) */
81 0x01,0x01,0x01, /* 1280x960 (guessed) */
82 0x01,0x01,0x01, /* 1152x768 (unknown) */
83 0x01,0x01,0x01, /* 1400x1050 */
84 0x01,0x01,0x01, /* 1280x768 (guessed) */
85 0x01,0x01,0x01, /* 1600x1200 */
86 0x02,0x02,0x02,
87 0x02,0x02,0x02,
88 0x02,0x02,0x02,
89 0x02,0x02,0x02
90};
91
92static const unsigned char SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
93{
94 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
95 0x33,0x33,0x33, /* 1024x768 */
96 0x33,0x33,0x33, /* 1280x1024 */
97 0x33,0x33,0x33, /* 640x480 (unknown) */
98 0x33,0x33,0x33, /* 1024x600 (unknown) */
99 0x33,0x33,0x33, /* 1152x864 (unknown) */
100 0x33,0x33,0x33, /* 1280x960 (guessed) */
101 0x33,0x33,0x33, /* 1152x768 (unknown) */
102 0x33,0x33,0x33, /* 1400x1050 */
103 0x33,0x33,0x33, /* 1280x768 (guessed) */
104 0x33,0x33,0x33, /* 1600x1200 */
105 0x33,0x33,0x33,
106 0x33,0x33,0x33,
107 0x33,0x33,0x33,
108 0x33,0x33,0x33
109};
110
111static const unsigned char SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
112{
113 0x33,0x33,0x33, /* 800x600 (guessed) */
114 0x33,0x33,0x33, /* 1024x768 */
115 0x33,0x33,0x33, /* 1280x1024 */
116 0x33,0x33,0x33, /* 640x480 (unknown) */
117 0x33,0x33,0x33, /* 1024x600 (unknown) */
118 0x33,0x33,0x33, /* 1152x864 (unknown) */
119 0x33,0x33,0x33, /* 1280x960 (guessed) */
120 0x33,0x33,0x33, /* 1152x768 (unknown) */
121 0x33,0x33,0x33, /* 1400x1050 */
122 0x33,0x33,0x33, /* 1280x768 (guessed) */
123 0x33,0x33,0x33, /* 1600x1200 */
124 0x33,0x33,0x33,
125 0x33,0x33,0x33,
126 0x33,0x33,0x33,
127 0x33,0x33,0x33
128};
129
130static const unsigned char SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
131{
132 0x01,0x01,0x01, /* 800x600 */
133 0x0C,0x0C,0x0C, /* 1024x768 */
134 0x0C,0x0C,0x0C, /* 1280x1024 */
135 0x08,0x08,0x08, /* 640x480 */
136 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
137 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
138 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
139 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
140 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
141 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
142 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
143 0x02,0x02,0x02,
144 0x02,0x02,0x02,
145 0x02,0x02,0x02,
146 0x02,0x02,0x02
147};
148
149static const unsigned char SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
150{
151 0x01,0x01,0x01, /* 800x600 */
152 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
153 0x0C,0x0C,0x0C, /* 1280x1024 */
154 0x08,0x08,0x08, /* 640x480 */
155 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
156 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
157 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
158 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
159 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
160 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
161 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
162 0x02,0x02,0x02,
163 0x02,0x02,0x02,
164 0x02,0x02,0x02,
165 0x02,0x02,0x02
166};
167
168static const unsigned char SiS310_TVDelayCompensation_301[] = /* 301 */
169{
170 0x02,0x02, /* NTSC Enhanced, Standard */
171 0x02,0x02, /* PAL */
172 0x08,0x0b /* HiVision */
173};
174
175static const unsigned char SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */
176{
177 0x03,0x03,
178 0x03,0x03,
179 0x03,0x03
180};
181
182static const unsigned char SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */
183{
184 0x05,0x05,
185 0x05,0x05,
186 0x05,0x05
187};
188
189static const unsigned char SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
190{
191 0x33,0x33,
192 0x33,0x33,
193 0x33,0x33
194};
195
196static const unsigned char SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */
197{
198 0x33,0x33,
199 0x33,0x33,
200 0x33,0x33
201};
202
203static const unsigned char SiS_TVDelay661_301[] = /* 661, 301 */
204{
205 0x44,0x44,
206 0x44,0x44,
207 0x00,0x00,
208 0x44,0x44,
209 0x44,0x44,
210 0x44,0x44
211};
212
213static const unsigned char SiS_TVDelay661_301B[] = /* 661, 301B et al */
214{
215 0x44,0x44,
216 0x44,0x44,
217 0x00,0x00,
218 0x44,0x44,
219 0x44,0x44,
220 0x44,0x44
221};
222
223static const unsigned char SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
224{
225 0x0a,0x0a,
226 0x0a,0x0a,
227 0x0a,0x0a
228};
229
230static const unsigned char SiS310_TVAntiFlick1[6][2] =
231{
232 {0x4,0x0},
233 {0x4,0x8},
234 {0x0,0x0},
235 {0x0,0x0},
236 {0x0,0x0},
237 {0x0,0x0}
238};
239
240static const unsigned char SiS310_TVEdge1[6][2] =
241{
242 {0x0,0x4},
243 {0x0,0x4},
244 {0x0,0x0},
245 {0x0,0x0},
246 {0x0,0x0},
247 {0x0,0x0}
248};
249
250static const unsigned char SiS310_TVYFilter1[5][8][4] =
251{
252 {
253 {0x00,0xf4,0x10,0x38}, /* NTSC */
254 {0x00,0xf4,0x10,0x38},
255 {0xeb,0x04,0x25,0x18},
256 {0xf1,0x04,0x1f,0x18},
257 {0x00,0xf4,0x10,0x38},
258 {0xeb,0x04,0x25,0x18},
259 {0xee,0x0c,0x22,0x08},
260 {0xeb,0x15,0x25,0xf6}
261 },
262 {
263 {0x00,0xf4,0x10,0x38}, /* PAL */
264 {0x00,0xf4,0x10,0x38},
265 {0xf1,0xf7,0x1f,0x32},
266 {0xf3,0x00,0x1d,0x20},
267 {0x00,0xf4,0x10,0x38},
268 {0xf1,0xf7,0x1f,0x32},
269 {0xf3,0x00,0x1d,0x20},
270 {0xfc,0xfb,0x14,0x2a}
271 },
272 {
273 {0x00,0x00,0x00,0x00}, /* HiVision */
274 {0x00,0xf4,0x10,0x38},
275 {0x00,0xf4,0x10,0x38},
276 {0xeb,0x04,0x25,0x18},
277 {0xf7,0x06,0x19,0x14},
278 {0x00,0xf4,0x10,0x38},
279 {0xeb,0x04,0x25,0x18},
280 {0xee,0x0c,0x22,0x08}
281 },
282 {
283 {0x00,0xf4,0x10,0x38}, /* PAL-M */
284 {0x00,0xf4,0x10,0x38},
285 {0xeb,0x04,0x10,0x18},
286 {0xf7,0x06,0x19,0x14},
287 {0x00,0xf4,0x10,0x38},
288 {0xeb,0x04,0x25,0x18},
289 {0xeb,0x04,0x25,0x18},
290 {0xeb,0x15,0x25,0xf6}
291 },
292 {
293 {0x00,0xf4,0x10,0x38}, /* PAL-N */
294 {0x00,0xf4,0x10,0x38},
295 {0xeb,0x04,0x10,0x18},
296 {0xf7,0x06,0x19,0x14},
297 {0x00,0xf4,0x10,0x38},
298 {0xeb,0x04,0x25,0x18},
299 {0xeb,0x04,0x25,0x18},
300 {0xeb,0x15,0x25,0xf6}
301 }
302};
303
304static const unsigned char SiS310_TVYFilter2[5][9][7] =
305{
306 {
307 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* NTSC */
308 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
309 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
310 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
311 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
312 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
313 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
314 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
315 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
316 },
317 {
318 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL */
319 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
320 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
321 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
322 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
323 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
324 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
325 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
326 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
327 },
328 {
329 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, /* HiVision */
330 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
331 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
332 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
333 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
334 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
335 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
336 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
337 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
338 },
339 {
340 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */
341 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
342 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
343 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
344 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
345 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
346 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
347 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
348 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
349 },
350 {
351 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */
352 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
353 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
354 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
355 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
356 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
357 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
358 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
359 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
360 }
361};
362
363static const unsigned char SiS310_TVPhaseIncr1[3][2][4] =
364{
365 {
366 {0x21,0xed,0xba,0x08},
367 {0x21,0xed,0xba,0x08}
368 },
369 {
370 {0x2a,0x05,0xe3,0x00},
371 {0x2a,0x05,0xe3,0x00}
372 },
373 {
374 {0x2a,0x05,0xd3,0x00},
375 {0x2a,0x05,0xd3,0x00}
376 }
377};
378
379static const unsigned char SiS310_TVPhaseIncr2[3][2][4] =
380{
381 {
382 {0x21,0xf0,0x7b,0xd6},
383 {0x21,0xf0,0x7b,0xd6}
384 },
385 {
386 {0x2a,0x0a,0x41,0xe9},
387 {0x2a,0x0a,0x41,0xe9}
388 },
389 {
390 {0x2a,0x05,0xd3,0x00},
391 {0x2a,0x05,0xd3,0x00}
392 }
393};
394
395/**************************************************************/
396/* CUSTOM TIMING DATA --------------------------------------- */
397/**************************************************************/
398
399/* Inventec / Compaq Presario 3045US, 3017 */
400
401static const struct SiS_LCDData SiS310_ExtCompaq1280x1024Data[] =
402{
403 { 211, 60,1024, 501,1688,1066},
404 { 211, 60,1024, 508,1688,1066},
405 { 211, 60,1024, 501,1688,1066},
406 { 211, 60,1024, 508,1688,1066},
407 { 32, 15,1696, 501,1696,1066},
408 { 212, 75,1024, 621,1696,1066},
409 { 4, 3,1696, 810,1696,1066},
410 { 1, 1,1696,1066,1696,1066}
411};
412
413/* Asus A2xxxH _2 */
414
415static const struct SiS_Part2PortTbl SiS310_CRT2Part2_Asus1024x768_3[] =
416{
417 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
418 {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
419 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
420 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
421 {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
422 {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
423 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
424 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
425 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
426};
427
428
429
430
diff --git a/drivers/video/fbdev/sis/sis.h b/drivers/video/fbdev/sis/sis.h
new file mode 100644
index 000000000000..1987f1b7212f
--- /dev/null
+++ b/drivers/video/fbdev/sis/sis.h
@@ -0,0 +1,586 @@
1/*
2 * SiS 300/540/630[S]/730[S],
3 * SiS 315[E|PRO]/550/[M]65x/[M]661[F|M]X/740/[M]741[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
6 *
7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the named License,
12 * or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
22 */
23
24#ifndef _SIS_H_
25#define _SIS_H_
26
27#include <video/sisfb.h>
28
29#include "vgatypes.h"
30#include "vstruct.h"
31
32#define VER_MAJOR 1
33#define VER_MINOR 8
34#define VER_LEVEL 9
35
36#include <linux/spinlock.h>
37
38#ifdef CONFIG_COMPAT
39#define SIS_NEW_CONFIG_COMPAT
40#endif /* CONFIG_COMPAT */
41
42#undef SISFBDEBUG
43
44#ifdef SISFBDEBUG
45#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
46#define TWDEBUG(x) printk(KERN_INFO x "\n");
47#else
48#define DPRINTK(fmt, args...)
49#define TWDEBUG(x)
50#endif
51
52#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
53
54/* To be included in pci_ids.h */
55#ifndef PCI_DEVICE_ID_SI_650_VGA
56#define PCI_DEVICE_ID_SI_650_VGA 0x6325
57#endif
58#ifndef PCI_DEVICE_ID_SI_650
59#define PCI_DEVICE_ID_SI_650 0x0650
60#endif
61#ifndef PCI_DEVICE_ID_SI_651
62#define PCI_DEVICE_ID_SI_651 0x0651
63#endif
64#ifndef PCI_DEVICE_ID_SI_740
65#define PCI_DEVICE_ID_SI_740 0x0740
66#endif
67#ifndef PCI_DEVICE_ID_SI_330
68#define PCI_DEVICE_ID_SI_330 0x0330
69#endif
70#ifndef PCI_DEVICE_ID_SI_660_VGA
71#define PCI_DEVICE_ID_SI_660_VGA 0x6330
72#endif
73#ifndef PCI_DEVICE_ID_SI_661
74#define PCI_DEVICE_ID_SI_661 0x0661
75#endif
76#ifndef PCI_DEVICE_ID_SI_741
77#define PCI_DEVICE_ID_SI_741 0x0741
78#endif
79#ifndef PCI_DEVICE_ID_SI_660
80#define PCI_DEVICE_ID_SI_660 0x0660
81#endif
82#ifndef PCI_DEVICE_ID_SI_760
83#define PCI_DEVICE_ID_SI_760 0x0760
84#endif
85#ifndef PCI_DEVICE_ID_SI_761
86#define PCI_DEVICE_ID_SI_761 0x0761
87#endif
88
89#ifndef PCI_VENDOR_ID_XGI
90#define PCI_VENDOR_ID_XGI 0x18ca
91#endif
92
93#ifndef PCI_DEVICE_ID_XGI_20
94#define PCI_DEVICE_ID_XGI_20 0x0020
95#endif
96
97#ifndef PCI_DEVICE_ID_XGI_40
98#define PCI_DEVICE_ID_XGI_40 0x0040
99#endif
100
101/* To be included in fb.h */
102#ifndef FB_ACCEL_SIS_GLAMOUR_2
103#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
104#endif
105#ifndef FB_ACCEL_SIS_XABRE
106#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 76x */
107#endif
108#ifndef FB_ACCEL_XGI_VOLARI_V
109#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari Vx (V3XT, V5, V8) */
110#endif
111#ifndef FB_ACCEL_XGI_VOLARI_Z
112#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
113#endif
114
115/* ivideo->caps */
116#define HW_CURSOR_CAP 0x80
117#define TURBO_QUEUE_CAP 0x40
118#define AGP_CMD_QUEUE_CAP 0x20
119#define VM_CMD_QUEUE_CAP 0x10
120#define MMIO_CMD_QUEUE_CAP 0x08
121
122/* For 300 series */
123#define TURBO_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
124#define HW_CURSOR_AREA_SIZE_300 4096 /* 4K */
125
126/* For 315/Xabre series */
127#define COMMAND_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
128#define COMMAND_QUEUE_AREA_SIZE_Z7 (128 * 1024) /* 128k for XGI Z7 */
129#define HW_CURSOR_AREA_SIZE_315 16384 /* 16K */
130#define COMMAND_QUEUE_THRESHOLD 0x1F
131
132#define SIS_OH_ALLOC_SIZE 4000
133#define SENTINEL 0x7fffffff
134
135#define SEQ_ADR 0x14
136#define SEQ_DATA 0x15
137#define DAC_ADR 0x18
138#define DAC_DATA 0x19
139#define CRTC_ADR 0x24
140#define CRTC_DATA 0x25
141#define DAC2_ADR (0x16-0x30)
142#define DAC2_DATA (0x17-0x30)
143#define VB_PART1_ADR (0x04-0x30)
144#define VB_PART1_DATA (0x05-0x30)
145#define VB_PART2_ADR (0x10-0x30)
146#define VB_PART2_DATA (0x11-0x30)
147#define VB_PART3_ADR (0x12-0x30)
148#define VB_PART3_DATA (0x13-0x30)
149#define VB_PART4_ADR (0x14-0x30)
150#define VB_PART4_DATA (0x15-0x30)
151
152#define SISSR ivideo->SiS_Pr.SiS_P3c4
153#define SISCR ivideo->SiS_Pr.SiS_P3d4
154#define SISDACA ivideo->SiS_Pr.SiS_P3c8
155#define SISDACD ivideo->SiS_Pr.SiS_P3c9
156#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
157#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
158#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
159#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
160#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
161#define SISDAC2A SISPART5
162#define SISDAC2D (SISPART5 + 1)
163#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
164#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
165#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
166#define SISPEL ivideo->SiS_Pr.SiS_P3c6
167#define SISVGAENABLE (ivideo->SiS_Pr.RelIO + 0x13)
168#define SISVID (ivideo->SiS_Pr.RelIO + 0x02 - 0x30)
169#define SISCAP (ivideo->SiS_Pr.RelIO + 0x00 - 0x30)
170
171#define IND_SIS_PASSWORD 0x05 /* SRs */
172#define IND_SIS_COLOR_MODE 0x06
173#define IND_SIS_RAMDAC_CONTROL 0x07
174#define IND_SIS_DRAM_SIZE 0x14
175#define IND_SIS_MODULE_ENABLE 0x1E
176#define IND_SIS_PCI_ADDRESS_SET 0x20
177#define IND_SIS_TURBOQUEUE_ADR 0x26
178#define IND_SIS_TURBOQUEUE_SET 0x27
179#define IND_SIS_POWER_ON_TRAP 0x38
180#define IND_SIS_POWER_ON_TRAP2 0x39
181#define IND_SIS_CMDQUEUE_SET 0x26
182#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
183
184#define IND_SIS_AGP_IO_PAD 0x48
185
186#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
187#define SIS_CRT2_WENABLE_315 0x2F
188
189#define SIS_PASSWORD 0x86 /* SR05 */
190
191#define SIS_INTERLACED_MODE 0x20 /* SR06 */
192#define SIS_8BPP_COLOR_MODE 0x0
193#define SIS_15BPP_COLOR_MODE 0x1
194#define SIS_16BPP_COLOR_MODE 0x2
195#define SIS_32BPP_COLOR_MODE 0x4
196
197#define SIS_ENABLE_2D 0x40 /* SR1E */
198
199#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
200#define SIS_PCI_ADDR_ENABLE 0x80
201
202#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */
203#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
204#define SIS_MMIO_CMD_ENABLE 0x20
205#define SIS_CMD_QUEUE_SIZE_512k 0x00
206#define SIS_CMD_QUEUE_SIZE_1M 0x04
207#define SIS_CMD_QUEUE_SIZE_2M 0x08
208#define SIS_CMD_QUEUE_SIZE_4M 0x0C
209#define SIS_CMD_QUEUE_RESET 0x01
210#define SIS_CMD_AUTO_CORR 0x02
211
212#define SIS_CMD_QUEUE_SIZE_Z7_64k 0x00 /* XGI Z7 */
213#define SIS_CMD_QUEUE_SIZE_Z7_128k 0x04
214
215#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
216#define SIS_MODE_SELECT_CRT2 0x02
217#define SIS_VB_OUTPUT_COMPOSITE 0x04
218#define SIS_VB_OUTPUT_SVIDEO 0x08
219#define SIS_VB_OUTPUT_SCART 0x10
220#define SIS_VB_OUTPUT_LCD 0x20
221#define SIS_VB_OUTPUT_CRT2 0x40
222#define SIS_VB_OUTPUT_HIVISION 0x80
223
224#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
225#define SIS_DRIVER_MODE 0x40
226
227#define SIS_VB_COMPOSITE 0x01 /* CR32 */
228#define SIS_VB_SVIDEO 0x02
229#define SIS_VB_SCART 0x04
230#define SIS_VB_LCD 0x08
231#define SIS_VB_CRT2 0x10
232#define SIS_CRT1 0x20
233#define SIS_VB_HIVISION 0x40
234#define SIS_VB_YPBPR 0x80
235#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
236 SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
237
238#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
239#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
240#define SIS_EXTERNAL_CHIP_LVDS 0x02
241#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
242#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
243#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
244#define SIS310_EXTERNAL_CHIP_LVDS 0x02
245#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
246
247#define SIS_AGP_2X 0x20 /* CR48 */
248
249/* vbflags, private entries (others in sisfb.h) */
250#define VB_CONEXANT 0x00000800 /* 661 series only */
251#define VB_TRUMPION VB_CONEXANT /* 300 series only */
252#define VB_302ELV 0x00004000
253#define VB_301 0x00100000 /* Video bridge type */
254#define VB_301B 0x00200000
255#define VB_302B 0x00400000
256#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
257#define VB_LVDS 0x01000000
258#define VB_CHRONTEL 0x02000000
259#define VB_301LV 0x04000000
260#define VB_302LV 0x08000000
261#define VB_301C 0x10000000
262
263#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
264#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
265
266/* vbflags2 (static stuff only!) */
267#define VB2_SISUMC 0x00000001
268#define VB2_301 0x00000002 /* Video bridge type */
269#define VB2_301B 0x00000004
270#define VB2_301C 0x00000008
271#define VB2_307T 0x00000010
272#define VB2_302B 0x00000800
273#define VB2_301LV 0x00001000
274#define VB2_302LV 0x00002000
275#define VB2_302ELV 0x00004000
276#define VB2_307LV 0x00008000
277#define VB2_30xBDH 0x08000000 /* 30xB DH version (w/o LCD support) */
278#define VB2_CONEXANT 0x10000000
279#define VB2_TRUMPION 0x20000000
280#define VB2_LVDS 0x40000000
281#define VB2_CHRONTEL 0x80000000
282
283#define VB2_SISLVDSBRIDGE (VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
284#define VB2_SISTMDSBRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
285#define VB2_SISBRIDGE (VB2_SISLVDSBRIDGE | VB2_SISTMDSBRIDGE)
286
287#define VB2_SISTMDSLCDABRIDGE (VB2_301C | VB2_307T)
288#define VB2_SISLCDABRIDGE (VB2_SISTMDSLCDABRIDGE | VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
289
290#define VB2_SISHIVISIONBRIDGE (VB2_301 | VB2_301B | VB2_302B)
291#define VB2_SISYPBPRBRIDGE (VB2_301C | VB2_307T | VB2_SISLVDSBRIDGE)
292#define VB2_SISYPBPRARBRIDGE (VB2_301C | VB2_307T | VB2_307LV)
293#define VB2_SISTAP4SCALER (VB2_301C | VB2_307T | VB2_302ELV | VB2_307LV)
294#define VB2_SISTVBRIDGE (VB2_SISHIVISIONBRIDGE | VB2_SISYPBPRBRIDGE)
295
296#define VB2_SISVGA2BRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
297
298#define VB2_VIDEOBRIDGE (VB2_SISBRIDGE | VB2_LVDS | VB2_CHRONTEL | VB2_CONEXANT)
299
300#define VB2_30xB (VB2_301B | VB2_301C | VB2_302B | VB2_307T)
301#define VB2_30xBLV (VB2_30xB | VB2_SISLVDSBRIDGE)
302#define VB2_30xC (VB2_301C | VB2_307T)
303#define VB2_30xCLV (VB2_301C | VB2_307T | VB2_302ELV| VB2_307LV)
304#define VB2_SISEMIBRIDGE (VB2_302LV | VB2_302ELV | VB2_307LV)
305#define VB2_LCD162MHZBRIDGE (VB2_301C | VB2_307T)
306#define VB2_LCDOVER1280BRIDGE (VB2_301C | VB2_307T | VB2_302LV | VB2_302ELV | VB2_307LV)
307#define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV)
308#define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T)
309
310/* I/O port access functions */
311
312void SiS_SetReg(SISIOADDRESS, u8, u8);
313void SiS_SetRegByte(SISIOADDRESS, u8);
314void SiS_SetRegShort(SISIOADDRESS, u16);
315void SiS_SetRegLong(SISIOADDRESS, u32);
316void SiS_SetRegANDOR(SISIOADDRESS, u8, u8, u8);
317void SiS_SetRegAND(SISIOADDRESS, u8, u8);
318void SiS_SetRegOR(SISIOADDRESS, u8, u8);
319u8 SiS_GetReg(SISIOADDRESS, u8);
320u8 SiS_GetRegByte(SISIOADDRESS);
321u16 SiS_GetRegShort(SISIOADDRESS);
322u32 SiS_GetRegLong(SISIOADDRESS);
323
324/* MMIO access macros */
325#define MMIO_IN8(base, offset) readb((base+offset))
326#define MMIO_IN16(base, offset) readw((base+offset))
327#define MMIO_IN32(base, offset) readl((base+offset))
328
329#define MMIO_OUT8(base, offset, val) writeb(((u8)(val)), (base+offset))
330#define MMIO_OUT16(base, offset, val) writew(((u16)(val)), (base+offset))
331#define MMIO_OUT32(base, offset, val) writel(((u32)(val)), (base+offset))
332
333/* Queue control MMIO registers */
334#define Q_BASE_ADDR 0x85C0 /* Base address of software queue */
335#define Q_WRITE_PTR 0x85C4 /* Current write pointer */
336#define Q_READ_PTR 0x85C8 /* Current read pointer */
337#define Q_STATUS 0x85CC /* queue status */
338
339#define MMIO_QUEUE_PHYBASE Q_BASE_ADDR
340#define MMIO_QUEUE_WRITEPORT Q_WRITE_PTR
341#define MMIO_QUEUE_READPORT Q_READ_PTR
342
343#ifndef FB_BLANK_UNBLANK
344#define FB_BLANK_UNBLANK 0
345#endif
346#ifndef FB_BLANK_NORMAL
347#define FB_BLANK_NORMAL 1
348#endif
349#ifndef FB_BLANK_VSYNC_SUSPEND
350#define FB_BLANK_VSYNC_SUSPEND 2
351#endif
352#ifndef FB_BLANK_HSYNC_SUSPEND
353#define FB_BLANK_HSYNC_SUSPEND 3
354#endif
355#ifndef FB_BLANK_POWERDOWN
356#define FB_BLANK_POWERDOWN 4
357#endif
358
359enum _SIS_LCD_TYPE {
360 LCD_INVALID = 0,
361 LCD_800x600,
362 LCD_1024x768,
363 LCD_1280x1024,
364 LCD_1280x960,
365 LCD_640x480,
366 LCD_1600x1200,
367 LCD_1920x1440,
368 LCD_2048x1536,
369 LCD_320x240, /* FSTN */
370 LCD_1400x1050,
371 LCD_1152x864,
372 LCD_1152x768,
373 LCD_1280x768,
374 LCD_1024x600,
375 LCD_320x240_2, /* DSTN */
376 LCD_320x240_3, /* DSTN */
377 LCD_848x480,
378 LCD_1280x800,
379 LCD_1680x1050,
380 LCD_1280x720,
381 LCD_1280x854,
382 LCD_CUSTOM,
383 LCD_UNKNOWN
384};
385
386enum _SIS_CMDTYPE {
387 MMIO_CMD = 0,
388 AGP_CMD_QUEUE,
389 VM_CMD_QUEUE,
390};
391
392struct SIS_OH {
393 struct SIS_OH *poh_next;
394 struct SIS_OH *poh_prev;
395 u32 offset;
396 u32 size;
397};
398
399struct SIS_OHALLOC {
400 struct SIS_OHALLOC *poha_next;
401 struct SIS_OH aoh[1];
402};
403
404struct SIS_HEAP {
405 struct SIS_OH oh_free;
406 struct SIS_OH oh_used;
407 struct SIS_OH *poh_freelist;
408 struct SIS_OHALLOC *poha_chain;
409 u32 max_freesize;
410 struct sis_video_info *vinfo;
411};
412
413/* Our "par" */
414struct sis_video_info {
415 int cardnumber;
416 struct fb_info *memyselfandi;
417
418 struct SiS_Private SiS_Pr;
419
420 struct sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
421
422 struct fb_var_screeninfo default_var;
423
424 struct fb_fix_screeninfo sisfb_fix;
425 u32 pseudo_palette[16];
426
427 struct sisfb_monitor {
428 u16 hmin;
429 u16 hmax;
430 u16 vmin;
431 u16 vmax;
432 u32 dclockmax;
433 u8 feature;
434 bool datavalid;
435 } sisfb_thismonitor;
436
437 unsigned short chip_id; /* PCI ID of chip */
438 unsigned short chip_vendor; /* PCI ID of vendor */
439 char myid[40];
440
441 struct pci_dev *nbridge;
442 struct pci_dev *lpcdev;
443
444 int mni; /* Mode number index */
445
446 unsigned long video_size;
447 unsigned long video_base;
448 unsigned long mmio_size;
449 unsigned long mmio_base;
450 unsigned long vga_base;
451
452 unsigned long video_offset;
453
454 unsigned long UMAsize, LFBsize;
455
456 void __iomem *video_vbase;
457 void __iomem *mmio_vbase;
458
459 unsigned char *bios_abase;
460
461 int mtrr;
462
463 u32 sisfb_mem;
464
465 u32 sisfb_parm_mem;
466 int sisfb_accel;
467 int sisfb_ypan;
468 int sisfb_max;
469 int sisfb_userom;
470 int sisfb_useoem;
471 int sisfb_mode_idx;
472 int sisfb_parm_rate;
473 int sisfb_crt1off;
474 int sisfb_forcecrt1;
475 int sisfb_crt2type;
476 int sisfb_crt2flags;
477 int sisfb_dstn;
478 int sisfb_fstn;
479 int sisfb_tvplug;
480 int sisfb_tvstd;
481 int sisfb_nocrt2rate;
482
483 u32 heapstart; /* offset */
484 void __iomem *sisfb_heap_start; /* address */
485 void __iomem *sisfb_heap_end; /* address */
486 u32 sisfb_heap_size;
487 int havenoheap;
488
489 struct SIS_HEAP sisfb_heap; /* This card's vram heap */
490
491 int video_bpp;
492 int video_cmap_len;
493 int video_width;
494 int video_height;
495 unsigned int refresh_rate;
496
497 unsigned int chip;
498 unsigned int chip_real_id;
499 u8 revision_id;
500 int sisvga_enabled; /* PCI device was enabled */
501
502 int video_linelength; /* real pitch */
503 int scrnpitchCRT1; /* pitch regarding interlace */
504
505 u16 DstColor; /* For 2d acceleration */
506 u32 SiS310_AccelDepth;
507 u32 CommandReg;
508 int cmdqueuelength; /* Current (for accel) */
509 u32 cmdQueueSize; /* Total size in KB */
510
511 spinlock_t lockaccel; /* Do not use outside of kernel! */
512
513 unsigned int pcibus;
514 unsigned int pcislot;
515 unsigned int pcifunc;
516
517 int accel;
518 int engineok;
519
520 u16 subsysvendor;
521 u16 subsysdevice;
522
523 u32 vbflags; /* Replacing deprecated stuff from above */
524 u32 currentvbflags;
525 u32 vbflags2;
526
527 int lcdxres, lcdyres;
528 int lcddefmodeidx, tvdefmodeidx, defmodeidx;
529 u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */
530 u32 curFSTN, curDSTN;
531
532 int current_bpp;
533 int current_width;
534 int current_height;
535 int current_htotal;
536 int current_vtotal;
537 int current_linelength;
538 __u32 current_pixclock;
539 int current_refresh_rate;
540
541 unsigned int current_base;
542
543 u8 mode_no;
544 u8 rate_idx;
545 int modechanged;
546 unsigned char modeprechange;
547
548 u8 sisfb_lastrates[128];
549
550 int newrom;
551 int haveXGIROM;
552 int registered;
553 int warncount;
554
555 int sisvga_engine;
556 int hwcursor_size;
557 int CRT2_write_enable;
558 u8 caps;
559
560 u8 detectedpdc;
561 u8 detectedpdca;
562 u8 detectedlcda;
563
564 void __iomem *hwcursor_vbase;
565
566 int chronteltype;
567 int tvxpos, tvypos;
568 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
569 int tvx, tvy;
570
571 u8 sisfblocked;
572
573 struct sisfb_info sisfb_infoblock;
574
575 struct sisfb_cmd sisfb_command;
576
577 u32 sisfb_id;
578
579 u8 sisfb_can_post;
580 u8 sisfb_card_posted;
581 u8 sisfb_was_boot_device;
582
583 struct sis_video_info *next;
584};
585
586#endif
diff --git a/drivers/video/fbdev/sis/sis_accel.c b/drivers/video/fbdev/sis/sis_accel.c
new file mode 100644
index 000000000000..ceb434c95c0d
--- /dev/null
+++ b/drivers/video/fbdev/sis/sis_accel.c
@@ -0,0 +1,423 @@
1/*
2 * SiS 300/540/630[S]/730[S],
3 * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
6 *
7 * 2D acceleration part
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the named License,
12 * or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
22 *
23 * Based on the XFree86/X.org driver which is
24 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
25 *
26 * Author: Thomas Winischhofer <thomas@winischhofer.net>
27 * (see http://www.winischhofer.net/
28 * for more information and updates)
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/fb.h>
34#include <linux/ioport.h>
35#include <linux/types.h>
36#include <asm/io.h>
37
38#include "sis.h"
39#include "sis_accel.h"
40
41static const u8 sisALUConv[] =
42{
43 0x00, /* dest = 0; 0, GXclear, 0 */
44 0x88, /* dest &= src; DSa, GXand, 0x1 */
45 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
46 0xCC, /* dest = src; S, GXcopy, 0x3 */
47 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
48 0xAA, /* dest = dest; D, GXnoop, 0x5 */
49 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
50 0xEE, /* dest |= src; DSo, GXor, 0x7 */
51 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
52 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
53 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
54 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
55 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
56 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
57 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
58 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
59};
60/* same ROP but with Pattern as Source */
61static const u8 sisPatALUConv[] =
62{
63 0x00, /* dest = 0; 0, GXclear, 0 */
64 0xA0, /* dest &= src; DPa, GXand, 0x1 */
65 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
66 0xF0, /* dest = src; P, GXcopy, 0x3 */
67 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
68 0xAA, /* dest = dest; D, GXnoop, 0x5 */
69 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
70 0xFA, /* dest |= src; DPo, GXor, 0x7 */
71 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
72 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
73 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
74 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
75 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
76 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
77 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
78 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
79};
80
81static const int myrops[] = {
82 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
83};
84
85/* 300 series ----------------------------------------------------- */
86#ifdef CONFIG_FB_SIS_300
87static void
88SiS300Sync(struct sis_video_info *ivideo)
89{
90 SiS300Idle
91}
92
93static void
94SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir,
95 int rop, int trans_color)
96{
97 SiS300SetupDSTColorDepth(ivideo->DstColor);
98 SiS300SetupSRCPitch(ivideo->video_linelength)
99 SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
100
101 if(trans_color != -1) {
102 SiS300SetupROP(0x0A)
103 SiS300SetupSRCTrans(trans_color)
104 SiS300SetupCMDFlag(TRANSPARENT_BITBLT)
105 } else {
106 SiS300SetupROP(sisALUConv[rop])
107 }
108 if(xdir > 0) {
109 SiS300SetupCMDFlag(X_INC)
110 }
111 if(ydir > 0) {
112 SiS300SetupCMDFlag(Y_INC)
113 }
114}
115
116static void
117SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x,
118 int src_y, int dst_x, int dst_y, int width, int height)
119{
120 u32 srcbase = 0, dstbase = 0;
121
122 if(src_y >= 2048) {
123 srcbase = ivideo->video_linelength * src_y;
124 src_y = 0;
125 }
126 if(dst_y >= 2048) {
127 dstbase = ivideo->video_linelength * dst_y;
128 dst_y = 0;
129 }
130
131 SiS300SetupSRCBase(srcbase);
132 SiS300SetupDSTBase(dstbase);
133
134 if(!(ivideo->CommandReg & X_INC)) {
135 src_x += width-1;
136 dst_x += width-1;
137 }
138 if(!(ivideo->CommandReg & Y_INC)) {
139 src_y += height-1;
140 dst_y += height-1;
141 }
142 SiS300SetupRect(width, height)
143 SiS300SetupSRCXY(src_x, src_y)
144 SiS300SetupDSTXY(dst_x, dst_y)
145 SiS300DoCMD
146}
147
148static void
149SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
150{
151 SiS300SetupPATFG(color)
152 SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
153 SiS300SetupDSTColorDepth(ivideo->DstColor);
154 SiS300SetupROP(sisPatALUConv[rop])
155 SiS300SetupCMDFlag(PATFG)
156}
157
158static void
159SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
160{
161 u32 dstbase = 0;
162
163 if(y >= 2048) {
164 dstbase = ivideo->video_linelength * y;
165 y = 0;
166 }
167 SiS300SetupDSTBase(dstbase)
168 SiS300SetupDSTXY(x,y)
169 SiS300SetupRect(w,h)
170 SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT)
171 SiS300DoCMD
172}
173#endif
174
175/* 315/330/340 series ---------------------------------------------- */
176
177#ifdef CONFIG_FB_SIS_315
178static void
179SiS310Sync(struct sis_video_info *ivideo)
180{
181 SiS310Idle
182}
183
184static void
185SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color)
186{
187 SiS310SetupDSTColorDepth(ivideo->DstColor);
188 SiS310SetupSRCPitch(ivideo->video_linelength)
189 SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
190 if(trans_color != -1) {
191 SiS310SetupROP(0x0A)
192 SiS310SetupSRCTrans(trans_color)
193 SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
194 } else {
195 SiS310SetupROP(sisALUConv[rop])
196 /* Set command - not needed, both 0 */
197 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
198 }
199 SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
200 /* The chip is smart enough to know the direction */
201}
202
203static void
204SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y,
205 int dst_x, int dst_y, int width, int height)
206{
207 u32 srcbase = 0, dstbase = 0;
208 int mymin = min(src_y, dst_y);
209 int mymax = max(src_y, dst_y);
210
211 /* Although the chip knows the direction to use
212 * if the source and destination areas overlap,
213 * that logic fails if we fiddle with the bitmap
214 * addresses. Therefore, we check if the source
215 * and destination blitting areas overlap and
216 * adapt the bitmap addresses synchronously
217 * if the coordinates exceed the valid range.
218 * The the areas do not overlap, we do our
219 * normal check.
220 */
221 if((mymax - mymin) < height) {
222 if((src_y >= 2048) || (dst_y >= 2048)) {
223 srcbase = ivideo->video_linelength * mymin;
224 dstbase = ivideo->video_linelength * mymin;
225 src_y -= mymin;
226 dst_y -= mymin;
227 }
228 } else {
229 if(src_y >= 2048) {
230 srcbase = ivideo->video_linelength * src_y;
231 src_y = 0;
232 }
233 if(dst_y >= 2048) {
234 dstbase = ivideo->video_linelength * dst_y;
235 dst_y = 0;
236 }
237 }
238
239 srcbase += ivideo->video_offset;
240 dstbase += ivideo->video_offset;
241
242 SiS310SetupSRCBase(srcbase);
243 SiS310SetupDSTBase(dstbase);
244 SiS310SetupRect(width, height)
245 SiS310SetupSRCXY(src_x, src_y)
246 SiS310SetupDSTXY(dst_x, dst_y)
247 SiS310DoCMD
248}
249
250static void
251SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
252{
253 SiS310SetupPATFG(color)
254 SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
255 SiS310SetupDSTColorDepth(ivideo->DstColor);
256 SiS310SetupROP(sisPatALUConv[rop])
257 SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
258}
259
260static void
261SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
262{
263 u32 dstbase = 0;
264
265 if(y >= 2048) {
266 dstbase = ivideo->video_linelength * y;
267 y = 0;
268 }
269 dstbase += ivideo->video_offset;
270 SiS310SetupDSTBase(dstbase)
271 SiS310SetupDSTXY(x,y)
272 SiS310SetupRect(w,h)
273 SiS310SetupCMDFlag(BITBLT)
274 SiS310DoCMD
275}
276#endif
277
278/* --------------------------------------------------------------------- */
279
280/* The exported routines */
281
282int sisfb_initaccel(struct sis_video_info *ivideo)
283{
284#ifdef SISFB_USE_SPINLOCKS
285 spin_lock_init(&ivideo->lockaccel);
286#endif
287 return 0;
288}
289
290void sisfb_syncaccel(struct sis_video_info *ivideo)
291{
292 if(ivideo->sisvga_engine == SIS_300_VGA) {
293#ifdef CONFIG_FB_SIS_300
294 SiS300Sync(ivideo);
295#endif
296 } else {
297#ifdef CONFIG_FB_SIS_315
298 SiS310Sync(ivideo);
299#endif
300 }
301}
302
303int fbcon_sis_sync(struct fb_info *info)
304{
305 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
306 CRITFLAGS
307
308 if((!ivideo->accel) || (!ivideo->engineok))
309 return 0;
310
311 CRITBEGIN
312 sisfb_syncaccel(ivideo);
313 CRITEND
314
315 return 0;
316}
317
318void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
319{
320 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
321 u32 col = 0;
322 u32 vxres = info->var.xres_virtual;
323 u32 vyres = info->var.yres_virtual;
324 int width, height;
325 CRITFLAGS
326
327 if(info->state != FBINFO_STATE_RUNNING)
328 return;
329
330 if((!ivideo->accel) || (!ivideo->engineok)) {
331 cfb_fillrect(info, rect);
332 return;
333 }
334
335 if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres)
336 return;
337
338 /* Clipping */
339 width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
340 height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
341
342 switch(info->var.bits_per_pixel) {
343 case 8: col = rect->color;
344 break;
345 case 16:
346 case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
347 break;
348 }
349
350 if(ivideo->sisvga_engine == SIS_300_VGA) {
351#ifdef CONFIG_FB_SIS_300
352 CRITBEGIN
353 SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
354 SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
355 CRITEND
356#endif
357 } else {
358#ifdef CONFIG_FB_SIS_315
359 CRITBEGIN
360 SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
361 SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
362 CRITEND
363#endif
364 }
365
366 sisfb_syncaccel(ivideo);
367}
368
369void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
370{
371 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
372 u32 vxres = info->var.xres_virtual;
373 u32 vyres = info->var.yres_virtual;
374 int width = area->width;
375 int height = area->height;
376 CRITFLAGS
377
378 if(info->state != FBINFO_STATE_RUNNING)
379 return;
380
381 if((!ivideo->accel) || (!ivideo->engineok)) {
382 cfb_copyarea(info, area);
383 return;
384 }
385
386 if(!width || !height ||
387 area->sx >= vxres || area->sy >= vyres ||
388 area->dx >= vxres || area->dy >= vyres)
389 return;
390
391 /* Clipping */
392 if((area->sx + width) > vxres) width = vxres - area->sx;
393 if((area->dx + width) > vxres) width = vxres - area->dx;
394 if((area->sy + height) > vyres) height = vyres - area->sy;
395 if((area->dy + height) > vyres) height = vyres - area->dy;
396
397 if(ivideo->sisvga_engine == SIS_300_VGA) {
398#ifdef CONFIG_FB_SIS_300
399 int xdir, ydir;
400
401 if(area->sx < area->dx) xdir = 0;
402 else xdir = 1;
403 if(area->sy < area->dy) ydir = 0;
404 else ydir = 1;
405
406 CRITBEGIN
407 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
408 SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
409 area->dx, area->dy, width, height);
410 CRITEND
411#endif
412 } else {
413#ifdef CONFIG_FB_SIS_315
414 CRITBEGIN
415 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
416 SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
417 area->dx, area->dy, width, height);
418 CRITEND
419#endif
420 }
421
422 sisfb_syncaccel(ivideo);
423}
diff --git a/drivers/video/fbdev/sis/sis_accel.h b/drivers/video/fbdev/sis/sis_accel.h
new file mode 100644
index 000000000000..30e03cdf6b85
--- /dev/null
+++ b/drivers/video/fbdev/sis/sis_accel.h
@@ -0,0 +1,400 @@
1/*
2 * SiS 300/540/630[S]/730[S],
3 * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
6 *
7 * 2D acceleration part
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the named License,
12 * or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
22 *
23 * Based on the X driver's sis300_accel.h which is
24 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
25 * and sis310_accel.h which is
26 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
27 *
28 * Author: Thomas Winischhofer <thomas@winischhofer.net>:
29 * (see http://www.winischhofer.net/
30 * for more information and updates)
31 */
32
33#ifndef _SISFB_ACCEL_H
34#define _SISFB_ACCEL_H
35
36/* Guard accelerator accesses with spin_lock_irqsave? Works well without. */
37#undef SISFB_USE_SPINLOCKS
38
39#ifdef SISFB_USE_SPINLOCKS
40#include <linux/spinlock.h>
41#define CRITBEGIN spin_lock_irqsave(&ivideo->lockaccel, critflags);
42#define CRITEND spin_unlock_irqrestore(&ivideo->lockaccel, critflags);
43#define CRITFLAGS unsigned long critflags;
44#else
45#define CRITBEGIN
46#define CRITEND
47#define CRITFLAGS
48#endif
49
50/* Definitions for the SIS engine communication. */
51
52#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */
53#define BR(x) (0x8200 | (x) << 2)
54#define PBR(x) (0x8300 | (x) << 2)
55
56/* SiS300 engine commands */
57#define BITBLT 0x00000000 /* Blit */
58#define COLOREXP 0x00000001 /* Color expand */
59#define ENCOLOREXP 0x00000002 /* Enhanced color expand */
60#define MULTIPLE_SCANLINE 0x00000003 /* ? */
61#define LINE 0x00000004 /* Draw line */
62#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
63#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
64
65/* Additional engine commands for 315 */
66#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */
67#define A3D_FUNCTION 0x00000008 /* 3D command ? */
68#define CLEAR_Z_BUFFER 0x00000009 /* ? */
69#define GRADIENT_FILL 0x0000000A /* Gradient fill */
70
71/* source select */
72#define SRCVIDEO 0x00000000 /* source is video RAM */
73#define SRCSYSTEM 0x00000010 /* source is system memory */
74#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
75#define SRCAGP 0x00000020 /* source is AGP memory (?) */
76
77/* Pattern flags */
78#define PATFG 0x00000000 /* foreground color */
79#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
80#define PATMONO 0x00000080 /* mono pattern */
81
82/* blitting direction (300 series only) */
83#define X_INC 0x00010000
84#define X_DEC 0x00000000
85#define Y_INC 0x00020000
86#define Y_DEC 0x00000000
87
88/* Clipping flags */
89#define NOCLIP 0x00000000
90#define NOMERGECLIP 0x04000000
91#define CLIPENABLE 0x00040000
92#define CLIPWITHOUTMERGE 0x04040000
93
94/* Transparency */
95#define OPAQUE 0x00000000
96#define TRANSPARENT 0x00100000
97
98/* ? */
99#define DSTAGP 0x02000000
100#define DSTVIDEO 0x02000000
101
102/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
103#define COLOR_TO_MONO 0x00100000
104#define AA_TEXT 0x00200000
105
106/* Some general registers for 315 series */
107#define SRC_ADDR 0x8200
108#define SRC_PITCH 0x8204
109#define AGP_BASE 0x8206 /* color-depth dependent value */
110#define SRC_Y 0x8208
111#define SRC_X 0x820A
112#define DST_Y 0x820C
113#define DST_X 0x820E
114#define DST_ADDR 0x8210
115#define DST_PITCH 0x8214
116#define DST_HEIGHT 0x8216
117#define RECT_WIDTH 0x8218
118#define RECT_HEIGHT 0x821A
119#define PAT_FGCOLOR 0x821C
120#define PAT_BGCOLOR 0x8220
121#define SRC_FGCOLOR 0x8224
122#define SRC_BGCOLOR 0x8228
123#define MONO_MASK 0x822C
124#define LEFT_CLIP 0x8234
125#define TOP_CLIP 0x8236
126#define RIGHT_CLIP 0x8238
127#define BOTTOM_CLIP 0x823A
128#define COMMAND_READY 0x823C
129#define FIRE_TRIGGER 0x8240
130
131#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
132
133/* Transparent bitblit registers */
134#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
135#define TRANS_DST_KEY_LOW PAT_BGCOLOR
136#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
137#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
138
139/* Store queue length in par */
140#define CmdQueLen ivideo->cmdqueuelength
141
142/* ------------- SiS 300 series -------------- */
143
144/* BR(16) (0x8240):
145
146 bit 31 2D engine: 1 is idle,
147 bit 30 3D engine: 1 is idle,
148 bit 29 Command queue: 1 is empty
149 bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
150 bits 15:0: Current command queue length
151
152*/
153
154#define SiS300Idle \
155 { \
156 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
157 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
158 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
159 CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \
160 }
161/* (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
162
163#define SiS300SetupSRCBase(base) \
164 if(CmdQueLen <= 0) SiS300Idle;\
165 MMIO_OUT32(ivideo->mmio_vbase, BR(0), base);\
166 CmdQueLen--;
167
168#define SiS300SetupSRCPitch(pitch) \
169 if(CmdQueLen <= 0) SiS300Idle;\
170 MMIO_OUT16(ivideo->mmio_vbase, BR(1), pitch);\
171 CmdQueLen--;
172
173#define SiS300SetupSRCXY(x,y) \
174 if(CmdQueLen <= 0) SiS300Idle;\
175 MMIO_OUT32(ivideo->mmio_vbase, BR(2), (x)<<16 | (y) );\
176 CmdQueLen--;
177
178#define SiS300SetupDSTBase(base) \
179 if(CmdQueLen <= 0) SiS300Idle;\
180 MMIO_OUT32(ivideo->mmio_vbase, BR(4), base);\
181 CmdQueLen--;
182
183#define SiS300SetupDSTXY(x,y) \
184 if(CmdQueLen <= 0) SiS300Idle;\
185 MMIO_OUT32(ivideo->mmio_vbase, BR(3), (x)<<16 | (y) );\
186 CmdQueLen--;
187
188#define SiS300SetupDSTRect(x,y) \
189 if(CmdQueLen <= 0) SiS300Idle;\
190 MMIO_OUT32(ivideo->mmio_vbase, BR(5), (y)<<16 | (x) );\
191 CmdQueLen--;
192
193#define SiS300SetupDSTColorDepth(bpp) \
194 if(CmdQueLen <= 0) SiS300Idle;\
195 MMIO_OUT16(ivideo->mmio_vbase, BR(1)+2, bpp);\
196 CmdQueLen--;
197
198#define SiS300SetupRect(w,h) \
199 if(CmdQueLen <= 0) SiS300Idle;\
200 MMIO_OUT32(ivideo->mmio_vbase, BR(6), (h)<<16 | (w) );\
201 CmdQueLen--;
202
203#define SiS300SetupPATFG(color) \
204 if(CmdQueLen <= 0) SiS300Idle;\
205 MMIO_OUT32(ivideo->mmio_vbase, BR(7), color);\
206 CmdQueLen--;
207
208#define SiS300SetupPATBG(color) \
209 if(CmdQueLen <= 0) SiS300Idle;\
210 MMIO_OUT32(ivideo->mmio_vbase, BR(8), color);\
211 CmdQueLen--;
212
213#define SiS300SetupSRCFG(color) \
214 if(CmdQueLen <= 0) SiS300Idle;\
215 MMIO_OUT32(ivideo->mmio_vbase, BR(9), color);\
216 CmdQueLen--;
217
218#define SiS300SetupSRCBG(color) \
219 if(CmdQueLen <= 0) SiS300Idle;\
220 MMIO_OUT32(ivideo->mmio_vbase, BR(10), color);\
221 CmdQueLen--;
222
223/* 0x8224 src colorkey high */
224/* 0x8228 src colorkey low */
225/* 0x821c dest colorkey high */
226/* 0x8220 dest colorkey low */
227#define SiS300SetupSRCTrans(color) \
228 if(CmdQueLen <= 1) SiS300Idle;\
229 MMIO_OUT32(ivideo->mmio_vbase, 0x8224, color);\
230 MMIO_OUT32(ivideo->mmio_vbase, 0x8228, color);\
231 CmdQueLen -= 2;
232
233#define SiS300SetupDSTTrans(color) \
234 if(CmdQueLen <= 1) SiS300Idle;\
235 MMIO_OUT32(ivideo->mmio_vbase, 0x821C, color); \
236 MMIO_OUT32(ivideo->mmio_vbase, 0x8220, color); \
237 CmdQueLen -= 2;
238
239#define SiS300SetupMONOPAT(p0,p1) \
240 if(CmdQueLen <= 1) SiS300Idle;\
241 MMIO_OUT32(ivideo->mmio_vbase, BR(11), p0);\
242 MMIO_OUT32(ivideo->mmio_vbase, BR(12), p1);\
243 CmdQueLen -= 2;
244
245#define SiS300SetupClipLT(left,top) \
246 if(CmdQueLen <= 0) SiS300Idle;\
247 MMIO_OUT32(ivideo->mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
248 CmdQueLen--;
249
250#define SiS300SetupClipRB(right,bottom) \
251 if(CmdQueLen <= 0) SiS300Idle;\
252 MMIO_OUT32(ivideo->mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
253 CmdQueLen--;
254
255/* General */
256#define SiS300SetupROP(rop) \
257 ivideo->CommandReg = (rop) << 8;
258
259#define SiS300SetupCMDFlag(flags) \
260 ivideo->CommandReg |= (flags);
261
262#define SiS300DoCMD \
263 if(CmdQueLen <= 1) SiS300Idle;\
264 MMIO_OUT32(ivideo->mmio_vbase, BR(15), ivideo->CommandReg); \
265 MMIO_OUT32(ivideo->mmio_vbase, BR(16), 0);\
266 CmdQueLen -= 2;
267
268/* -------------- SiS 315/330 series --------------- */
269
270/* Q_STATUS:
271 bit 31 = 1: All engines idle and all queues empty
272 bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
273 bit 29 = 1: 2D engine is idle
274 bit 28 = 1: 3D engine is idle
275 bit 27 = 1: HW command queue empty
276 bit 26 = 1: 2D queue empty
277 bit 25 = 1: 3D queue empty
278 bit 24 = 1: SW command queue empty
279 bits 23:16: 2D counter 3
280 bits 15:8: 2D counter 2
281 bits 7:0: 2D counter 1
282*/
283
284#define SiS310Idle \
285 { \
286 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
287 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
288 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
289 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
290 CmdQueLen = 0; \
291 }
292
293#define SiS310SetupSRCBase(base) \
294 if(CmdQueLen <= 0) SiS310Idle;\
295 MMIO_OUT32(ivideo->mmio_vbase, SRC_ADDR, base);\
296 CmdQueLen--;
297
298#define SiS310SetupSRCPitch(pitch) \
299 if(CmdQueLen <= 0) SiS310Idle;\
300 MMIO_OUT16(ivideo->mmio_vbase, SRC_PITCH, pitch);\
301 CmdQueLen--;
302
303#define SiS310SetupSRCXY(x,y) \
304 if(CmdQueLen <= 0) SiS310Idle;\
305 MMIO_OUT32(ivideo->mmio_vbase, SRC_Y, (x)<<16 | (y) );\
306 CmdQueLen--;
307
308#define SiS310SetupDSTBase(base) \
309 if(CmdQueLen <= 0) SiS310Idle;\
310 MMIO_OUT32(ivideo->mmio_vbase, DST_ADDR, base);\
311 CmdQueLen--;
312
313#define SiS310SetupDSTXY(x,y) \
314 if(CmdQueLen <= 0) SiS310Idle;\
315 MMIO_OUT32(ivideo->mmio_vbase, DST_Y, (x)<<16 | (y) );\
316 CmdQueLen--;
317
318#define SiS310SetupDSTRect(x,y) \
319 if(CmdQueLen <= 0) SiS310Idle;\
320 MMIO_OUT32(ivideo->mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
321 CmdQueLen--;
322
323#define SiS310SetupDSTColorDepth(bpp) \
324 if(CmdQueLen <= 0) SiS310Idle;\
325 MMIO_OUT16(ivideo->mmio_vbase, AGP_BASE, bpp);\
326 CmdQueLen--;
327
328#define SiS310SetupRect(w,h) \
329 if(CmdQueLen <= 0) SiS310Idle;\
330 MMIO_OUT32(ivideo->mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
331 CmdQueLen--;
332
333#define SiS310SetupPATFG(color) \
334 if(CmdQueLen <= 0) SiS310Idle;\
335 MMIO_OUT32(ivideo->mmio_vbase, PAT_FGCOLOR, color);\
336 CmdQueLen--;
337
338#define SiS310SetupPATBG(color) \
339 if(CmdQueLen <= 0) SiS310Idle;\
340 MMIO_OUT32(ivideo->mmio_vbase, PAT_BGCOLOR, color);\
341 CmdQueLen--;
342
343#define SiS310SetupSRCFG(color) \
344 if(CmdQueLen <= 0) SiS310Idle;\
345 MMIO_OUT32(ivideo->mmio_vbase, SRC_FGCOLOR, color);\
346 CmdQueLen--;
347
348#define SiS310SetupSRCBG(color) \
349 if(CmdQueLen <= 0) SiS310Idle;\
350 MMIO_OUT32(ivideo->mmio_vbase, SRC_BGCOLOR, color);\
351 CmdQueLen--;
352
353#define SiS310SetupSRCTrans(color) \
354 if(CmdQueLen <= 1) SiS310Idle;\
355 MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
356 MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_LOW, color);\
357 CmdQueLen -= 2;
358
359#define SiS310SetupDSTTrans(color) \
360 if(CmdQueLen <= 1) SiS310Idle;\
361 MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_HIGH, color); \
362 MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_LOW, color); \
363 CmdQueLen -= 2;
364
365#define SiS310SetupMONOPAT(p0,p1) \
366 if(CmdQueLen <= 1) SiS310Idle;\
367 MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK, p0);\
368 MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK+4, p1);\
369 CmdQueLen -= 2;
370
371#define SiS310SetupClipLT(left,top) \
372 if(CmdQueLen <= 0) SiS310Idle;\
373 MMIO_OUT32(ivideo->mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
374 CmdQueLen--;
375
376#define SiS310SetupClipRB(right,bottom) \
377 if(CmdQueLen <= 0) SiS310Idle;\
378 MMIO_OUT32(ivideo->mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
379 CmdQueLen--;
380
381#define SiS310SetupROP(rop) \
382 ivideo->CommandReg = (rop) << 8;
383
384#define SiS310SetupCMDFlag(flags) \
385 ivideo->CommandReg |= (flags);
386
387#define SiS310DoCMD \
388 if(CmdQueLen <= 1) SiS310Idle;\
389 MMIO_OUT32(ivideo->mmio_vbase, COMMAND_READY, ivideo->CommandReg); \
390 MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
391 CmdQueLen -= 2;
392
393int sisfb_initaccel(struct sis_video_info *ivideo);
394void sisfb_syncaccel(struct sis_video_info *ivideo);
395
396int fbcon_sis_sync(struct fb_info *info);
397void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
398void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
399
400#endif
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
new file mode 100644
index 000000000000..22ad028bf123
--- /dev/null
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -0,0 +1,6844 @@
1/*
2 * SiS 300/540/630[S]/730[S],
3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
6 *
7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the named License,
12 * or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
22 *
23 * Author: Thomas Winischhofer <thomas@winischhofer.net>
24 *
25 * Author of (practically wiped) code base:
26 * SiS (www.sis.com)
27 * Copyright (C) 1999 Silicon Integrated Systems, Inc.
28 *
29 * See http://www.winischhofer.net/ for more information and updates
30 *
31 * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
32 * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
33 *
34 */
35
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/kernel.h>
39#include <linux/spinlock.h>
40#include <linux/errno.h>
41#include <linux/string.h>
42#include <linux/mm.h>
43#include <linux/screen_info.h>
44#include <linux/slab.h>
45#include <linux/fb.h>
46#include <linux/selection.h>
47#include <linux/ioport.h>
48#include <linux/init.h>
49#include <linux/pci.h>
50#include <linux/vmalloc.h>
51#include <linux/capability.h>
52#include <linux/fs.h>
53#include <linux/types.h>
54#include <linux/uaccess.h>
55#include <asm/io.h>
56#ifdef CONFIG_MTRR
57#include <asm/mtrr.h>
58#endif
59
60#include "sis.h"
61#include "sis_main.h"
62
63#if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315)
64#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
65#warning sisfb will not work!
66#endif
67
68static void sisfb_handle_command(struct sis_video_info *ivideo,
69 struct sisfb_cmd *sisfb_command);
70
71/* ------------------ Internal helper routines ----------------- */
72
73static void __init
74sisfb_setdefaultparms(void)
75{
76 sisfb_off = 0;
77 sisfb_parm_mem = 0;
78 sisfb_accel = -1;
79 sisfb_ypan = -1;
80 sisfb_max = -1;
81 sisfb_userom = -1;
82 sisfb_useoem = -1;
83 sisfb_mode_idx = -1;
84 sisfb_parm_rate = -1;
85 sisfb_crt1off = 0;
86 sisfb_forcecrt1 = -1;
87 sisfb_crt2type = -1;
88 sisfb_crt2flags = 0;
89 sisfb_pdc = 0xff;
90 sisfb_pdca = 0xff;
91 sisfb_scalelcd = -1;
92 sisfb_specialtiming = CUT_NONE;
93 sisfb_lvdshl = -1;
94 sisfb_dstn = 0;
95 sisfb_fstn = 0;
96 sisfb_tvplug = -1;
97 sisfb_tvstd = -1;
98 sisfb_tvxposoffset = 0;
99 sisfb_tvyposoffset = 0;
100 sisfb_nocrt2rate = 0;
101#if !defined(__i386__) && !defined(__x86_64__)
102 sisfb_resetcard = 0;
103 sisfb_videoram = 0;
104#endif
105}
106
107/* ------------- Parameter parsing -------------- */
108
109static void sisfb_search_vesamode(unsigned int vesamode, bool quiet)
110{
111 int i = 0, j = 0;
112
113 /* We don't know the hardware specs yet and there is no ivideo */
114
115 if(vesamode == 0) {
116 if(!quiet)
117 printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
118
119 sisfb_mode_idx = DEFAULT_MODE;
120
121 return;
122 }
123
124 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
125
126 while(sisbios_mode[i++].mode_no[0] != 0) {
127 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
128 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
129 if(sisfb_fstn) {
130 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
131 sisbios_mode[i-1].mode_no[1] == 0x56 ||
132 sisbios_mode[i-1].mode_no[1] == 0x53)
133 continue;
134 } else {
135 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
136 sisbios_mode[i-1].mode_no[1] == 0x5b)
137 continue;
138 }
139 sisfb_mode_idx = i - 1;
140 j = 1;
141 break;
142 }
143 }
144 if((!j) && !quiet)
145 printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
146}
147
148static void sisfb_search_mode(char *name, bool quiet)
149{
150 unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
151 int i = 0;
152 char strbuf[16], strbuf1[20];
153 char *nameptr = name;
154
155 /* We don't know the hardware specs yet and there is no ivideo */
156
157 if(name == NULL) {
158 if(!quiet)
159 printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
160
161 sisfb_mode_idx = DEFAULT_MODE;
162 return;
163 }
164
165 if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
166 if(!quiet)
167 printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
168
169 sisfb_mode_idx = DEFAULT_MODE;
170 return;
171 }
172
173 if(strlen(name) <= 19) {
174 strcpy(strbuf1, name);
175 for(i = 0; i < strlen(strbuf1); i++) {
176 if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
177 }
178
179 /* This does some fuzzy mode naming detection */
180 if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
181 if((rate <= 32) || (depth > 32)) {
182 j = rate; rate = depth; depth = j;
183 }
184 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
185 nameptr = strbuf;
186 sisfb_parm_rate = rate;
187 } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
188 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
189 nameptr = strbuf;
190 } else {
191 xres = 0;
192 if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
193 sprintf(strbuf, "%ux%ux8", xres, yres);
194 nameptr = strbuf;
195 } else {
196 sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
197 return;
198 }
199 }
200 }
201
202 i = 0; j = 0;
203 while(sisbios_mode[i].mode_no[0] != 0) {
204 if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
205 if(sisfb_fstn) {
206 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
207 sisbios_mode[i-1].mode_no[1] == 0x56 ||
208 sisbios_mode[i-1].mode_no[1] == 0x53)
209 continue;
210 } else {
211 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
212 sisbios_mode[i-1].mode_no[1] == 0x5b)
213 continue;
214 }
215 sisfb_mode_idx = i - 1;
216 j = 1;
217 break;
218 }
219 }
220
221 if((!j) && !quiet)
222 printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
223}
224
225#ifndef MODULE
226static void sisfb_get_vga_mode_from_kernel(void)
227{
228#ifdef CONFIG_X86
229 char mymode[32];
230 int mydepth = screen_info.lfb_depth;
231
232 if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
233
234 if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) &&
235 (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
236 (mydepth >= 8) && (mydepth <= 32) ) {
237
238 if(mydepth == 24) mydepth = 32;
239
240 sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
241 screen_info.lfb_height,
242 mydepth);
243
244 printk(KERN_DEBUG
245 "sisfb: Using vga mode %s pre-set by kernel as default\n",
246 mymode);
247
248 sisfb_search_mode(mymode, true);
249 }
250#endif
251 return;
252}
253#endif
254
255static void __init
256sisfb_search_crt2type(const char *name)
257{
258 int i = 0;
259
260 /* We don't know the hardware specs yet and there is no ivideo */
261
262 if(name == NULL) return;
263
264 while(sis_crt2type[i].type_no != -1) {
265 if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
266 sisfb_crt2type = sis_crt2type[i].type_no;
267 sisfb_tvplug = sis_crt2type[i].tvplug_no;
268 sisfb_crt2flags = sis_crt2type[i].flags;
269 break;
270 }
271 i++;
272 }
273
274 sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
275 sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
276
277 if(sisfb_crt2type < 0)
278 printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
279}
280
281static void __init
282sisfb_search_tvstd(const char *name)
283{
284 int i = 0;
285
286 /* We don't know the hardware specs yet and there is no ivideo */
287
288 if(name == NULL)
289 return;
290
291 while(sis_tvtype[i].type_no != -1) {
292 if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
293 sisfb_tvstd = sis_tvtype[i].type_no;
294 break;
295 }
296 i++;
297 }
298}
299
300static void __init
301sisfb_search_specialtiming(const char *name)
302{
303 int i = 0;
304 bool found = false;
305
306 /* We don't know the hardware specs yet and there is no ivideo */
307
308 if(name == NULL)
309 return;
310
311 if(!strnicmp(name, "none", 4)) {
312 sisfb_specialtiming = CUT_FORCENONE;
313 printk(KERN_DEBUG "sisfb: Special timing disabled\n");
314 } else {
315 while(mycustomttable[i].chipID != 0) {
316 if(!strnicmp(name,mycustomttable[i].optionName,
317 strlen(mycustomttable[i].optionName))) {
318 sisfb_specialtiming = mycustomttable[i].SpecialID;
319 found = true;
320 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
321 mycustomttable[i].vendorName,
322 mycustomttable[i].cardName,
323 mycustomttable[i].optionName);
324 break;
325 }
326 i++;
327 }
328 if(!found) {
329 printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
330 printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
331 i = 0;
332 while(mycustomttable[i].chipID != 0) {
333 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
334 mycustomttable[i].optionName,
335 mycustomttable[i].vendorName,
336 mycustomttable[i].cardName);
337 i++;
338 }
339 }
340 }
341}
342
343/* ----------- Various detection routines ----------- */
344
345static void sisfb_detect_custom_timing(struct sis_video_info *ivideo)
346{
347 unsigned char *biosver = NULL;
348 unsigned char *biosdate = NULL;
349 bool footprint;
350 u32 chksum = 0;
351 int i, j;
352
353 if(ivideo->SiS_Pr.UseROM) {
354 biosver = ivideo->SiS_Pr.VirtualRomBase + 0x06;
355 biosdate = ivideo->SiS_Pr.VirtualRomBase + 0x2c;
356 for(i = 0; i < 32768; i++)
357 chksum += ivideo->SiS_Pr.VirtualRomBase[i];
358 }
359
360 i = 0;
361 do {
362 if( (mycustomttable[i].chipID == ivideo->chip) &&
363 ((!strlen(mycustomttable[i].biosversion)) ||
364 (ivideo->SiS_Pr.UseROM &&
365 (!strncmp(mycustomttable[i].biosversion, biosver,
366 strlen(mycustomttable[i].biosversion))))) &&
367 ((!strlen(mycustomttable[i].biosdate)) ||
368 (ivideo->SiS_Pr.UseROM &&
369 (!strncmp(mycustomttable[i].biosdate, biosdate,
370 strlen(mycustomttable[i].biosdate))))) &&
371 ((!mycustomttable[i].bioschksum) ||
372 (ivideo->SiS_Pr.UseROM &&
373 (mycustomttable[i].bioschksum == chksum))) &&
374 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
375 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
376 footprint = true;
377 for(j = 0; j < 5; j++) {
378 if(mycustomttable[i].biosFootprintAddr[j]) {
379 if(ivideo->SiS_Pr.UseROM) {
380 if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
381 mycustomttable[i].biosFootprintData[j]) {
382 footprint = false;
383 }
384 } else
385 footprint = false;
386 }
387 }
388 if(footprint) {
389 ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
390 printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
391 mycustomttable[i].vendorName,
392 mycustomttable[i].cardName);
393 printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
394 mycustomttable[i].optionName);
395 break;
396 }
397 }
398 i++;
399 } while(mycustomttable[i].chipID);
400}
401
402static bool sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
403{
404 int i, j, xres, yres, refresh, index;
405 u32 emodes;
406
407 if(buffer[0] != 0x00 || buffer[1] != 0xff ||
408 buffer[2] != 0xff || buffer[3] != 0xff ||
409 buffer[4] != 0xff || buffer[5] != 0xff ||
410 buffer[6] != 0xff || buffer[7] != 0x00) {
411 printk(KERN_DEBUG "sisfb: Bad EDID header\n");
412 return false;
413 }
414
415 if(buffer[0x12] != 0x01) {
416 printk(KERN_INFO "sisfb: EDID version %d not supported\n",
417 buffer[0x12]);
418 return false;
419 }
420
421 monitor->feature = buffer[0x18];
422
423 if(!(buffer[0x14] & 0x80)) {
424 if(!(buffer[0x14] & 0x08)) {
425 printk(KERN_INFO
426 "sisfb: WARNING: Monitor does not support separate syncs\n");
427 }
428 }
429
430 if(buffer[0x13] >= 0x01) {
431 /* EDID V1 rev 1 and 2: Search for monitor descriptor
432 * to extract ranges
433 */
434 j = 0x36;
435 for(i=0; i<4; i++) {
436 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
437 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
438 buffer[j + 4] == 0x00) {
439 monitor->hmin = buffer[j + 7];
440 monitor->hmax = buffer[j + 8];
441 monitor->vmin = buffer[j + 5];
442 monitor->vmax = buffer[j + 6];
443 monitor->dclockmax = buffer[j + 9] * 10 * 1000;
444 monitor->datavalid = true;
445 break;
446 }
447 j += 18;
448 }
449 }
450
451 if(!monitor->datavalid) {
452 /* Otherwise: Get a range from the list of supported
453 * Estabished Timings. This is not entirely accurate,
454 * because fixed frequency monitors are not supported
455 * that way.
456 */
457 monitor->hmin = 65535; monitor->hmax = 0;
458 monitor->vmin = 65535; monitor->vmax = 0;
459 monitor->dclockmax = 0;
460 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
461 for(i = 0; i < 13; i++) {
462 if(emodes & sisfb_ddcsmodes[i].mask) {
463 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
464 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
465 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
466 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
467 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
468 }
469 }
470 index = 0x26;
471 for(i = 0; i < 8; i++) {
472 xres = (buffer[index] + 31) * 8;
473 switch(buffer[index + 1] & 0xc0) {
474 case 0xc0: yres = (xres * 9) / 16; break;
475 case 0x80: yres = (xres * 4) / 5; break;
476 case 0x40: yres = (xres * 3) / 4; break;
477 default: yres = xres; break;
478 }
479 refresh = (buffer[index + 1] & 0x3f) + 60;
480 if((xres >= 640) && (yres >= 480)) {
481 for(j = 0; j < 8; j++) {
482 if((xres == sisfb_ddcfmodes[j].x) &&
483 (yres == sisfb_ddcfmodes[j].y) &&
484 (refresh == sisfb_ddcfmodes[j].v)) {
485 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
486 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
487 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
488 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
489 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[j].d;
490 }
491 }
492 }
493 index += 2;
494 }
495 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
496 monitor->datavalid = true;
497 }
498 }
499
500 return monitor->datavalid;
501}
502
503static void sisfb_handle_ddc(struct sis_video_info *ivideo,
504 struct sisfb_monitor *monitor, int crtno)
505{
506 unsigned short temp, i, realcrtno = crtno;
507 unsigned char buffer[256];
508
509 monitor->datavalid = false;
510
511 if(crtno) {
512 if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
513 else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
514 else return;
515 }
516
517 if((ivideo->sisfb_crt1off) && (!crtno))
518 return;
519
520 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
521 realcrtno, 0, &buffer[0], ivideo->vbflags2);
522 if((!temp) || (temp == 0xffff)) {
523 printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
524 return;
525 } else {
526 printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
527 printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
528 crtno + 1,
529 (temp & 0x1a) ? "" : "[none of the supported]",
530 (temp & 0x02) ? "2 " : "",
531 (temp & 0x08) ? "D&P" : "",
532 (temp & 0x10) ? "FPDI-2" : "");
533 if(temp & 0x02) {
534 i = 3; /* Number of retrys */
535 do {
536 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
537 realcrtno, 1, &buffer[0], ivideo->vbflags2);
538 } while((temp) && i--);
539 if(!temp) {
540 if(sisfb_interpret_edid(monitor, &buffer[0])) {
541 printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
542 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
543 monitor->dclockmax / 1000);
544 } else {
545 printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
546 }
547 } else {
548 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
549 }
550 } else {
551 printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
552 }
553 }
554}
555
556/* -------------- Mode validation --------------- */
557
558static bool
559sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
560 int mode_idx, int rate_idx, int rate)
561{
562 int htotal, vtotal;
563 unsigned int dclock, hsync;
564
565 if(!monitor->datavalid)
566 return true;
567
568 if(mode_idx < 0)
569 return false;
570
571 /* Skip for 320x200, 320x240, 640x400 */
572 switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
573 case 0x59:
574 case 0x41:
575 case 0x4f:
576 case 0x50:
577 case 0x56:
578 case 0x53:
579 case 0x2f:
580 case 0x5d:
581 case 0x5e:
582 return true;
583#ifdef CONFIG_FB_SIS_315
584 case 0x5a:
585 case 0x5b:
586 if(ivideo->sisvga_engine == SIS_315_VGA) return true;
587#endif
588 }
589
590 if(rate < (monitor->vmin - 1))
591 return false;
592 if(rate > (monitor->vmax + 1))
593 return false;
594
595 if(sisfb_gettotalfrommode(&ivideo->SiS_Pr,
596 sisbios_mode[mode_idx].mode_no[ivideo->mni],
597 &htotal, &vtotal, rate_idx)) {
598 dclock = (htotal * vtotal * rate) / 1000;
599 if(dclock > (monitor->dclockmax + 1000))
600 return false;
601 hsync = dclock / htotal;
602 if(hsync < (monitor->hmin - 1))
603 return false;
604 if(hsync > (monitor->hmax + 1))
605 return false;
606 } else {
607 return false;
608 }
609 return true;
610}
611
612static int
613sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
614{
615 u16 xres=0, yres, myres;
616
617#ifdef CONFIG_FB_SIS_300
618 if(ivideo->sisvga_engine == SIS_300_VGA) {
619 if(!(sisbios_mode[myindex].chipset & MD_SIS300))
620 return -1 ;
621 }
622#endif
623#ifdef CONFIG_FB_SIS_315
624 if(ivideo->sisvga_engine == SIS_315_VGA) {
625 if(!(sisbios_mode[myindex].chipset & MD_SIS315))
626 return -1;
627 }
628#endif
629
630 myres = sisbios_mode[myindex].yres;
631
632 switch(vbflags & VB_DISPTYPE_DISP2) {
633
634 case CRT2_LCD:
635 xres = ivideo->lcdxres; yres = ivideo->lcdyres;
636
637 if((ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) &&
638 (ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL856)) {
639 if(sisbios_mode[myindex].xres > xres)
640 return -1;
641 if(myres > yres)
642 return -1;
643 }
644
645 if(ivideo->sisfb_fstn) {
646 if(sisbios_mode[myindex].xres == 320) {
647 if(myres == 240) {
648 switch(sisbios_mode[myindex].mode_no[1]) {
649 case 0x50: myindex = MODE_FSTN_8; break;
650 case 0x56: myindex = MODE_FSTN_16; break;
651 case 0x53: return -1;
652 }
653 }
654 }
655 }
656
657 if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
658 sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
659 ivideo->SiS_Pr.SiS_CustomT, xres, yres, ivideo->vbflags2) < 0x14) {
660 return -1;
661 }
662 break;
663
664 case CRT2_TV:
665 if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
666 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
667 return -1;
668 }
669 break;
670
671 case CRT2_VGA:
672 if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
673 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
674 return -1;
675 }
676 break;
677 }
678
679 return myindex;
680}
681
682static u8
683sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
684{
685 int i = 0;
686 u16 xres = sisbios_mode[mode_idx].xres;
687 u16 yres = sisbios_mode[mode_idx].yres;
688
689 ivideo->rate_idx = 0;
690 while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
691 if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
692 if(sisfb_vrate[i].refresh == rate) {
693 ivideo->rate_idx = sisfb_vrate[i].idx;
694 break;
695 } else if(sisfb_vrate[i].refresh > rate) {
696 if((sisfb_vrate[i].refresh - rate) <= 3) {
697 DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
698 rate, sisfb_vrate[i].refresh);
699 ivideo->rate_idx = sisfb_vrate[i].idx;
700 ivideo->refresh_rate = sisfb_vrate[i].refresh;
701 } else if((sisfb_vrate[i].idx != 1) &&
702 ((rate - sisfb_vrate[i-1].refresh) <= 2)) {
703 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
704 rate, sisfb_vrate[i-1].refresh);
705 ivideo->rate_idx = sisfb_vrate[i-1].idx;
706 ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
707 }
708 break;
709 } else if((rate - sisfb_vrate[i].refresh) <= 2) {
710 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
711 rate, sisfb_vrate[i].refresh);
712 ivideo->rate_idx = sisfb_vrate[i].idx;
713 break;
714 }
715 }
716 i++;
717 }
718 if(ivideo->rate_idx > 0) {
719 return ivideo->rate_idx;
720 } else {
721 printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n",
722 rate, xres, yres);
723 return 0;
724 }
725}
726
727static bool
728sisfb_bridgeisslave(struct sis_video_info *ivideo)
729{
730 unsigned char P1_00;
731
732 if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE))
733 return false;
734
735 P1_00 = SiS_GetReg(SISPART1, 0x00);
736 if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
737 ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
738 return true;
739 } else {
740 return false;
741 }
742}
743
744static bool
745sisfballowretracecrt1(struct sis_video_info *ivideo)
746{
747 u8 temp;
748
749 temp = SiS_GetReg(SISCR, 0x17);
750 if(!(temp & 0x80))
751 return false;
752
753 temp = SiS_GetReg(SISSR, 0x1f);
754 if(temp & 0xc0)
755 return false;
756
757 return true;
758}
759
760static bool
761sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
762{
763 if(!sisfballowretracecrt1(ivideo))
764 return false;
765
766 if (SiS_GetRegByte(SISINPSTAT) & 0x08)
767 return true;
768 else
769 return false;
770}
771
772static void
773sisfbwaitretracecrt1(struct sis_video_info *ivideo)
774{
775 int watchdog;
776
777 if(!sisfballowretracecrt1(ivideo))
778 return;
779
780 watchdog = 65536;
781 while ((!(SiS_GetRegByte(SISINPSTAT) & 0x08)) && --watchdog);
782 watchdog = 65536;
783 while ((SiS_GetRegByte(SISINPSTAT) & 0x08) && --watchdog);
784}
785
786static bool
787sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
788{
789 unsigned char temp, reg;
790
791 switch(ivideo->sisvga_engine) {
792 case SIS_300_VGA: reg = 0x25; break;
793 case SIS_315_VGA: reg = 0x30; break;
794 default: return false;
795 }
796
797 temp = SiS_GetReg(SISPART1, reg);
798 if(temp & 0x02)
799 return true;
800 else
801 return false;
802}
803
804static bool
805sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
806{
807 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
808 if(!sisfb_bridgeisslave(ivideo)) {
809 return sisfbcheckvretracecrt2(ivideo);
810 }
811 }
812 return sisfbcheckvretracecrt1(ivideo);
813}
814
815static u32
816sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
817{
818 u8 idx, reg1, reg2, reg3, reg4;
819 u32 ret = 0;
820
821 (*vcount) = (*hcount) = 0;
822
823 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
824
825 ret |= (FB_VBLANK_HAVE_VSYNC |
826 FB_VBLANK_HAVE_HBLANK |
827 FB_VBLANK_HAVE_VBLANK |
828 FB_VBLANK_HAVE_VCOUNT |
829 FB_VBLANK_HAVE_HCOUNT);
830 switch(ivideo->sisvga_engine) {
831 case SIS_300_VGA: idx = 0x25; break;
832 default:
833 case SIS_315_VGA: idx = 0x30; break;
834 }
835 reg1 = SiS_GetReg(SISPART1, (idx+0)); /* 30 */
836 reg2 = SiS_GetReg(SISPART1, (idx+1)); /* 31 */
837 reg3 = SiS_GetReg(SISPART1, (idx+2)); /* 32 */
838 reg4 = SiS_GetReg(SISPART1, (idx+3)); /* 33 */
839 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
840 if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
841 if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
842 (*vcount) = reg3 | ((reg4 & 0x70) << 4);
843 (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
844
845 } else if(sisfballowretracecrt1(ivideo)) {
846
847 ret |= (FB_VBLANK_HAVE_VSYNC |
848 FB_VBLANK_HAVE_VBLANK |
849 FB_VBLANK_HAVE_VCOUNT |
850 FB_VBLANK_HAVE_HCOUNT);
851 reg1 = SiS_GetRegByte(SISINPSTAT);
852 if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
853 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
854 reg1 = SiS_GetReg(SISCR, 0x20);
855 reg1 = SiS_GetReg(SISCR, 0x1b);
856 reg2 = SiS_GetReg(SISCR, 0x1c);
857 reg3 = SiS_GetReg(SISCR, 0x1d);
858 (*vcount) = reg2 | ((reg3 & 0x07) << 8);
859 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
860 }
861
862 return ret;
863}
864
865static int
866sisfb_myblank(struct sis_video_info *ivideo, int blank)
867{
868 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
869 bool backlight = true;
870
871 switch(blank) {
872 case FB_BLANK_UNBLANK: /* on */
873 sr01 = 0x00;
874 sr11 = 0x00;
875 sr1f = 0x00;
876 cr63 = 0x00;
877 p2_0 = 0x20;
878 p1_13 = 0x00;
879 backlight = true;
880 break;
881 case FB_BLANK_NORMAL: /* blank */
882 sr01 = 0x20;
883 sr11 = 0x00;
884 sr1f = 0x00;
885 cr63 = 0x00;
886 p2_0 = 0x20;
887 p1_13 = 0x00;
888 backlight = true;
889 break;
890 case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
891 sr01 = 0x20;
892 sr11 = 0x08;
893 sr1f = 0x80;
894 cr63 = 0x40;
895 p2_0 = 0x40;
896 p1_13 = 0x80;
897 backlight = false;
898 break;
899 case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
900 sr01 = 0x20;
901 sr11 = 0x08;
902 sr1f = 0x40;
903 cr63 = 0x40;
904 p2_0 = 0x80;
905 p1_13 = 0x40;
906 backlight = false;
907 break;
908 case FB_BLANK_POWERDOWN: /* off */
909 sr01 = 0x20;
910 sr11 = 0x08;
911 sr1f = 0xc0;
912 cr63 = 0x40;
913 p2_0 = 0xc0;
914 p1_13 = 0xc0;
915 backlight = false;
916 break;
917 default:
918 return 1;
919 }
920
921 if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
922
923 if( (!ivideo->sisfb_thismonitor.datavalid) ||
924 ((ivideo->sisfb_thismonitor.datavalid) &&
925 (ivideo->sisfb_thismonitor.feature & 0xe0))) {
926
927 if(ivideo->sisvga_engine == SIS_315_VGA) {
928 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
929 }
930
931 if(!(sisfb_bridgeisslave(ivideo))) {
932 SiS_SetRegANDOR(SISSR, 0x01, ~0x20, sr01);
933 SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, sr1f);
934 }
935 }
936
937 }
938
939 if(ivideo->currentvbflags & CRT2_LCD) {
940
941 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
942 if(backlight) {
943 SiS_SiS30xBLOn(&ivideo->SiS_Pr);
944 } else {
945 SiS_SiS30xBLOff(&ivideo->SiS_Pr);
946 }
947 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
948#ifdef CONFIG_FB_SIS_315
949 if(ivideo->vbflags2 & VB2_CHRONTEL) {
950 if(backlight) {
951 SiS_Chrontel701xBLOn(&ivideo->SiS_Pr);
952 } else {
953 SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
954 }
955 }
956#endif
957 }
958
959 if(((ivideo->sisvga_engine == SIS_300_VGA) &&
960 (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) ||
961 ((ivideo->sisvga_engine == SIS_315_VGA) &&
962 ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) {
963 SiS_SetRegANDOR(SISSR, 0x11, ~0x0c, sr11);
964 }
965
966 if(ivideo->sisvga_engine == SIS_300_VGA) {
967 if((ivideo->vbflags2 & VB2_30xB) &&
968 (!(ivideo->vbflags2 & VB2_30xBDH))) {
969 SiS_SetRegANDOR(SISPART1, 0x13, 0x3f, p1_13);
970 }
971 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
972 if((ivideo->vbflags2 & VB2_30xB) &&
973 (!(ivideo->vbflags2 & VB2_30xBDH))) {
974 SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0);
975 }
976 }
977
978 } else if(ivideo->currentvbflags & CRT2_VGA) {
979
980 if(ivideo->vbflags2 & VB2_30xB) {
981 SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0);
982 }
983
984 }
985
986 return 0;
987}
988
989/* ------------- Callbacks from init.c/init301.c -------------- */
990
991#ifdef CONFIG_FB_SIS_300
992unsigned int
993sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg)
994{
995 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
996 u32 val = 0;
997
998 pci_read_config_dword(ivideo->nbridge, reg, &val);
999 return (unsigned int)val;
1000}
1001
1002void
1003sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val)
1004{
1005 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1006
1007 pci_write_config_dword(ivideo->nbridge, reg, (u32)val);
1008}
1009
1010unsigned int
1011sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg)
1012{
1013 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1014 u32 val = 0;
1015
1016 if(!ivideo->lpcdev) return 0;
1017
1018 pci_read_config_dword(ivideo->lpcdev, reg, &val);
1019 return (unsigned int)val;
1020}
1021#endif
1022
1023#ifdef CONFIG_FB_SIS_315
1024void
1025sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val)
1026{
1027 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1028
1029 pci_write_config_byte(ivideo->nbridge, reg, (u8)val);
1030}
1031
1032unsigned int
1033sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg)
1034{
1035 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1036 u16 val = 0;
1037
1038 if(!ivideo->lpcdev) return 0;
1039
1040 pci_read_config_word(ivideo->lpcdev, reg, &val);
1041 return (unsigned int)val;
1042}
1043#endif
1044
1045/* ----------- FBDev related routines for all series ----------- */
1046
1047static int
1048sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
1049{
1050 return (var->bits_per_pixel == 8) ? 256 : 16;
1051}
1052
1053static void
1054sisfb_set_vparms(struct sis_video_info *ivideo)
1055{
1056 switch(ivideo->video_bpp) {
1057 case 8:
1058 ivideo->DstColor = 0x0000;
1059 ivideo->SiS310_AccelDepth = 0x00000000;
1060 ivideo->video_cmap_len = 256;
1061 break;
1062 case 16:
1063 ivideo->DstColor = 0x8000;
1064 ivideo->SiS310_AccelDepth = 0x00010000;
1065 ivideo->video_cmap_len = 16;
1066 break;
1067 case 32:
1068 ivideo->DstColor = 0xC000;
1069 ivideo->SiS310_AccelDepth = 0x00020000;
1070 ivideo->video_cmap_len = 16;
1071 break;
1072 default:
1073 ivideo->video_cmap_len = 16;
1074 printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
1075 ivideo->accel = 0;
1076 }
1077}
1078
1079static int
1080sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1081{
1082 int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3));
1083
1084 if(maxyres > 32767) maxyres = 32767;
1085
1086 return maxyres;
1087}
1088
1089static void
1090sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1091{
1092 ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3);
1093 ivideo->scrnpitchCRT1 = ivideo->video_linelength;
1094 if(!(ivideo->currentvbflags & CRT1_LCDA)) {
1095 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1096 ivideo->scrnpitchCRT1 <<= 1;
1097 }
1098 }
1099}
1100
1101static void
1102sisfb_set_pitch(struct sis_video_info *ivideo)
1103{
1104 bool isslavemode = false;
1105 unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
1106 unsigned short HDisplay2 = ivideo->video_linelength >> 3;
1107
1108 if(sisfb_bridgeisslave(ivideo)) isslavemode = true;
1109
1110 /* We need to set pitch for CRT1 if bridge is in slave mode, too */
1111 if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
1112 SiS_SetReg(SISCR, 0x13, (HDisplay1 & 0xFF));
1113 SiS_SetRegANDOR(SISSR, 0x0E, 0xF0, (HDisplay1 >> 8));
1114 }
1115
1116 /* We must not set the pitch for CRT2 if bridge is in slave mode */
1117 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
1118 SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01);
1119 SiS_SetReg(SISPART1, 0x07, (HDisplay2 & 0xFF));
1120 SiS_SetRegANDOR(SISPART1, 0x09, 0xF0, (HDisplay2 >> 8));
1121 }
1122}
1123
1124static void
1125sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1126{
1127 ivideo->video_cmap_len = sisfb_get_cmap_len(var);
1128
1129 switch(var->bits_per_pixel) {
1130 case 8:
1131 var->red.offset = var->green.offset = var->blue.offset = 0;
1132 var->red.length = var->green.length = var->blue.length = 8;
1133 break;
1134 case 16:
1135 var->red.offset = 11;
1136 var->red.length = 5;
1137 var->green.offset = 5;
1138 var->green.length = 6;
1139 var->blue.offset = 0;
1140 var->blue.length = 5;
1141 var->transp.offset = 0;
1142 var->transp.length = 0;
1143 break;
1144 case 32:
1145 var->red.offset = 16;
1146 var->red.length = 8;
1147 var->green.offset = 8;
1148 var->green.length = 8;
1149 var->blue.offset = 0;
1150 var->blue.length = 8;
1151 var->transp.offset = 24;
1152 var->transp.length = 8;
1153 break;
1154 }
1155}
1156
1157static int
1158sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
1159{
1160 unsigned short modeno = ivideo->mode_no;
1161
1162 /* >=2.6.12's fbcon clears the screen anyway */
1163 modeno |= 0x80;
1164
1165 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1166
1167 sisfb_pre_setmode(ivideo);
1168
1169 if(!SiSSetMode(&ivideo->SiS_Pr, modeno)) {
1170 printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
1171 return -EINVAL;
1172 }
1173
1174 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1175
1176 sisfb_post_setmode(ivideo);
1177
1178 return 0;
1179}
1180
1181
1182static int
1183sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
1184{
1185 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1186 unsigned int htotal = 0, vtotal = 0;
1187 unsigned int drate = 0, hrate = 0;
1188 int found_mode = 0, ret;
1189 int old_mode;
1190 u32 pixclock;
1191
1192 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
1193
1194 vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
1195
1196 pixclock = var->pixclock;
1197
1198 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1199 vtotal += var->yres;
1200 vtotal <<= 1;
1201 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1202 vtotal += var->yres;
1203 vtotal <<= 2;
1204 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1205 vtotal += var->yres;
1206 vtotal <<= 1;
1207 } else vtotal += var->yres;
1208
1209 if(!(htotal) || !(vtotal)) {
1210 DPRINTK("sisfb: Invalid 'var' information\n");
1211 return -EINVAL;
1212 }
1213
1214 if(pixclock && htotal && vtotal) {
1215 drate = 1000000000 / pixclock;
1216 hrate = (drate * 1000) / htotal;
1217 ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1218 } else {
1219 ivideo->refresh_rate = 60;
1220 }
1221
1222 old_mode = ivideo->sisfb_mode_idx;
1223 ivideo->sisfb_mode_idx = 0;
1224
1225 while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&
1226 (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {
1227 if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&
1228 (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&
1229 (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {
1230 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
1231 found_mode = 1;
1232 break;
1233 }
1234 ivideo->sisfb_mode_idx++;
1235 }
1236
1237 if(found_mode) {
1238 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
1239 ivideo->sisfb_mode_idx, ivideo->currentvbflags);
1240 } else {
1241 ivideo->sisfb_mode_idx = -1;
1242 }
1243
1244 if(ivideo->sisfb_mode_idx < 0) {
1245 printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,
1246 var->yres, var->bits_per_pixel);
1247 ivideo->sisfb_mode_idx = old_mode;
1248 return -EINVAL;
1249 }
1250
1251 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
1252
1253 if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {
1254 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
1255 ivideo->refresh_rate = 60;
1256 }
1257
1258 if(isactive) {
1259 /* If acceleration to be used? Need to know
1260 * before pre/post_set_mode()
1261 */
1262 ivideo->accel = 0;
1263#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
1264#ifdef STUPID_ACCELF_TEXT_SHIT
1265 if(var->accel_flags & FB_ACCELF_TEXT) {
1266 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1267 } else {
1268 info->flags |= FBINFO_HWACCEL_DISABLED;
1269 }
1270#endif
1271 if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1;
1272#else
1273 if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
1274#endif
1275
1276 if((ret = sisfb_set_mode(ivideo, 1))) {
1277 return ret;
1278 }
1279
1280 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
1281 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
1282 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
1283
1284 sisfb_calc_pitch(ivideo, var);
1285 sisfb_set_pitch(ivideo);
1286
1287 sisfb_set_vparms(ivideo);
1288
1289 ivideo->current_width = ivideo->video_width;
1290 ivideo->current_height = ivideo->video_height;
1291 ivideo->current_bpp = ivideo->video_bpp;
1292 ivideo->current_htotal = htotal;
1293 ivideo->current_vtotal = vtotal;
1294 ivideo->current_linelength = ivideo->video_linelength;
1295 ivideo->current_pixclock = var->pixclock;
1296 ivideo->current_refresh_rate = ivideo->refresh_rate;
1297 ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
1298 }
1299
1300 return 0;
1301}
1302
1303static void
1304sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base)
1305{
1306 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1307
1308 SiS_SetReg(SISCR, 0x0D, base & 0xFF);
1309 SiS_SetReg(SISCR, 0x0C, (base >> 8) & 0xFF);
1310 SiS_SetReg(SISSR, 0x0D, (base >> 16) & 0xFF);
1311 if(ivideo->sisvga_engine == SIS_315_VGA) {
1312 SiS_SetRegANDOR(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
1313 }
1314}
1315
1316static void
1317sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
1318{
1319 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1320 SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01);
1321 SiS_SetReg(SISPART1, 0x06, (base & 0xFF));
1322 SiS_SetReg(SISPART1, 0x05, ((base >> 8) & 0xFF));
1323 SiS_SetReg(SISPART1, 0x04, ((base >> 16) & 0xFF));
1324 if(ivideo->sisvga_engine == SIS_315_VGA) {
1325 SiS_SetRegANDOR(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1326 }
1327 }
1328}
1329
1330static int
1331sisfb_pan_var(struct sis_video_info *ivideo, struct fb_info *info,
1332 struct fb_var_screeninfo *var)
1333{
1334 ivideo->current_base = var->yoffset * info->var.xres_virtual
1335 + var->xoffset;
1336
1337 /* calculate base bpp dep. */
1338 switch (info->var.bits_per_pixel) {
1339 case 32:
1340 break;
1341 case 16:
1342 ivideo->current_base >>= 1;
1343 break;
1344 case 8:
1345 default:
1346 ivideo->current_base >>= 2;
1347 break;
1348 }
1349
1350 ivideo->current_base += (ivideo->video_offset >> 2);
1351
1352 sisfb_set_base_CRT1(ivideo, ivideo->current_base);
1353 sisfb_set_base_CRT2(ivideo, ivideo->current_base);
1354
1355 return 0;
1356}
1357
1358static int
1359sisfb_open(struct fb_info *info, int user)
1360{
1361 return 0;
1362}
1363
1364static int
1365sisfb_release(struct fb_info *info, int user)
1366{
1367 return 0;
1368}
1369
1370static int
1371sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1372 unsigned transp, struct fb_info *info)
1373{
1374 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1375
1376 if(regno >= sisfb_get_cmap_len(&info->var))
1377 return 1;
1378
1379 switch(info->var.bits_per_pixel) {
1380 case 8:
1381 SiS_SetRegByte(SISDACA, regno);
1382 SiS_SetRegByte(SISDACD, (red >> 10));
1383 SiS_SetRegByte(SISDACD, (green >> 10));
1384 SiS_SetRegByte(SISDACD, (blue >> 10));
1385 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1386 SiS_SetRegByte(SISDAC2A, regno);
1387 SiS_SetRegByte(SISDAC2D, (red >> 8));
1388 SiS_SetRegByte(SISDAC2D, (green >> 8));
1389 SiS_SetRegByte(SISDAC2D, (blue >> 8));
1390 }
1391 break;
1392 case 16:
1393 if (regno >= 16)
1394 break;
1395
1396 ((u32 *)(info->pseudo_palette))[regno] =
1397 (red & 0xf800) |
1398 ((green & 0xfc00) >> 5) |
1399 ((blue & 0xf800) >> 11);
1400 break;
1401 case 32:
1402 if (regno >= 16)
1403 break;
1404
1405 red >>= 8;
1406 green >>= 8;
1407 blue >>= 8;
1408 ((u32 *)(info->pseudo_palette))[regno] =
1409 (red << 16) | (green << 8) | (blue);
1410 break;
1411 }
1412 return 0;
1413}
1414
1415static int
1416sisfb_set_par(struct fb_info *info)
1417{
1418 int err;
1419
1420 if((err = sisfb_do_set_var(&info->var, 1, info)))
1421 return err;
1422
1423 sisfb_get_fix(&info->fix, -1, info);
1424
1425 return 0;
1426}
1427
1428static int
1429sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1430{
1431 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1432 unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
1433 unsigned int drate = 0, hrate = 0, maxyres;
1434 int found_mode = 0;
1435 int refresh_rate, search_idx, tidx;
1436 bool recalc_clock = false;
1437 u32 pixclock;
1438
1439 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
1440
1441 vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
1442
1443 pixclock = var->pixclock;
1444
1445 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1446 vtotal += var->yres;
1447 vtotal <<= 1;
1448 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1449 vtotal += var->yres;
1450 vtotal <<= 2;
1451 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1452 vtotal += var->yres;
1453 vtotal <<= 1;
1454 } else
1455 vtotal += var->yres;
1456
1457 if(!(htotal) || !(vtotal)) {
1458 SISFAIL("sisfb: no valid timing data");
1459 }
1460
1461 search_idx = 0;
1462 while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
1463 (sisbios_mode[search_idx].xres <= var->xres) ) {
1464 if( (sisbios_mode[search_idx].xres == var->xres) &&
1465 (sisbios_mode[search_idx].yres == var->yres) &&
1466 (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1467 if((tidx = sisfb_validate_mode(ivideo, search_idx,
1468 ivideo->currentvbflags)) > 0) {
1469 found_mode = 1;
1470 search_idx = tidx;
1471 break;
1472 }
1473 }
1474 search_idx++;
1475 }
1476
1477 if(!found_mode) {
1478 search_idx = 0;
1479 while(sisbios_mode[search_idx].mode_no[0] != 0) {
1480 if( (var->xres <= sisbios_mode[search_idx].xres) &&
1481 (var->yres <= sisbios_mode[search_idx].yres) &&
1482 (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
1483 if((tidx = sisfb_validate_mode(ivideo,search_idx,
1484 ivideo->currentvbflags)) > 0) {
1485 found_mode = 1;
1486 search_idx = tidx;
1487 break;
1488 }
1489 }
1490 search_idx++;
1491 }
1492 if(found_mode) {
1493 printk(KERN_DEBUG
1494 "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
1495 var->xres, var->yres, var->bits_per_pixel,
1496 sisbios_mode[search_idx].xres,
1497 sisbios_mode[search_idx].yres,
1498 var->bits_per_pixel);
1499 var->xres = sisbios_mode[search_idx].xres;
1500 var->yres = sisbios_mode[search_idx].yres;
1501 } else {
1502 printk(KERN_ERR
1503 "sisfb: Failed to find supported mode near %dx%dx%d\n",
1504 var->xres, var->yres, var->bits_per_pixel);
1505 return -EINVAL;
1506 }
1507 }
1508
1509 if( ((ivideo->vbflags2 & VB2_LVDS) ||
1510 ((ivideo->vbflags2 & VB2_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
1511 (var->bits_per_pixel == 8) ) {
1512 /* Slave modes on LVDS and 301B-DH */
1513 refresh_rate = 60;
1514 recalc_clock = true;
1515 } else if( (ivideo->current_htotal == htotal) &&
1516 (ivideo->current_vtotal == vtotal) &&
1517 (ivideo->current_pixclock == pixclock) ) {
1518 /* x=x & y=y & c=c -> assume depth change */
1519 drate = 1000000000 / pixclock;
1520 hrate = (drate * 1000) / htotal;
1521 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1522 } else if( ( (ivideo->current_htotal != htotal) ||
1523 (ivideo->current_vtotal != vtotal) ) &&
1524 (ivideo->current_pixclock == var->pixclock) ) {
1525 /* x!=x | y!=y & c=c -> invalid pixclock */
1526 if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
1527 refresh_rate =
1528 ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
1529 } else if(ivideo->sisfb_parm_rate != -1) {
1530 /* Sic, sisfb_parm_rate - want to know originally desired rate here */
1531 refresh_rate = ivideo->sisfb_parm_rate;
1532 } else {
1533 refresh_rate = 60;
1534 }
1535 recalc_clock = true;
1536 } else if((pixclock) && (htotal) && (vtotal)) {
1537 drate = 1000000000 / pixclock;
1538 hrate = (drate * 1000) / htotal;
1539 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1540 } else if(ivideo->current_refresh_rate) {
1541 refresh_rate = ivideo->current_refresh_rate;
1542 recalc_clock = true;
1543 } else {
1544 refresh_rate = 60;
1545 recalc_clock = true;
1546 }
1547
1548 myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
1549
1550 /* Eventually recalculate timing and clock */
1551 if(recalc_clock) {
1552 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
1553 var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
1554 sisbios_mode[search_idx].mode_no[ivideo->mni],
1555 myrateindex));
1556 sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr,
1557 sisbios_mode[search_idx].mode_no[ivideo->mni],
1558 myrateindex, var);
1559 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1560 var->pixclock <<= 1;
1561 }
1562 }
1563
1564 if(ivideo->sisfb_thismonitor.datavalid) {
1565 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
1566 myrateindex, refresh_rate)) {
1567 printk(KERN_INFO
1568 "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1569 }
1570 }
1571
1572 /* Adapt RGB settings */
1573 sisfb_bpp_to_var(ivideo, var);
1574
1575 /* Sanity check for offsets */
1576 if(var->xoffset < 0) var->xoffset = 0;
1577 if(var->yoffset < 0) var->yoffset = 0;
1578
1579 if(var->xres > var->xres_virtual)
1580 var->xres_virtual = var->xres;
1581
1582 if(ivideo->sisfb_ypan) {
1583 maxyres = sisfb_calc_maxyres(ivideo, var);
1584 if(ivideo->sisfb_max) {
1585 var->yres_virtual = maxyres;
1586 } else {
1587 if(var->yres_virtual > maxyres) {
1588 var->yres_virtual = maxyres;
1589 }
1590 }
1591 if(var->yres_virtual <= var->yres) {
1592 var->yres_virtual = var->yres;
1593 }
1594 } else {
1595 if(var->yres != var->yres_virtual) {
1596 var->yres_virtual = var->yres;
1597 }
1598 var->xoffset = 0;
1599 var->yoffset = 0;
1600 }
1601
1602 /* Truncate offsets to maximum if too high */
1603 if(var->xoffset > var->xres_virtual - var->xres) {
1604 var->xoffset = var->xres_virtual - var->xres - 1;
1605 }
1606
1607 if(var->yoffset > var->yres_virtual - var->yres) {
1608 var->yoffset = var->yres_virtual - var->yres - 1;
1609 }
1610
1611 /* Set everything else to 0 */
1612 var->red.msb_right =
1613 var->green.msb_right =
1614 var->blue.msb_right =
1615 var->transp.offset =
1616 var->transp.length =
1617 var->transp.msb_right = 0;
1618
1619 return 0;
1620}
1621
1622static int
1623sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
1624{
1625 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1626 int err;
1627
1628 if (var->vmode & FB_VMODE_YWRAP)
1629 return -EINVAL;
1630
1631 if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1632 var->yoffset + info->var.yres > info->var.yres_virtual)
1633 return -EINVAL;
1634
1635 err = sisfb_pan_var(ivideo, info, var);
1636 if (err < 0)
1637 return err;
1638
1639 info->var.xoffset = var->xoffset;
1640 info->var.yoffset = var->yoffset;
1641
1642 return 0;
1643}
1644
1645static int
1646sisfb_blank(int blank, struct fb_info *info)
1647{
1648 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1649
1650 return sisfb_myblank(ivideo, blank);
1651}
1652
1653/* ----------- FBDev related routines for all series ---------- */
1654
1655static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
1656 unsigned long arg)
1657{
1658 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1659 struct sis_memreq sismemreq;
1660 struct fb_vblank sisvbblank;
1661 u32 gpu32 = 0;
1662#ifndef __user
1663#define __user
1664#endif
1665 u32 __user *argp = (u32 __user *)arg;
1666
1667 switch(cmd) {
1668 case FBIO_ALLOC:
1669 if(!capable(CAP_SYS_RAWIO))
1670 return -EPERM;
1671
1672 if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq)))
1673 return -EFAULT;
1674
1675 sis_malloc(&sismemreq);
1676
1677 if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
1678 sis_free((u32)sismemreq.offset);
1679 return -EFAULT;
1680 }
1681 break;
1682
1683 case FBIO_FREE:
1684 if(!capable(CAP_SYS_RAWIO))
1685 return -EPERM;
1686
1687 if(get_user(gpu32, argp))
1688 return -EFAULT;
1689
1690 sis_free(gpu32);
1691 break;
1692
1693 case FBIOGET_VBLANK:
1694
1695 memset(&sisvbblank, 0, sizeof(struct fb_vblank));
1696
1697 sisvbblank.count = 0;
1698 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
1699
1700 if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank)))
1701 return -EFAULT;
1702
1703 break;
1704
1705 case SISFB_GET_INFO_SIZE:
1706 return put_user(sizeof(struct sisfb_info), argp);
1707
1708 case SISFB_GET_INFO_OLD:
1709 if(ivideo->warncount++ < 10)
1710 printk(KERN_INFO
1711 "sisfb: Deprecated ioctl call received - update your application!\n");
1712 case SISFB_GET_INFO: /* For communication with X driver */
1713 ivideo->sisfb_infoblock.sisfb_id = SISFB_ID;
1714 ivideo->sisfb_infoblock.sisfb_version = VER_MAJOR;
1715 ivideo->sisfb_infoblock.sisfb_revision = VER_MINOR;
1716 ivideo->sisfb_infoblock.sisfb_patchlevel = VER_LEVEL;
1717 ivideo->sisfb_infoblock.chip_id = ivideo->chip_id;
1718 ivideo->sisfb_infoblock.sisfb_pci_vendor = ivideo->chip_vendor;
1719 ivideo->sisfb_infoblock.memory = ivideo->video_size / 1024;
1720 ivideo->sisfb_infoblock.heapstart = ivideo->heapstart / 1024;
1721 if(ivideo->modechanged) {
1722 ivideo->sisfb_infoblock.fbvidmode = ivideo->mode_no;
1723 } else {
1724 ivideo->sisfb_infoblock.fbvidmode = ivideo->modeprechange;
1725 }
1726 ivideo->sisfb_infoblock.sisfb_caps = ivideo->caps;
1727 ivideo->sisfb_infoblock.sisfb_tqlen = ivideo->cmdQueueSize / 1024;
1728 ivideo->sisfb_infoblock.sisfb_pcibus = ivideo->pcibus;
1729 ivideo->sisfb_infoblock.sisfb_pcislot = ivideo->pcislot;
1730 ivideo->sisfb_infoblock.sisfb_pcifunc = ivideo->pcifunc;
1731 ivideo->sisfb_infoblock.sisfb_lcdpdc = ivideo->detectedpdc;
1732 ivideo->sisfb_infoblock.sisfb_lcdpdca = ivideo->detectedpdca;
1733 ivideo->sisfb_infoblock.sisfb_lcda = ivideo->detectedlcda;
1734 ivideo->sisfb_infoblock.sisfb_vbflags = ivideo->vbflags;
1735 ivideo->sisfb_infoblock.sisfb_currentvbflags = ivideo->currentvbflags;
1736 ivideo->sisfb_infoblock.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
1737 ivideo->sisfb_infoblock.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
1738 ivideo->sisfb_infoblock.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
1739 ivideo->sisfb_infoblock.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
1740 ivideo->sisfb_infoblock.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
1741 ivideo->sisfb_infoblock.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
1742 ivideo->sisfb_infoblock.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
1743 ivideo->sisfb_infoblock.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
1744 ivideo->sisfb_infoblock.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
1745 ivideo->sisfb_infoblock.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
1746 ivideo->sisfb_infoblock.sisfb_heapsize = ivideo->sisfb_heap_size / 1024;
1747 ivideo->sisfb_infoblock.sisfb_videooffset = ivideo->video_offset;
1748 ivideo->sisfb_infoblock.sisfb_curfstn = ivideo->curFSTN;
1749 ivideo->sisfb_infoblock.sisfb_curdstn = ivideo->curDSTN;
1750 ivideo->sisfb_infoblock.sisfb_vbflags2 = ivideo->vbflags2;
1751 ivideo->sisfb_infoblock.sisfb_can_post = ivideo->sisfb_can_post ? 1 : 0;
1752 ivideo->sisfb_infoblock.sisfb_card_posted = ivideo->sisfb_card_posted ? 1 : 0;
1753 ivideo->sisfb_infoblock.sisfb_was_boot_device = ivideo->sisfb_was_boot_device ? 1 : 0;
1754
1755 if(copy_to_user((void __user *)arg, &ivideo->sisfb_infoblock,
1756 sizeof(ivideo->sisfb_infoblock)))
1757 return -EFAULT;
1758
1759 break;
1760
1761 case SISFB_GET_VBRSTATUS_OLD:
1762 if(ivideo->warncount++ < 10)
1763 printk(KERN_INFO
1764 "sisfb: Deprecated ioctl call received - update your application!\n");
1765 case SISFB_GET_VBRSTATUS:
1766 if(sisfb_CheckVBRetrace(ivideo))
1767 return put_user((u32)1, argp);
1768 else
1769 return put_user((u32)0, argp);
1770
1771 case SISFB_GET_AUTOMAXIMIZE_OLD:
1772 if(ivideo->warncount++ < 10)
1773 printk(KERN_INFO
1774 "sisfb: Deprecated ioctl call received - update your application!\n");
1775 case SISFB_GET_AUTOMAXIMIZE:
1776 if(ivideo->sisfb_max)
1777 return put_user((u32)1, argp);
1778 else
1779 return put_user((u32)0, argp);
1780
1781 case SISFB_SET_AUTOMAXIMIZE_OLD:
1782 if(ivideo->warncount++ < 10)
1783 printk(KERN_INFO
1784 "sisfb: Deprecated ioctl call received - update your application!\n");
1785 case SISFB_SET_AUTOMAXIMIZE:
1786 if(get_user(gpu32, argp))
1787 return -EFAULT;
1788
1789 ivideo->sisfb_max = (gpu32) ? 1 : 0;
1790 break;
1791
1792 case SISFB_SET_TVPOSOFFSET:
1793 if(get_user(gpu32, argp))
1794 return -EFAULT;
1795
1796 sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
1797 sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
1798 break;
1799
1800 case SISFB_GET_TVPOSOFFSET:
1801 return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
1802 argp);
1803
1804 case SISFB_COMMAND:
1805 if(copy_from_user(&ivideo->sisfb_command, (void __user *)arg,
1806 sizeof(struct sisfb_cmd)))
1807 return -EFAULT;
1808
1809 sisfb_handle_command(ivideo, &ivideo->sisfb_command);
1810
1811 if(copy_to_user((void __user *)arg, &ivideo->sisfb_command,
1812 sizeof(struct sisfb_cmd)))
1813 return -EFAULT;
1814
1815 break;
1816
1817 case SISFB_SET_LOCK:
1818 if(get_user(gpu32, argp))
1819 return -EFAULT;
1820
1821 ivideo->sisfblocked = (gpu32) ? 1 : 0;
1822 break;
1823
1824 default:
1825#ifdef SIS_NEW_CONFIG_COMPAT
1826 return -ENOIOCTLCMD;
1827#else
1828 return -EINVAL;
1829#endif
1830 }
1831 return 0;
1832}
1833
1834static int
1835sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
1836{
1837 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1838
1839 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1840
1841 strlcpy(fix->id, ivideo->myid, sizeof(fix->id));
1842
1843 mutex_lock(&info->mm_lock);
1844 fix->smem_start = ivideo->video_base + ivideo->video_offset;
1845 fix->smem_len = ivideo->sisfb_mem;
1846 mutex_unlock(&info->mm_lock);
1847 fix->type = FB_TYPE_PACKED_PIXELS;
1848 fix->type_aux = 0;
1849 fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1850 fix->xpanstep = 1;
1851 fix->ypanstep = (ivideo->sisfb_ypan) ? 1 : 0;
1852 fix->ywrapstep = 0;
1853 fix->line_length = ivideo->video_linelength;
1854 fix->mmio_start = ivideo->mmio_base;
1855 fix->mmio_len = ivideo->mmio_size;
1856 if(ivideo->sisvga_engine == SIS_300_VGA) {
1857 fix->accel = FB_ACCEL_SIS_GLAMOUR;
1858 } else if((ivideo->chip == SIS_330) ||
1859 (ivideo->chip == SIS_760) ||
1860 (ivideo->chip == SIS_761)) {
1861 fix->accel = FB_ACCEL_SIS_XABRE;
1862 } else if(ivideo->chip == XGI_20) {
1863 fix->accel = FB_ACCEL_XGI_VOLARI_Z;
1864 } else if(ivideo->chip >= XGI_40) {
1865 fix->accel = FB_ACCEL_XGI_VOLARI_V;
1866 } else {
1867 fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
1868 }
1869
1870 return 0;
1871}
1872
1873/* ---------------- fb_ops structures ----------------- */
1874
1875static struct fb_ops sisfb_ops = {
1876 .owner = THIS_MODULE,
1877 .fb_open = sisfb_open,
1878 .fb_release = sisfb_release,
1879 .fb_check_var = sisfb_check_var,
1880 .fb_set_par = sisfb_set_par,
1881 .fb_setcolreg = sisfb_setcolreg,
1882 .fb_pan_display = sisfb_pan_display,
1883 .fb_blank = sisfb_blank,
1884 .fb_fillrect = fbcon_sis_fillrect,
1885 .fb_copyarea = fbcon_sis_copyarea,
1886 .fb_imageblit = cfb_imageblit,
1887 .fb_sync = fbcon_sis_sync,
1888#ifdef SIS_NEW_CONFIG_COMPAT
1889 .fb_compat_ioctl= sisfb_ioctl,
1890#endif
1891 .fb_ioctl = sisfb_ioctl
1892};
1893
1894/* ---------------- Chip generation dependent routines ---------------- */
1895
1896static struct pci_dev *sisfb_get_northbridge(int basechipid)
1897{
1898 struct pci_dev *pdev = NULL;
1899 int nbridgenum, nbridgeidx, i;
1900 static const unsigned short nbridgeids[] = {
1901 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */
1902 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */
1903 PCI_DEVICE_ID_SI_730,
1904 PCI_DEVICE_ID_SI_550, /* for SiS 550 VGA */
1905 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */
1906 PCI_DEVICE_ID_SI_651,
1907 PCI_DEVICE_ID_SI_740,
1908 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760/761 VGA */
1909 PCI_DEVICE_ID_SI_741,
1910 PCI_DEVICE_ID_SI_660,
1911 PCI_DEVICE_ID_SI_760,
1912 PCI_DEVICE_ID_SI_761
1913 };
1914
1915 switch(basechipid) {
1916#ifdef CONFIG_FB_SIS_300
1917 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break;
1918 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break;
1919#endif
1920#ifdef CONFIG_FB_SIS_315
1921 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break;
1922 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break;
1923 case SIS_660: nbridgeidx = 7; nbridgenum = 5; break;
1924#endif
1925 default: return NULL;
1926 }
1927 for(i = 0; i < nbridgenum; i++) {
1928 if((pdev = pci_get_device(PCI_VENDOR_ID_SI,
1929 nbridgeids[nbridgeidx+i], NULL)))
1930 break;
1931 }
1932 return pdev;
1933}
1934
1935static int sisfb_get_dram_size(struct sis_video_info *ivideo)
1936{
1937#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
1938 u8 reg;
1939#endif
1940
1941 ivideo->video_size = 0;
1942 ivideo->UMAsize = ivideo->LFBsize = 0;
1943
1944 switch(ivideo->chip) {
1945#ifdef CONFIG_FB_SIS_300
1946 case SIS_300:
1947 reg = SiS_GetReg(SISSR, 0x14);
1948 ivideo->video_size = ((reg & 0x3F) + 1) << 20;
1949 break;
1950 case SIS_540:
1951 case SIS_630:
1952 case SIS_730:
1953 if(!ivideo->nbridge)
1954 return -1;
1955 pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
1956 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
1957 break;
1958#endif
1959#ifdef CONFIG_FB_SIS_315
1960 case SIS_315H:
1961 case SIS_315PRO:
1962 case SIS_315:
1963 reg = SiS_GetReg(SISSR, 0x14);
1964 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
1965 switch((reg >> 2) & 0x03) {
1966 case 0x01:
1967 case 0x03:
1968 ivideo->video_size <<= 1;
1969 break;
1970 case 0x02:
1971 ivideo->video_size += (ivideo->video_size/2);
1972 }
1973 break;
1974 case SIS_330:
1975 reg = SiS_GetReg(SISSR, 0x14);
1976 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
1977 if(reg & 0x0c) ivideo->video_size <<= 1;
1978 break;
1979 case SIS_550:
1980 case SIS_650:
1981 case SIS_740:
1982 reg = SiS_GetReg(SISSR, 0x14);
1983 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
1984 break;
1985 case SIS_661:
1986 case SIS_741:
1987 reg = SiS_GetReg(SISCR, 0x79);
1988 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
1989 break;
1990 case SIS_660:
1991 case SIS_760:
1992 case SIS_761:
1993 reg = SiS_GetReg(SISCR, 0x79);
1994 reg = (reg & 0xf0) >> 4;
1995 if(reg) {
1996 ivideo->video_size = (1 << reg) << 20;
1997 ivideo->UMAsize = ivideo->video_size;
1998 }
1999 reg = SiS_GetReg(SISCR, 0x78);
2000 reg &= 0x30;
2001 if(reg) {
2002 if(reg == 0x10) {
2003 ivideo->LFBsize = (32 << 20);
2004 } else {
2005 ivideo->LFBsize = (64 << 20);
2006 }
2007 ivideo->video_size += ivideo->LFBsize;
2008 }
2009 break;
2010 case SIS_340:
2011 case XGI_20:
2012 case XGI_40:
2013 reg = SiS_GetReg(SISSR, 0x14);
2014 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2015 if(ivideo->chip != XGI_20) {
2016 reg = (reg & 0x0c) >> 2;
2017 if(ivideo->revision_id == 2) {
2018 if(reg & 0x01) reg = 0x02;
2019 else reg = 0x00;
2020 }
2021 if(reg == 0x02) ivideo->video_size <<= 1;
2022 else if(reg == 0x03) ivideo->video_size <<= 2;
2023 }
2024 break;
2025#endif
2026 default:
2027 return -1;
2028 }
2029 return 0;
2030}
2031
2032/* -------------- video bridge device detection --------------- */
2033
2034static void sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2035{
2036 u8 cr32, temp;
2037
2038 /* No CRT2 on XGI Z7 */
2039 if(ivideo->chip == XGI_20) {
2040 ivideo->sisfb_crt1off = 0;
2041 return;
2042 }
2043
2044#ifdef CONFIG_FB_SIS_300
2045 if(ivideo->sisvga_engine == SIS_300_VGA) {
2046 temp = SiS_GetReg(SISSR, 0x17);
2047 if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
2048 /* PAL/NTSC is stored on SR16 on such machines */
2049 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
2050 temp = SiS_GetReg(SISSR, 0x16);
2051 if(temp & 0x20)
2052 ivideo->vbflags |= TV_PAL;
2053 else
2054 ivideo->vbflags |= TV_NTSC;
2055 }
2056 }
2057 }
2058#endif
2059
2060 cr32 = SiS_GetReg(SISCR, 0x32);
2061
2062 if(cr32 & SIS_CRT1) {
2063 ivideo->sisfb_crt1off = 0;
2064 } else {
2065 ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0;
2066 }
2067
2068 ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
2069
2070 if(cr32 & SIS_VB_TV) ivideo->vbflags |= CRT2_TV;
2071 if(cr32 & SIS_VB_LCD) ivideo->vbflags |= CRT2_LCD;
2072 if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA;
2073
2074 /* Check given parms for hardware compatibility.
2075 * (Cannot do this in the search_xx routines since we don't
2076 * know what hardware we are running on then)
2077 */
2078
2079 if(ivideo->chip != SIS_550) {
2080 ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0;
2081 }
2082
2083 if(ivideo->sisfb_tvplug != -1) {
2084 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2085 (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) {
2086 if(ivideo->sisfb_tvplug & TV_YPBPR) {
2087 ivideo->sisfb_tvplug = -1;
2088 printk(KERN_ERR "sisfb: YPbPr not supported\n");
2089 }
2090 }
2091 }
2092 if(ivideo->sisfb_tvplug != -1) {
2093 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2094 (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) {
2095 if(ivideo->sisfb_tvplug & TV_HIVISION) {
2096 ivideo->sisfb_tvplug = -1;
2097 printk(KERN_ERR "sisfb: HiVision not supported\n");
2098 }
2099 }
2100 }
2101 if(ivideo->sisfb_tvstd != -1) {
2102 if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) &&
2103 (!((ivideo->sisvga_engine == SIS_315_VGA) &&
2104 (ivideo->vbflags2 & VB2_CHRONTEL))) ) {
2105 if(ivideo->sisfb_tvstd & (TV_PALM | TV_PALN | TV_NTSCJ)) {
2106 ivideo->sisfb_tvstd = -1;
2107 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
2108 }
2109 }
2110 }
2111
2112 /* Detect/set TV plug & type */
2113 if(ivideo->sisfb_tvplug != -1) {
2114 ivideo->vbflags |= ivideo->sisfb_tvplug;
2115 } else {
2116 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
2117 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION;
2118 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART;
2119 else {
2120 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO;
2121 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
2122 }
2123 }
2124
2125 if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) {
2126 if(ivideo->sisfb_tvstd != -1) {
2127 ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ);
2128 ivideo->vbflags |= ivideo->sisfb_tvstd;
2129 }
2130 if(ivideo->vbflags & TV_SCART) {
2131 ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ);
2132 ivideo->vbflags |= TV_PAL;
2133 }
2134 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
2135 if(ivideo->sisvga_engine == SIS_300_VGA) {
2136 temp = SiS_GetReg(SISSR, 0x38);
2137 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2138 else ivideo->vbflags |= TV_NTSC;
2139 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
2140 temp = SiS_GetReg(SISSR, 0x38);
2141 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2142 else ivideo->vbflags |= TV_NTSC;
2143 } else {
2144 temp = SiS_GetReg(SISCR, 0x79);
2145 if(temp & 0x20) ivideo->vbflags |= TV_PAL;
2146 else ivideo->vbflags |= TV_NTSC;
2147 }
2148 }
2149 }
2150
2151 /* Copy forceCRT1 option to CRT1off if option is given */
2152 if(ivideo->sisfb_forcecrt1 != -1) {
2153 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
2154 }
2155}
2156
2157/* ------------------ Sensing routines ------------------ */
2158
2159static bool sisfb_test_DDC1(struct sis_video_info *ivideo)
2160{
2161 unsigned short old;
2162 int count = 48;
2163
2164 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
2165 do {
2166 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
2167 } while(count--);
2168 return (count != -1);
2169}
2170
2171static void sisfb_sense_crt1(struct sis_video_info *ivideo)
2172{
2173 bool mustwait = false;
2174 u8 sr1F, cr17;
2175#ifdef CONFIG_FB_SIS_315
2176 u8 cr63=0;
2177#endif
2178 u16 temp = 0xffff;
2179 int i;
2180
2181 sr1F = SiS_GetReg(SISSR, 0x1F);
2182 SiS_SetRegOR(SISSR, 0x1F, 0x04);
2183 SiS_SetRegAND(SISSR, 0x1F, 0x3F);
2184 if(sr1F & 0xc0) mustwait = true;
2185
2186#ifdef CONFIG_FB_SIS_315
2187 if(ivideo->sisvga_engine == SIS_315_VGA) {
2188 cr63 = SiS_GetReg(SISCR, ivideo->SiS_Pr.SiS_MyCR63);
2189 cr63 &= 0x40;
2190 SiS_SetRegAND(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF);
2191 }
2192#endif
2193
2194 cr17 = SiS_GetReg(SISCR, 0x17);
2195 cr17 &= 0x80;
2196 if(!cr17) {
2197 SiS_SetRegOR(SISCR, 0x17, 0x80);
2198 mustwait = true;
2199 SiS_SetReg(SISSR, 0x00, 0x01);
2200 SiS_SetReg(SISSR, 0x00, 0x03);
2201 }
2202
2203 if(mustwait) {
2204 for(i=0; i < 10; i++) sisfbwaitretracecrt1(ivideo);
2205 }
2206
2207#ifdef CONFIG_FB_SIS_315
2208 if(ivideo->chip >= SIS_330) {
2209 SiS_SetRegAND(SISCR, 0x32, ~0x20);
2210 if(ivideo->chip >= SIS_340) {
2211 SiS_SetReg(SISCR, 0x57, 0x4a);
2212 } else {
2213 SiS_SetReg(SISCR, 0x57, 0x5f);
2214 }
2215 SiS_SetRegOR(SISCR, 0x53, 0x02);
2216 while ((SiS_GetRegByte(SISINPSTAT)) & 0x01) break;
2217 while (!((SiS_GetRegByte(SISINPSTAT)) & 0x01)) break;
2218 if ((SiS_GetRegByte(SISMISCW)) & 0x10) temp = 1;
2219 SiS_SetRegAND(SISCR, 0x53, 0xfd);
2220 SiS_SetRegAND(SISCR, 0x57, 0x00);
2221 }
2222#endif
2223
2224 if(temp == 0xffff) {
2225 i = 3;
2226 do {
2227 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
2228 ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2);
2229 } while(((temp == 0) || (temp == 0xffff)) && i--);
2230
2231 if((temp == 0) || (temp == 0xffff)) {
2232 if(sisfb_test_DDC1(ivideo)) temp = 1;
2233 }
2234 }
2235
2236 if((temp) && (temp != 0xffff)) {
2237 SiS_SetRegOR(SISCR, 0x32, 0x20);
2238 }
2239
2240#ifdef CONFIG_FB_SIS_315
2241 if(ivideo->sisvga_engine == SIS_315_VGA) {
2242 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF, cr63);
2243 }
2244#endif
2245
2246 SiS_SetRegANDOR(SISCR, 0x17, 0x7F, cr17);
2247
2248 SiS_SetReg(SISSR, 0x1F, sr1F);
2249}
2250
2251/* Determine and detect attached devices on SiS30x */
2252static void SiS_SenseLCD(struct sis_video_info *ivideo)
2253{
2254 unsigned char buffer[256];
2255 unsigned short temp, realcrtno, i;
2256 u8 reg, cr37 = 0, paneltype = 0;
2257 u16 xres, yres;
2258
2259 ivideo->SiS_Pr.PanelSelfDetected = false;
2260
2261 /* LCD detection only for TMDS bridges */
2262 if(!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE))
2263 return;
2264 if(ivideo->vbflags2 & VB2_30xBDH)
2265 return;
2266
2267 /* If LCD already set up by BIOS, skip it */
2268 reg = SiS_GetReg(SISCR, 0x32);
2269 if(reg & 0x08)
2270 return;
2271
2272 realcrtno = 1;
2273 if(ivideo->SiS_Pr.DDCPortMixup)
2274 realcrtno = 0;
2275
2276 /* Check DDC capabilities */
2277 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
2278 realcrtno, 0, &buffer[0], ivideo->vbflags2);
2279
2280 if((!temp) || (temp == 0xffff) || (!(temp & 0x02)))
2281 return;
2282
2283 /* Read DDC data */
2284 i = 3; /* Number of retrys */
2285 do {
2286 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
2287 ivideo->sisvga_engine, realcrtno, 1,
2288 &buffer[0], ivideo->vbflags2);
2289 } while((temp) && i--);
2290
2291 if(temp)
2292 return;
2293
2294 /* No digital device */
2295 if(!(buffer[0x14] & 0x80))
2296 return;
2297
2298 /* First detailed timing preferred timing? */
2299 if(!(buffer[0x18] & 0x02))
2300 return;
2301
2302 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
2303 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
2304
2305 switch(xres) {
2306 case 1024:
2307 if(yres == 768)
2308 paneltype = 0x02;
2309 break;
2310 case 1280:
2311 if(yres == 1024)
2312 paneltype = 0x03;
2313 break;
2314 case 1600:
2315 if((yres == 1200) && (ivideo->vbflags2 & VB2_30xC))
2316 paneltype = 0x0b;
2317 break;
2318 }
2319
2320 if(!paneltype)
2321 return;
2322
2323 if(buffer[0x23])
2324 cr37 |= 0x10;
2325
2326 if((buffer[0x47] & 0x18) == 0x18)
2327 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
2328 else
2329 cr37 |= 0xc0;
2330
2331 SiS_SetReg(SISCR, 0x36, paneltype);
2332 cr37 &= 0xf1;
2333 SiS_SetRegANDOR(SISCR, 0x37, 0x0c, cr37);
2334 SiS_SetRegOR(SISCR, 0x32, 0x08);
2335
2336 ivideo->SiS_Pr.PanelSelfDetected = true;
2337}
2338
2339static int SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
2340{
2341 int temp, mytest, result, i, j;
2342
2343 for(j = 0; j < 10; j++) {
2344 result = 0;
2345 for(i = 0; i < 3; i++) {
2346 mytest = test;
2347 SiS_SetReg(SISPART4, 0x11, (type & 0x00ff));
2348 temp = (type >> 8) | (mytest & 0x00ff);
2349 SiS_SetRegANDOR(SISPART4, 0x10, 0xe0, temp);
2350 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500);
2351 mytest >>= 8;
2352 mytest &= 0x7f;
2353 temp = SiS_GetReg(SISPART4, 0x03);
2354 temp ^= 0x0e;
2355 temp &= mytest;
2356 if(temp == mytest) result++;
2357#if 1
2358 SiS_SetReg(SISPART4, 0x11, 0x00);
2359 SiS_SetRegAND(SISPART4, 0x10, 0xe0);
2360 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000);
2361#endif
2362 }
2363 if((result == 0) || (result >= 2)) break;
2364 }
2365 return result;
2366}
2367
2368static void SiS_Sense30x(struct sis_video_info *ivideo)
2369{
2370 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
2371 u16 svhs=0, svhs_c=0;
2372 u16 cvbs=0, cvbs_c=0;
2373 u16 vga2=0, vga2_c=0;
2374 int myflag, result;
2375 char stdstr[] = "sisfb: Detected";
2376 char tvstr[] = "TV connected to";
2377
2378 if(ivideo->vbflags2 & VB2_301) {
2379 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
2380 myflag = SiS_GetReg(SISPART4, 0x01);
2381 if(myflag & 0x04) {
2382 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
2383 }
2384 } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) {
2385 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
2386 } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) {
2387 svhs = 0x0200; cvbs = 0x0100;
2388 } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) {
2389 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
2390 } else
2391 return;
2392
2393 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
2394 if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) {
2395 svhs_c = 0x0408; cvbs_c = 0x0808;
2396 }
2397
2398 biosflag = 2;
2399 if(ivideo->haveXGIROM) {
2400 biosflag = ivideo->bios_abase[0x58] & 0x03;
2401 } else if(ivideo->newrom) {
2402 if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01;
2403 } else if(ivideo->sisvga_engine == SIS_300_VGA) {
2404 if(ivideo->bios_abase) {
2405 biosflag = ivideo->bios_abase[0xfe] & 0x03;
2406 }
2407 }
2408
2409 if(ivideo->chip == SIS_300) {
2410 myflag = SiS_GetReg(SISSR, 0x3b);
2411 if(!(myflag & 0x01)) vga2 = vga2_c = 0;
2412 }
2413
2414 if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) {
2415 vga2 = vga2_c = 0;
2416 }
2417
2418 backupSR_1e = SiS_GetReg(SISSR, 0x1e);
2419 SiS_SetRegOR(SISSR, 0x1e, 0x20);
2420
2421 backupP4_0d = SiS_GetReg(SISPART4, 0x0d);
2422 if(ivideo->vbflags2 & VB2_30xC) {
2423 SiS_SetRegANDOR(SISPART4, 0x0d, ~0x07, 0x01);
2424 } else {
2425 SiS_SetRegOR(SISPART4, 0x0d, 0x04);
2426 }
2427 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
2428
2429 backupP2_00 = SiS_GetReg(SISPART2, 0x00);
2430 SiS_SetReg(SISPART2, 0x00, ((backupP2_00 | 0x1c) & 0xfc));
2431
2432 backupP2_4d = SiS_GetReg(SISPART2, 0x4d);
2433 if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) {
2434 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d & ~0x10));
2435 }
2436
2437 if(!(ivideo->vbflags2 & VB2_30xCLV)) {
2438 SISDoSense(ivideo, 0, 0);
2439 }
2440
2441 SiS_SetRegAND(SISCR, 0x32, ~0x14);
2442
2443 if(vga2_c || vga2) {
2444 if(SISDoSense(ivideo, vga2, vga2_c)) {
2445 if(biosflag & 0x01) {
2446 printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr);
2447 SiS_SetRegOR(SISCR, 0x32, 0x04);
2448 } else {
2449 printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
2450 SiS_SetRegOR(SISCR, 0x32, 0x10);
2451 }
2452 }
2453 }
2454
2455 SiS_SetRegAND(SISCR, 0x32, 0x3f);
2456
2457 if(ivideo->vbflags2 & VB2_30xCLV) {
2458 SiS_SetRegOR(SISPART4, 0x0d, 0x04);
2459 }
2460
2461 if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
2462 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d | 0x10));
2463 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
2464 if((result = SISDoSense(ivideo, svhs, 0x0604))) {
2465 if((result = SISDoSense(ivideo, cvbs, 0x0804))) {
2466 printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr);
2467 SiS_SetRegOR(SISCR, 0x32, 0x80);
2468 }
2469 }
2470 SiS_SetReg(SISPART2, 0x4d, backupP2_4d);
2471 }
2472
2473 SiS_SetRegAND(SISCR, 0x32, ~0x03);
2474
2475 if(!(ivideo->vbflags & TV_YPBPR)) {
2476 if((result = SISDoSense(ivideo, svhs, svhs_c))) {
2477 printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
2478 SiS_SetRegOR(SISCR, 0x32, 0x02);
2479 }
2480 if((biosflag & 0x02) || (!result)) {
2481 if(SISDoSense(ivideo, cvbs, cvbs_c)) {
2482 printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
2483 SiS_SetRegOR(SISCR, 0x32, 0x01);
2484 }
2485 }
2486 }
2487
2488 SISDoSense(ivideo, 0, 0);
2489
2490 SiS_SetReg(SISPART2, 0x00, backupP2_00);
2491 SiS_SetReg(SISPART4, 0x0d, backupP4_0d);
2492 SiS_SetReg(SISSR, 0x1e, backupSR_1e);
2493
2494 if(ivideo->vbflags2 & VB2_30xCLV) {
2495 biosflag = SiS_GetReg(SISPART2, 0x00);
2496 if(biosflag & 0x20) {
2497 for(myflag = 2; myflag > 0; myflag--) {
2498 biosflag ^= 0x20;
2499 SiS_SetReg(SISPART2, 0x00, biosflag);
2500 }
2501 }
2502 }
2503
2504 SiS_SetReg(SISPART2, 0x00, backupP2_00);
2505}
2506
2507/* Determine and detect attached TV's on Chrontel */
2508static void SiS_SenseCh(struct sis_video_info *ivideo)
2509{
2510#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2511 u8 temp1, temp2;
2512 char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
2513#endif
2514#ifdef CONFIG_FB_SIS_300
2515 unsigned char test[3];
2516 int i;
2517#endif
2518
2519 if(ivideo->chip < SIS_315H) {
2520
2521#ifdef CONFIG_FB_SIS_300
2522 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */
2523 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */
2524 SiS_DDC2Delay(&ivideo->SiS_Pr, 1000);
2525 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
2526 /* See Chrontel TB31 for explanation */
2527 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2528 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
2529 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b);
2530 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2531 }
2532 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
2533 if(temp2 != temp1) temp1 = temp2;
2534
2535 if((temp1 >= 0x22) && (temp1 <= 0x50)) {
2536 /* Read power status */
2537 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2538 if((temp1 & 0x03) != 0x03) {
2539 /* Power all outputs */
2540 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b);
2541 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2542 }
2543 /* Sense connected TV devices */
2544 for(i = 0; i < 3; i++) {
2545 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01);
2546 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2547 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00);
2548 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2549 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
2550 if(!(temp1 & 0x08)) test[i] = 0x02;
2551 else if(!(temp1 & 0x02)) test[i] = 0x01;
2552 else test[i] = 0;
2553 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2554 }
2555
2556 if(test[0] == test[1]) temp1 = test[0];
2557 else if(test[0] == test[2]) temp1 = test[0];
2558 else if(test[1] == test[2]) temp1 = test[1];
2559 else {
2560 printk(KERN_INFO
2561 "sisfb: TV detection unreliable - test results varied\n");
2562 temp1 = test[2];
2563 }
2564 if(temp1 == 0x02) {
2565 printk(KERN_INFO "%s SVIDEO output\n", stdstr);
2566 ivideo->vbflags |= TV_SVIDEO;
2567 SiS_SetRegOR(SISCR, 0x32, 0x02);
2568 SiS_SetRegAND(SISCR, 0x32, ~0x05);
2569 } else if (temp1 == 0x01) {
2570 printk(KERN_INFO "%s CVBS output\n", stdstr);
2571 ivideo->vbflags |= TV_AVIDEO;
2572 SiS_SetRegOR(SISCR, 0x32, 0x01);
2573 SiS_SetRegAND(SISCR, 0x32, ~0x06);
2574 } else {
2575 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
2576 SiS_SetRegAND(SISCR, 0x32, ~0x07);
2577 }
2578 } else if(temp1 == 0) {
2579 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
2580 SiS_SetRegAND(SISCR, 0x32, ~0x07);
2581 }
2582 /* Set general purpose IO for Chrontel communication */
2583 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00);
2584#endif
2585
2586 } else {
2587
2588#ifdef CONFIG_FB_SIS_315
2589 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
2590 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
2591 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20);
2592 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2593 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2594 temp2 |= 0x01;
2595 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
2596 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2597 temp2 ^= 0x01;
2598 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
2599 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2600 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2601 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1);
2602 temp1 = 0;
2603 if(temp2 & 0x02) temp1 |= 0x01;
2604 if(temp2 & 0x10) temp1 |= 0x01;
2605 if(temp2 & 0x04) temp1 |= 0x02;
2606 if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
2607 switch(temp1) {
2608 case 0x01:
2609 printk(KERN_INFO "%s CVBS output\n", stdstr);
2610 ivideo->vbflags |= TV_AVIDEO;
2611 SiS_SetRegOR(SISCR, 0x32, 0x01);
2612 SiS_SetRegAND(SISCR, 0x32, ~0x06);
2613 break;
2614 case 0x02:
2615 printk(KERN_INFO "%s SVIDEO output\n", stdstr);
2616 ivideo->vbflags |= TV_SVIDEO;
2617 SiS_SetRegOR(SISCR, 0x32, 0x02);
2618 SiS_SetRegAND(SISCR, 0x32, ~0x05);
2619 break;
2620 case 0x04:
2621 printk(KERN_INFO "%s SCART output\n", stdstr);
2622 SiS_SetRegOR(SISCR, 0x32, 0x04);
2623 SiS_SetRegAND(SISCR, 0x32, ~0x03);
2624 break;
2625 default:
2626 SiS_SetRegAND(SISCR, 0x32, ~0x07);
2627 }
2628#endif
2629 }
2630}
2631
2632static void sisfb_get_VB_type(struct sis_video_info *ivideo)
2633{
2634 char stdstr[] = "sisfb: Detected";
2635 char bridgestr[] = "video bridge";
2636 u8 vb_chipid;
2637 u8 reg;
2638
2639 /* No CRT2 on XGI Z7 */
2640 if(ivideo->chip == XGI_20)
2641 return;
2642
2643 vb_chipid = SiS_GetReg(SISPART4, 0x00);
2644 switch(vb_chipid) {
2645 case 0x01:
2646 reg = SiS_GetReg(SISPART4, 0x01);
2647 if(reg < 0xb0) {
2648 ivideo->vbflags |= VB_301; /* Deprecated */
2649 ivideo->vbflags2 |= VB2_301;
2650 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
2651 } else if(reg < 0xc0) {
2652 ivideo->vbflags |= VB_301B; /* Deprecated */
2653 ivideo->vbflags2 |= VB2_301B;
2654 reg = SiS_GetReg(SISPART4, 0x23);
2655 if(!(reg & 0x02)) {
2656 ivideo->vbflags |= VB_30xBDH; /* Deprecated */
2657 ivideo->vbflags2 |= VB2_30xBDH;
2658 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
2659 } else {
2660 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
2661 }
2662 } else if(reg < 0xd0) {
2663 ivideo->vbflags |= VB_301C; /* Deprecated */
2664 ivideo->vbflags2 |= VB2_301C;
2665 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
2666 } else if(reg < 0xe0) {
2667 ivideo->vbflags |= VB_301LV; /* Deprecated */
2668 ivideo->vbflags2 |= VB2_301LV;
2669 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
2670 } else if(reg <= 0xe1) {
2671 reg = SiS_GetReg(SISPART4, 0x39);
2672 if(reg == 0xff) {
2673 ivideo->vbflags |= VB_302LV; /* Deprecated */
2674 ivideo->vbflags2 |= VB2_302LV;
2675 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
2676 } else {
2677 ivideo->vbflags |= VB_301C; /* Deprecated */
2678 ivideo->vbflags2 |= VB2_301C;
2679 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
2680#if 0
2681 ivideo->vbflags |= VB_302ELV; /* Deprecated */
2682 ivideo->vbflags2 |= VB2_302ELV;
2683 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
2684#endif
2685 }
2686 }
2687 break;
2688 case 0x02:
2689 ivideo->vbflags |= VB_302B; /* Deprecated */
2690 ivideo->vbflags2 |= VB2_302B;
2691 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
2692 break;
2693 }
2694
2695 if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
2696 reg = SiS_GetReg(SISCR, 0x37);
2697 reg &= SIS_EXTERNAL_CHIP_MASK;
2698 reg >>= 1;
2699 if(ivideo->sisvga_engine == SIS_300_VGA) {
2700#ifdef CONFIG_FB_SIS_300
2701 switch(reg) {
2702 case SIS_EXTERNAL_CHIP_LVDS:
2703 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2704 ivideo->vbflags2 |= VB2_LVDS;
2705 break;
2706 case SIS_EXTERNAL_CHIP_TRUMPION:
2707 ivideo->vbflags |= (VB_LVDS | VB_TRUMPION); /* Deprecated */
2708 ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION);
2709 break;
2710 case SIS_EXTERNAL_CHIP_CHRONTEL:
2711 ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */
2712 ivideo->vbflags2 |= VB2_CHRONTEL;
2713 break;
2714 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
2715 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2716 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2717 break;
2718 }
2719 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1;
2720#endif
2721 } else if(ivideo->chip < SIS_661) {
2722#ifdef CONFIG_FB_SIS_315
2723 switch (reg) {
2724 case SIS310_EXTERNAL_CHIP_LVDS:
2725 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2726 ivideo->vbflags2 |= VB2_LVDS;
2727 break;
2728 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
2729 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2730 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2731 break;
2732 }
2733 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
2734#endif
2735 } else if(ivideo->chip >= SIS_661) {
2736#ifdef CONFIG_FB_SIS_315
2737 reg = SiS_GetReg(SISCR, 0x38);
2738 reg >>= 5;
2739 switch(reg) {
2740 case 0x02:
2741 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2742 ivideo->vbflags2 |= VB2_LVDS;
2743 break;
2744 case 0x03:
2745 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2746 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2747 break;
2748 case 0x04:
2749 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT); /* Deprecated */
2750 ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT);
2751 break;
2752 }
2753 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
2754#endif
2755 }
2756 if(ivideo->vbflags2 & VB2_LVDS) {
2757 printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
2758 }
2759 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) {
2760 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
2761 }
2762 if(ivideo->vbflags2 & VB2_CHRONTEL) {
2763 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
2764 }
2765 if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) {
2766 printk(KERN_INFO "%s Conexant external device\n", stdstr);
2767 }
2768 }
2769
2770 if(ivideo->vbflags2 & VB2_SISBRIDGE) {
2771 SiS_SenseLCD(ivideo);
2772 SiS_Sense30x(ivideo);
2773 } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
2774 SiS_SenseCh(ivideo);
2775 }
2776}
2777
2778/* ---------- Engine initialization routines ------------ */
2779
2780static void
2781sisfb_engine_init(struct sis_video_info *ivideo)
2782{
2783
2784 /* Initialize command queue (we use MMIO only) */
2785
2786 /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */
2787
2788 ivideo->caps &= ~(TURBO_QUEUE_CAP |
2789 MMIO_CMD_QUEUE_CAP |
2790 VM_CMD_QUEUE_CAP |
2791 AGP_CMD_QUEUE_CAP);
2792
2793#ifdef CONFIG_FB_SIS_300
2794 if(ivideo->sisvga_engine == SIS_300_VGA) {
2795 u32 tqueue_pos;
2796 u8 tq_state;
2797
2798 tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024);
2799
2800 tq_state = SiS_GetReg(SISSR, IND_SIS_TURBOQUEUE_SET);
2801 tq_state |= 0xf0;
2802 tq_state &= 0xfc;
2803 tq_state |= (u8)(tqueue_pos >> 8);
2804 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
2805
2806 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
2807
2808 ivideo->caps |= TURBO_QUEUE_CAP;
2809 }
2810#endif
2811
2812#ifdef CONFIG_FB_SIS_315
2813 if(ivideo->sisvga_engine == SIS_315_VGA) {
2814 u32 tempq = 0, templ;
2815 u8 temp;
2816
2817 if(ivideo->chip == XGI_20) {
2818 switch(ivideo->cmdQueueSize) {
2819 case (64 * 1024):
2820 temp = SIS_CMD_QUEUE_SIZE_Z7_64k;
2821 break;
2822 case (128 * 1024):
2823 default:
2824 temp = SIS_CMD_QUEUE_SIZE_Z7_128k;
2825 }
2826 } else {
2827 switch(ivideo->cmdQueueSize) {
2828 case (4 * 1024 * 1024):
2829 temp = SIS_CMD_QUEUE_SIZE_4M;
2830 break;
2831 case (2 * 1024 * 1024):
2832 temp = SIS_CMD_QUEUE_SIZE_2M;
2833 break;
2834 case (1 * 1024 * 1024):
2835 temp = SIS_CMD_QUEUE_SIZE_1M;
2836 break;
2837 default:
2838 case (512 * 1024):
2839 temp = SIS_CMD_QUEUE_SIZE_512k;
2840 }
2841 }
2842
2843 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2844 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
2845
2846 if((ivideo->chip >= XGI_40) && ivideo->modechanged) {
2847 /* Must disable dual pipe on XGI_40. Can't do
2848 * this in MMIO mode, because it requires
2849 * setting/clearing a bit in the MMIO fire trigger
2850 * register.
2851 */
2852 if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) {
2853
2854 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0);
2855
2856 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE));
2857
2858 tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR);
2859 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq);
2860
2861 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
2862 MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq);
2863
2864 writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq);
2865 writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4);
2866 writel(0x168F0000, ivideo->video_vbase + tempq + 8);
2867 writel(0x168F0000, ivideo->video_vbase + tempq + 12);
2868
2869 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16));
2870
2871 sisfb_syncaccel(ivideo);
2872
2873 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
2874
2875 }
2876 }
2877
2878 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
2879 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
2880
2881 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
2882 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, temp);
2883
2884 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
2885 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
2886
2887 ivideo->caps |= MMIO_CMD_QUEUE_CAP;
2888 }
2889#endif
2890
2891 ivideo->engineok = 1;
2892}
2893
2894static void sisfb_detect_lcd_type(struct sis_video_info *ivideo)
2895{
2896 u8 reg;
2897 int i;
2898
2899 reg = SiS_GetReg(SISCR, 0x36);
2900 reg &= 0x0f;
2901 if(ivideo->sisvga_engine == SIS_300_VGA) {
2902 ivideo->CRT2LCDType = sis300paneltype[reg];
2903 } else if(ivideo->chip >= SIS_661) {
2904 ivideo->CRT2LCDType = sis661paneltype[reg];
2905 } else {
2906 ivideo->CRT2LCDType = sis310paneltype[reg];
2907 if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
2908 if((ivideo->CRT2LCDType != LCD_320x240_2) &&
2909 (ivideo->CRT2LCDType != LCD_320x240_3)) {
2910 ivideo->CRT2LCDType = LCD_320x240;
2911 }
2912 }
2913 }
2914
2915 if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
2916 /* For broken BIOSes: Assume 1024x768, RGB18 */
2917 ivideo->CRT2LCDType = LCD_1024x768;
2918 SiS_SetRegANDOR(SISCR, 0x36, 0xf0, 0x02);
2919 SiS_SetRegANDOR(SISCR, 0x37, 0xee, 0x01);
2920 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
2921 }
2922
2923 for(i = 0; i < SIS_LCD_NUMBER; i++) {
2924 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
2925 ivideo->lcdxres = sis_lcd_data[i].xres;
2926 ivideo->lcdyres = sis_lcd_data[i].yres;
2927 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
2928 break;
2929 }
2930 }
2931
2932#ifdef CONFIG_FB_SIS_300
2933 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
2934 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024;
2935 ivideo->lcddefmodeidx = DEFAULT_MODE_1360;
2936 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
2937 ivideo->lcdxres = 848; ivideo->lcdyres = 480;
2938 ivideo->lcddefmodeidx = DEFAULT_MODE_848;
2939 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) {
2940 ivideo->lcdxres = 856; ivideo->lcdyres = 480;
2941 ivideo->lcddefmodeidx = DEFAULT_MODE_856;
2942 }
2943#endif
2944
2945 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
2946 ivideo->lcdxres, ivideo->lcdyres);
2947}
2948
2949static void sisfb_save_pdc_emi(struct sis_video_info *ivideo)
2950{
2951#ifdef CONFIG_FB_SIS_300
2952 /* Save the current PanelDelayCompensation if the LCD is currently used */
2953 if(ivideo->sisvga_engine == SIS_300_VGA) {
2954 if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) {
2955 int tmp;
2956 tmp = SiS_GetReg(SISCR, 0x30);
2957 if(tmp & 0x20) {
2958 /* Currently on LCD? If yes, read current pdc */
2959 ivideo->detectedpdc = SiS_GetReg(SISPART1, 0x13);
2960 ivideo->detectedpdc &= 0x3c;
2961 if(ivideo->SiS_Pr.PDC == -1) {
2962 /* Let option override detection */
2963 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
2964 }
2965 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
2966 ivideo->detectedpdc);
2967 }
2968 if((ivideo->SiS_Pr.PDC != -1) &&
2969 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
2970 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
2971 ivideo->SiS_Pr.PDC);
2972 }
2973 }
2974 }
2975#endif
2976
2977#ifdef CONFIG_FB_SIS_315
2978 if(ivideo->sisvga_engine == SIS_315_VGA) {
2979
2980 /* Try to find about LCDA */
2981 if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) {
2982 int tmp;
2983 tmp = SiS_GetReg(SISPART1, 0x13);
2984 if(tmp & 0x04) {
2985 ivideo->SiS_Pr.SiS_UseLCDA = true;
2986 ivideo->detectedlcda = 0x03;
2987 }
2988 }
2989
2990 /* Save PDC */
2991 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
2992 int tmp;
2993 tmp = SiS_GetReg(SISCR, 0x30);
2994 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
2995 /* Currently on LCD? If yes, read current pdc */
2996 u8 pdc;
2997 pdc = SiS_GetReg(SISPART1, 0x2D);
2998 ivideo->detectedpdc = (pdc & 0x0f) << 1;
2999 ivideo->detectedpdca = (pdc & 0xf0) >> 3;
3000 pdc = SiS_GetReg(SISPART1, 0x35);
3001 ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
3002 pdc = SiS_GetReg(SISPART1, 0x20);
3003 ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
3004 if(ivideo->newrom) {
3005 /* New ROM invalidates other PDC resp. */
3006 if(ivideo->detectedlcda != 0xff) {
3007 ivideo->detectedpdc = 0xff;
3008 } else {
3009 ivideo->detectedpdca = 0xff;
3010 }
3011 }
3012 if(ivideo->SiS_Pr.PDC == -1) {
3013 if(ivideo->detectedpdc != 0xff) {
3014 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
3015 }
3016 }
3017 if(ivideo->SiS_Pr.PDCA == -1) {
3018 if(ivideo->detectedpdca != 0xff) {
3019 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
3020 }
3021 }
3022 if(ivideo->detectedpdc != 0xff) {
3023 printk(KERN_INFO
3024 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
3025 ivideo->detectedpdc);
3026 }
3027 if(ivideo->detectedpdca != 0xff) {
3028 printk(KERN_INFO
3029 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
3030 ivideo->detectedpdca);
3031 }
3032 }
3033
3034 /* Save EMI */
3035 if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) {
3036 ivideo->SiS_Pr.EMI_30 = SiS_GetReg(SISPART4, 0x30);
3037 ivideo->SiS_Pr.EMI_31 = SiS_GetReg(SISPART4, 0x31);
3038 ivideo->SiS_Pr.EMI_32 = SiS_GetReg(SISPART4, 0x32);
3039 ivideo->SiS_Pr.EMI_33 = SiS_GetReg(SISPART4, 0x33);
3040 ivideo->SiS_Pr.HaveEMI = true;
3041 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
3042 ivideo->SiS_Pr.HaveEMILCD = true;
3043 }
3044 }
3045 }
3046
3047 /* Let user override detected PDCs (all bridges) */
3048 if(ivideo->vbflags2 & VB2_30xBLV) {
3049 if((ivideo->SiS_Pr.PDC != -1) &&
3050 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
3051 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
3052 ivideo->SiS_Pr.PDC);
3053 }
3054 if((ivideo->SiS_Pr.PDCA != -1) &&
3055 (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
3056 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
3057 ivideo->SiS_Pr.PDCA);
3058 }
3059 }
3060
3061 }
3062#endif
3063}
3064
3065/* -------------------- Memory manager routines ---------------------- */
3066
3067static u32 sisfb_getheapstart(struct sis_video_info *ivideo)
3068{
3069 u32 ret = ivideo->sisfb_parm_mem * 1024;
3070 u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
3071 u32 def;
3072
3073 /* Calculate heap start = end of memory for console
3074 *
3075 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
3076 * C = console, D = heap, H = HWCursor, Q = cmd-queue
3077 *
3078 * On 76x in UMA+LFB mode, the layout is as follows:
3079 * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ
3080 * where the heap is the entire UMA area, eventually
3081 * into the LFB area if the given mem parameter is
3082 * higher than the size of the UMA memory.
3083 *
3084 * Basically given by "mem" parameter
3085 *
3086 * maximum = videosize - cmd_queue - hwcursor
3087 * (results in a heap of size 0)
3088 * default = SiS 300: depends on videosize
3089 * SiS 315/330/340/XGI: 32k below max
3090 */
3091
3092 if(ivideo->sisvga_engine == SIS_300_VGA) {
3093 if(ivideo->video_size > 0x1000000) {
3094 def = 0xc00000;
3095 } else if(ivideo->video_size > 0x800000) {
3096 def = 0x800000;
3097 } else {
3098 def = 0x400000;
3099 }
3100 } else if(ivideo->UMAsize && ivideo->LFBsize) {
3101 ret = def = 0;
3102 } else {
3103 def = maxoffs - 0x8000;
3104 }
3105
3106 /* Use default for secondary card for now (FIXME) */
3107 if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0))
3108 ret = def;
3109
3110 return ret;
3111}
3112
3113static u32 sisfb_getheapsize(struct sis_video_info *ivideo)
3114{
3115 u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
3116 u32 ret = 0;
3117
3118 if(ivideo->UMAsize && ivideo->LFBsize) {
3119 if( (!ivideo->sisfb_parm_mem) ||
3120 ((ivideo->sisfb_parm_mem * 1024) > max) ||
3121 ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) {
3122 ret = ivideo->UMAsize;
3123 max -= ivideo->UMAsize;
3124 } else {
3125 ret = max - (ivideo->sisfb_parm_mem * 1024);
3126 max = ivideo->sisfb_parm_mem * 1024;
3127 }
3128 ivideo->video_offset = ret;
3129 ivideo->sisfb_mem = max;
3130 } else {
3131 ret = max - ivideo->heapstart;
3132 ivideo->sisfb_mem = ivideo->heapstart;
3133 }
3134
3135 return ret;
3136}
3137
3138static int sisfb_heap_init(struct sis_video_info *ivideo)
3139{
3140 struct SIS_OH *poh;
3141
3142 ivideo->video_offset = 0;
3143 if(ivideo->sisfb_parm_mem) {
3144 if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) ||
3145 (ivideo->sisfb_parm_mem > ivideo->video_size) ) {
3146 ivideo->sisfb_parm_mem = 0;
3147 }
3148 }
3149
3150 ivideo->heapstart = sisfb_getheapstart(ivideo);
3151 ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo);
3152
3153 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
3154 ivideo->sisfb_heap_end = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size;
3155
3156 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
3157 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
3158
3159 ivideo->sisfb_heap.vinfo = ivideo;
3160
3161 ivideo->sisfb_heap.poha_chain = NULL;
3162 ivideo->sisfb_heap.poh_freelist = NULL;
3163
3164 poh = sisfb_poh_new_node(&ivideo->sisfb_heap);
3165 if(poh == NULL)
3166 return 1;
3167
3168 poh->poh_next = &ivideo->sisfb_heap.oh_free;
3169 poh->poh_prev = &ivideo->sisfb_heap.oh_free;
3170 poh->size = ivideo->sisfb_heap_size;
3171 poh->offset = ivideo->heapstart;
3172
3173 ivideo->sisfb_heap.oh_free.poh_next = poh;
3174 ivideo->sisfb_heap.oh_free.poh_prev = poh;
3175 ivideo->sisfb_heap.oh_free.size = 0;
3176 ivideo->sisfb_heap.max_freesize = poh->size;
3177
3178 ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used;
3179 ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used;
3180 ivideo->sisfb_heap.oh_used.size = SENTINEL;
3181
3182 if(ivideo->cardnumber == 0) {
3183 /* For the first card, make this heap the "global" one
3184 * for old DRM (which could handle only one card)
3185 */
3186 sisfb_heap = &ivideo->sisfb_heap;
3187 }
3188
3189 return 0;
3190}
3191
3192static struct SIS_OH *
3193sisfb_poh_new_node(struct SIS_HEAP *memheap)
3194{
3195 struct SIS_OHALLOC *poha;
3196 struct SIS_OH *poh;
3197 unsigned long cOhs;
3198 int i;
3199
3200 if(memheap->poh_freelist == NULL) {
3201 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
3202 if(!poha)
3203 return NULL;
3204
3205 poha->poha_next = memheap->poha_chain;
3206 memheap->poha_chain = poha;
3207
3208 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1;
3209
3210 poh = &poha->aoh[0];
3211 for(i = cOhs - 1; i != 0; i--) {
3212 poh->poh_next = poh + 1;
3213 poh = poh + 1;
3214 }
3215
3216 poh->poh_next = NULL;
3217 memheap->poh_freelist = &poha->aoh[0];
3218 }
3219
3220 poh = memheap->poh_freelist;
3221 memheap->poh_freelist = poh->poh_next;
3222
3223 return poh;
3224}
3225
3226static struct SIS_OH *
3227sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size)
3228{
3229 struct SIS_OH *pohThis;
3230 struct SIS_OH *pohRoot;
3231 int bAllocated = 0;
3232
3233 if(size > memheap->max_freesize) {
3234 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3235 (unsigned int) size / 1024);
3236 return NULL;
3237 }
3238
3239 pohThis = memheap->oh_free.poh_next;
3240
3241 while(pohThis != &memheap->oh_free) {
3242 if(size <= pohThis->size) {
3243 bAllocated = 1;
3244 break;
3245 }
3246 pohThis = pohThis->poh_next;
3247 }
3248
3249 if(!bAllocated) {
3250 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3251 (unsigned int) size / 1024);
3252 return NULL;
3253 }
3254
3255 if(size == pohThis->size) {
3256 pohRoot = pohThis;
3257 sisfb_delete_node(pohThis);
3258 } else {
3259 pohRoot = sisfb_poh_new_node(memheap);
3260 if(pohRoot == NULL)
3261 return NULL;
3262
3263 pohRoot->offset = pohThis->offset;
3264 pohRoot->size = size;
3265
3266 pohThis->offset += size;
3267 pohThis->size -= size;
3268 }
3269
3270 memheap->max_freesize -= size;
3271
3272 pohThis = &memheap->oh_used;
3273 sisfb_insert_node(pohThis, pohRoot);
3274
3275 return pohRoot;
3276}
3277
3278static void
3279sisfb_delete_node(struct SIS_OH *poh)
3280{
3281 poh->poh_prev->poh_next = poh->poh_next;
3282 poh->poh_next->poh_prev = poh->poh_prev;
3283}
3284
3285static void
3286sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh)
3287{
3288 struct SIS_OH *pohTemp = pohList->poh_next;
3289
3290 pohList->poh_next = poh;
3291 pohTemp->poh_prev = poh;
3292
3293 poh->poh_prev = pohList;
3294 poh->poh_next = pohTemp;
3295}
3296
3297static struct SIS_OH *
3298sisfb_poh_free(struct SIS_HEAP *memheap, u32 base)
3299{
3300 struct SIS_OH *pohThis;
3301 struct SIS_OH *poh_freed;
3302 struct SIS_OH *poh_prev;
3303 struct SIS_OH *poh_next;
3304 u32 ulUpper;
3305 u32 ulLower;
3306 int foundNode = 0;
3307
3308 poh_freed = memheap->oh_used.poh_next;
3309
3310 while(poh_freed != &memheap->oh_used) {
3311 if(poh_freed->offset == base) {
3312 foundNode = 1;
3313 break;
3314 }
3315
3316 poh_freed = poh_freed->poh_next;
3317 }
3318
3319 if(!foundNode)
3320 return NULL;
3321
3322 memheap->max_freesize += poh_freed->size;
3323
3324 poh_prev = poh_next = NULL;
3325 ulUpper = poh_freed->offset + poh_freed->size;
3326 ulLower = poh_freed->offset;
3327
3328 pohThis = memheap->oh_free.poh_next;
3329
3330 while(pohThis != &memheap->oh_free) {
3331 if(pohThis->offset == ulUpper) {
3332 poh_next = pohThis;
3333 } else if((pohThis->offset + pohThis->size) == ulLower) {
3334 poh_prev = pohThis;
3335 }
3336 pohThis = pohThis->poh_next;
3337 }
3338
3339 sisfb_delete_node(poh_freed);
3340
3341 if(poh_prev && poh_next) {
3342 poh_prev->size += (poh_freed->size + poh_next->size);
3343 sisfb_delete_node(poh_next);
3344 sisfb_free_node(memheap, poh_freed);
3345 sisfb_free_node(memheap, poh_next);
3346 return poh_prev;
3347 }
3348
3349 if(poh_prev) {
3350 poh_prev->size += poh_freed->size;
3351 sisfb_free_node(memheap, poh_freed);
3352 return poh_prev;
3353 }
3354
3355 if(poh_next) {
3356 poh_next->size += poh_freed->size;
3357 poh_next->offset = poh_freed->offset;
3358 sisfb_free_node(memheap, poh_freed);
3359 return poh_next;
3360 }
3361
3362 sisfb_insert_node(&memheap->oh_free, poh_freed);
3363
3364 return poh_freed;
3365}
3366
3367static void
3368sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh)
3369{
3370 if(poh == NULL)
3371 return;
3372
3373 poh->poh_next = memheap->poh_freelist;
3374 memheap->poh_freelist = poh;
3375}
3376
3377static void
3378sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req)
3379{
3380 struct SIS_OH *poh = NULL;
3381
3382 if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap))
3383 poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size);
3384
3385 if(poh == NULL) {
3386 req->offset = req->size = 0;
3387 DPRINTK("sisfb: Video RAM allocation failed\n");
3388 } else {
3389 req->offset = poh->offset;
3390 req->size = poh->size;
3391 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
3392 (poh->offset + ivideo->video_vbase));
3393 }
3394}
3395
3396void
3397sis_malloc(struct sis_memreq *req)
3398{
3399 struct sis_video_info *ivideo = sisfb_heap->vinfo;
3400
3401 if(&ivideo->sisfb_heap == sisfb_heap)
3402 sis_int_malloc(ivideo, req);
3403 else
3404 req->offset = req->size = 0;
3405}
3406
3407void
3408sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req)
3409{
3410 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3411
3412 sis_int_malloc(ivideo, req);
3413}
3414
3415/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
3416
3417static void
3418sis_int_free(struct sis_video_info *ivideo, u32 base)
3419{
3420 struct SIS_OH *poh;
3421
3422 if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap))
3423 return;
3424
3425 poh = sisfb_poh_free(&ivideo->sisfb_heap, base);
3426
3427 if(poh == NULL) {
3428 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
3429 (unsigned int) base);
3430 }
3431}
3432
3433void
3434sis_free(u32 base)
3435{
3436 struct sis_video_info *ivideo = sisfb_heap->vinfo;
3437
3438 sis_int_free(ivideo, base);
3439}
3440
3441void
3442sis_free_new(struct pci_dev *pdev, u32 base)
3443{
3444 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3445
3446 sis_int_free(ivideo, base);
3447}
3448
3449/* --------------------- SetMode routines ------------------------- */
3450
3451static void
3452sisfb_check_engine_and_sync(struct sis_video_info *ivideo)
3453{
3454 u8 cr30, cr31;
3455
3456 /* Check if MMIO and engines are enabled,
3457 * and sync in case they are. Can't use
3458 * ivideo->accel here, as this might have
3459 * been changed before this is called.
3460 */
3461 cr30 = SiS_GetReg(SISSR, IND_SIS_PCI_ADDRESS_SET);
3462 cr31 = SiS_GetReg(SISSR, IND_SIS_MODULE_ENABLE);
3463 /* MMIO and 2D/3D engine enabled? */
3464 if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) {
3465#ifdef CONFIG_FB_SIS_300
3466 if(ivideo->sisvga_engine == SIS_300_VGA) {
3467 /* Don't care about TurboQueue. It's
3468 * enough to know that the engines
3469 * are enabled
3470 */
3471 sisfb_syncaccel(ivideo);
3472 }
3473#endif
3474#ifdef CONFIG_FB_SIS_315
3475 if(ivideo->sisvga_engine == SIS_315_VGA) {
3476 /* Check that any queue mode is
3477 * enabled, and that the queue
3478 * is not in the state of "reset"
3479 */
3480 cr30 = SiS_GetReg(SISSR, 0x26);
3481 if((cr30 & 0xe0) && (!(cr30 & 0x01))) {
3482 sisfb_syncaccel(ivideo);
3483 }
3484 }
3485#endif
3486 }
3487}
3488
3489static void
3490sisfb_pre_setmode(struct sis_video_info *ivideo)
3491{
3492 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
3493 int tvregnum = 0;
3494
3495 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
3496
3497 SiS_SetReg(SISSR, 0x05, 0x86);
3498
3499 cr31 = SiS_GetReg(SISCR, 0x31);
3500 cr31 &= ~0x60;
3501 cr31 |= 0x04;
3502
3503 cr33 = ivideo->rate_idx & 0x0F;
3504
3505#ifdef CONFIG_FB_SIS_315
3506 if(ivideo->sisvga_engine == SIS_315_VGA) {
3507 if(ivideo->chip >= SIS_661) {
3508 cr38 = SiS_GetReg(SISCR, 0x38);
3509 cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */
3510 } else {
3511 tvregnum = 0x38;
3512 cr38 = SiS_GetReg(SISCR, tvregnum);
3513 cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */
3514 }
3515 }
3516#endif
3517#ifdef CONFIG_FB_SIS_300
3518 if(ivideo->sisvga_engine == SIS_300_VGA) {
3519 tvregnum = 0x35;
3520 cr38 = SiS_GetReg(SISCR, tvregnum);
3521 }
3522#endif
3523
3524 SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
3525 SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
3526 ivideo->curFSTN = ivideo->curDSTN = 0;
3527
3528 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
3529
3530 case CRT2_TV:
3531 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */
3532 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
3533#ifdef CONFIG_FB_SIS_315
3534 if(ivideo->chip >= SIS_661) {
3535 cr38 |= 0x04;
3536 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
3537 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40;
3538 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
3539 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3540 cr35 &= ~0x01;
3541 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3542 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
3543 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
3544 cr38 |= 0x08;
3545 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
3546 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20;
3547 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
3548 cr31 &= ~0x01;
3549 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3550 }
3551#endif
3552 } else if((ivideo->vbflags & TV_HIVISION) &&
3553 (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) {
3554 if(ivideo->chip >= SIS_661) {
3555 cr38 |= 0x04;
3556 cr35 |= 0x60;
3557 } else {
3558 cr30 |= 0x80;
3559 }
3560 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3561 cr31 |= 0x01;
3562 cr35 |= 0x01;
3563 ivideo->currentvbflags |= TV_HIVISION;
3564 } else if(ivideo->vbflags & TV_SCART) {
3565 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
3566 cr31 |= 0x01;
3567 cr35 |= 0x01;
3568 ivideo->currentvbflags |= TV_SCART;
3569 } else {
3570 if(ivideo->vbflags & TV_SVIDEO) {
3571 cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
3572 ivideo->currentvbflags |= TV_SVIDEO;
3573 }
3574 if(ivideo->vbflags & TV_AVIDEO) {
3575 cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
3576 ivideo->currentvbflags |= TV_AVIDEO;
3577 }
3578 }
3579 cr31 |= SIS_DRIVER_MODE;
3580
3581 if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) {
3582 if(ivideo->vbflags & TV_PAL) {
3583 cr31 |= 0x01; cr35 |= 0x01;
3584 ivideo->currentvbflags |= TV_PAL;
3585 if(ivideo->vbflags & TV_PALM) {
3586 cr38 |= 0x40; cr35 |= 0x04;
3587 ivideo->currentvbflags |= TV_PALM;
3588 } else if(ivideo->vbflags & TV_PALN) {
3589 cr38 |= 0x80; cr35 |= 0x08;
3590 ivideo->currentvbflags |= TV_PALN;
3591 }
3592 } else {
3593 cr31 &= ~0x01; cr35 &= ~0x01;
3594 ivideo->currentvbflags |= TV_NTSC;
3595 if(ivideo->vbflags & TV_NTSCJ) {
3596 cr38 |= 0x40; cr35 |= 0x02;
3597 ivideo->currentvbflags |= TV_NTSCJ;
3598 }
3599 }
3600 }
3601 break;
3602
3603 case CRT2_LCD:
3604 cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
3605 cr31 |= SIS_DRIVER_MODE;
3606 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
3607 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
3608 ivideo->curFSTN = ivideo->sisfb_fstn;
3609 ivideo->curDSTN = ivideo->sisfb_dstn;
3610 break;
3611
3612 case CRT2_VGA:
3613 cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
3614 cr31 |= SIS_DRIVER_MODE;
3615 if(ivideo->sisfb_nocrt2rate) {
3616 cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4);
3617 } else {
3618 cr33 |= ((ivideo->rate_idx & 0x0F) << 4);
3619 }
3620 break;
3621
3622 default: /* disable CRT2 */
3623 cr30 = 0x00;
3624 cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
3625 }
3626
3627 SiS_SetReg(SISCR, 0x30, cr30);
3628 SiS_SetReg(SISCR, 0x33, cr33);
3629
3630 if(ivideo->chip >= SIS_661) {
3631#ifdef CONFIG_FB_SIS_315
3632 cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */
3633 SiS_SetRegANDOR(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */
3634 cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */
3635 SiS_SetRegANDOR(SISCR, 0x38, 0xf8, cr38);
3636#endif
3637 } else if(ivideo->chip != SIS_300) {
3638 SiS_SetReg(SISCR, tvregnum, cr38);
3639 }
3640 SiS_SetReg(SISCR, 0x31, cr31);
3641
3642 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
3643
3644 sisfb_check_engine_and_sync(ivideo);
3645}
3646
3647/* Fix SR11 for 661 and later */
3648#ifdef CONFIG_FB_SIS_315
3649static void
3650sisfb_fixup_SR11(struct sis_video_info *ivideo)
3651{
3652 u8 tmpreg;
3653
3654 if(ivideo->chip >= SIS_661) {
3655 tmpreg = SiS_GetReg(SISSR, 0x11);
3656 if(tmpreg & 0x20) {
3657 tmpreg = SiS_GetReg(SISSR, 0x3e);
3658 tmpreg = (tmpreg + 1) & 0xff;
3659 SiS_SetReg(SISSR, 0x3e, tmpreg);
3660 tmpreg = SiS_GetReg(SISSR, 0x11);
3661 }
3662 if(tmpreg & 0xf0) {
3663 SiS_SetRegAND(SISSR, 0x11, 0x0f);
3664 }
3665 }
3666}
3667#endif
3668
3669static void
3670sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
3671{
3672 if(val > 32) val = 32;
3673 if(val < -32) val = -32;
3674 ivideo->tvxpos = val;
3675
3676 if(ivideo->sisfblocked) return;
3677 if(!ivideo->modechanged) return;
3678
3679 if(ivideo->currentvbflags & CRT2_TV) {
3680
3681 if(ivideo->vbflags2 & VB2_CHRONTEL) {
3682
3683 int x = ivideo->tvx;
3684
3685 switch(ivideo->chronteltype) {
3686 case 1:
3687 x += val;
3688 if(x < 0) x = 0;
3689 SiS_SetReg(SISSR, 0x05, 0x86);
3690 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff));
3691 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD);
3692 break;
3693 case 2:
3694 /* Not supported by hardware */
3695 break;
3696 }
3697
3698 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3699
3700 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
3701 unsigned short temp;
3702
3703 p2_1f = ivideo->p2_1f;
3704 p2_20 = ivideo->p2_20;
3705 p2_2b = ivideo->p2_2b;
3706 p2_42 = ivideo->p2_42;
3707 p2_43 = ivideo->p2_43;
3708
3709 temp = p2_1f | ((p2_20 & 0xf0) << 4);
3710 temp += (val * 2);
3711 p2_1f = temp & 0xff;
3712 p2_20 = (temp & 0xf00) >> 4;
3713 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
3714 temp = p2_43 | ((p2_42 & 0xf0) << 4);
3715 temp += (val * 2);
3716 p2_43 = temp & 0xff;
3717 p2_42 = (temp & 0xf00) >> 4;
3718 SiS_SetReg(SISPART2, 0x1f, p2_1f);
3719 SiS_SetRegANDOR(SISPART2, 0x20, 0x0F, p2_20);
3720 SiS_SetRegANDOR(SISPART2, 0x2b, 0xF0, p2_2b);
3721 SiS_SetRegANDOR(SISPART2, 0x42, 0x0F, p2_42);
3722 SiS_SetReg(SISPART2, 0x43, p2_43);
3723 }
3724 }
3725}
3726
3727static void
3728sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
3729{
3730 if(val > 32) val = 32;
3731 if(val < -32) val = -32;
3732 ivideo->tvypos = val;
3733
3734 if(ivideo->sisfblocked) return;
3735 if(!ivideo->modechanged) return;
3736
3737 if(ivideo->currentvbflags & CRT2_TV) {
3738
3739 if(ivideo->vbflags2 & VB2_CHRONTEL) {
3740
3741 int y = ivideo->tvy;
3742
3743 switch(ivideo->chronteltype) {
3744 case 1:
3745 y -= val;
3746 if(y < 0) y = 0;
3747 SiS_SetReg(SISSR, 0x05, 0x86);
3748 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff));
3749 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE);
3750 break;
3751 case 2:
3752 /* Not supported by hardware */
3753 break;
3754 }
3755
3756 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3757
3758 char p2_01, p2_02;
3759 val /= 2;
3760 p2_01 = ivideo->p2_01;
3761 p2_02 = ivideo->p2_02;
3762
3763 p2_01 += val;
3764 p2_02 += val;
3765 if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) {
3766 while((p2_01 <= 0) || (p2_02 <= 0)) {
3767 p2_01 += 2;
3768 p2_02 += 2;
3769 }
3770 }
3771 SiS_SetReg(SISPART2, 0x01, p2_01);
3772 SiS_SetReg(SISPART2, 0x02, p2_02);
3773 }
3774 }
3775}
3776
3777static void
3778sisfb_post_setmode(struct sis_video_info *ivideo)
3779{
3780 bool crt1isoff = false;
3781 bool doit = true;
3782#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
3783 u8 reg;
3784#endif
3785#ifdef CONFIG_FB_SIS_315
3786 u8 reg1;
3787#endif
3788
3789 SiS_SetReg(SISSR, 0x05, 0x86);
3790
3791#ifdef CONFIG_FB_SIS_315
3792 sisfb_fixup_SR11(ivideo);
3793#endif
3794
3795 /* Now we actually HAVE changed the display mode */
3796 ivideo->modechanged = 1;
3797
3798 /* We can't switch off CRT1 if bridge is in slave mode */
3799 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
3800 if(sisfb_bridgeisslave(ivideo)) doit = false;
3801 } else
3802 ivideo->sisfb_crt1off = 0;
3803
3804#ifdef CONFIG_FB_SIS_300
3805 if(ivideo->sisvga_engine == SIS_300_VGA) {
3806 if((ivideo->sisfb_crt1off) && (doit)) {
3807 crt1isoff = true;
3808 reg = 0x00;
3809 } else {
3810 crt1isoff = false;
3811 reg = 0x80;
3812 }
3813 SiS_SetRegANDOR(SISCR, 0x17, 0x7f, reg);
3814 }
3815#endif
3816#ifdef CONFIG_FB_SIS_315
3817 if(ivideo->sisvga_engine == SIS_315_VGA) {
3818 if((ivideo->sisfb_crt1off) && (doit)) {
3819 crt1isoff = true;
3820 reg = 0x40;
3821 reg1 = 0xc0;
3822 } else {
3823 crt1isoff = false;
3824 reg = 0x00;
3825 reg1 = 0x00;
3826 }
3827 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
3828 SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, reg1);
3829 }
3830#endif
3831
3832 if(crt1isoff) {
3833 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
3834 ivideo->currentvbflags |= VB_SINGLE_MODE;
3835 } else {
3836 ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
3837 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
3838 ivideo->currentvbflags |= VB_MIRROR_MODE;
3839 } else {
3840 ivideo->currentvbflags |= VB_SINGLE_MODE;
3841 }
3842 }
3843
3844 SiS_SetRegAND(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
3845
3846 if(ivideo->currentvbflags & CRT2_TV) {
3847 if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3848 ivideo->p2_1f = SiS_GetReg(SISPART2, 0x1f);
3849 ivideo->p2_20 = SiS_GetReg(SISPART2, 0x20);
3850 ivideo->p2_2b = SiS_GetReg(SISPART2, 0x2b);
3851 ivideo->p2_42 = SiS_GetReg(SISPART2, 0x42);
3852 ivideo->p2_43 = SiS_GetReg(SISPART2, 0x43);
3853 ivideo->p2_01 = SiS_GetReg(SISPART2, 0x01);
3854 ivideo->p2_02 = SiS_GetReg(SISPART2, 0x02);
3855 } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
3856 if(ivideo->chronteltype == 1) {
3857 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
3858 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
3859 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
3860 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
3861 }
3862 }
3863 }
3864
3865 if(ivideo->tvxpos) {
3866 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
3867 }
3868 if(ivideo->tvypos) {
3869 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
3870 }
3871
3872 /* Eventually sync engines */
3873 sisfb_check_engine_and_sync(ivideo);
3874
3875 /* (Re-)Initialize chip engines */
3876 if(ivideo->accel) {
3877 sisfb_engine_init(ivideo);
3878 } else {
3879 ivideo->engineok = 0;
3880 }
3881}
3882
3883static int
3884sisfb_reset_mode(struct sis_video_info *ivideo)
3885{
3886 if(sisfb_set_mode(ivideo, 0))
3887 return 1;
3888
3889 sisfb_set_pitch(ivideo);
3890 sisfb_set_base_CRT1(ivideo, ivideo->current_base);
3891 sisfb_set_base_CRT2(ivideo, ivideo->current_base);
3892
3893 return 0;
3894}
3895
3896static void
3897sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command)
3898{
3899 int mycrt1off;
3900
3901 switch(sisfb_command->sisfb_cmd) {
3902 case SISFB_CMD_GETVBFLAGS:
3903 if(!ivideo->modechanged) {
3904 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
3905 } else {
3906 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3907 sisfb_command->sisfb_result[1] = ivideo->currentvbflags;
3908 sisfb_command->sisfb_result[2] = ivideo->vbflags2;
3909 }
3910 break;
3911 case SISFB_CMD_SWITCHCRT1:
3912 /* arg[0]: 0 = off, 1 = on, 99 = query */
3913 if(!ivideo->modechanged) {
3914 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
3915 } else if(sisfb_command->sisfb_arg[0] == 99) {
3916 /* Query */
3917 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
3918 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3919 } else if(ivideo->sisfblocked) {
3920 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED;
3921 } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) &&
3922 (sisfb_command->sisfb_arg[0] == 0)) {
3923 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2;
3924 } else {
3925 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3926 mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1;
3927 if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) ||
3928 ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) {
3929 ivideo->sisfb_crt1off = mycrt1off;
3930 if(sisfb_reset_mode(ivideo)) {
3931 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER;
3932 }
3933 }
3934 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
3935 }
3936 break;
3937 /* more to come */
3938 default:
3939 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN;
3940 printk(KERN_ERR "sisfb: Unknown command 0x%x\n",
3941 sisfb_command->sisfb_cmd);
3942 }
3943}
3944
3945#ifndef MODULE
3946static int __init sisfb_setup(char *options)
3947{
3948 char *this_opt;
3949
3950 sisfb_setdefaultparms();
3951
3952 if(!options || !(*options))
3953 return 0;
3954
3955 while((this_opt = strsep(&options, ",")) != NULL) {
3956
3957 if(!(*this_opt)) continue;
3958
3959 if(!strnicmp(this_opt, "off", 3)) {
3960 sisfb_off = 1;
3961 } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) {
3962 /* Need to check crt2 type first for fstn/dstn */
3963 sisfb_search_crt2type(this_opt + 14);
3964 } else if(!strnicmp(this_opt, "tvmode:",7)) {
3965 sisfb_search_tvstd(this_opt + 7);
3966 } else if(!strnicmp(this_opt, "tvstandard:",11)) {
3967 sisfb_search_tvstd(this_opt + 11);
3968 } else if(!strnicmp(this_opt, "mode:", 5)) {
3969 sisfb_search_mode(this_opt + 5, false);
3970 } else if(!strnicmp(this_opt, "vesa:", 5)) {
3971 sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false);
3972 } else if(!strnicmp(this_opt, "rate:", 5)) {
3973 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
3974 } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
3975 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
3976 } else if(!strnicmp(this_opt, "mem:",4)) {
3977 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
3978 } else if(!strnicmp(this_opt, "pdc:", 4)) {
3979 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
3980 } else if(!strnicmp(this_opt, "pdc1:", 5)) {
3981 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
3982 } else if(!strnicmp(this_opt, "noaccel", 7)) {
3983 sisfb_accel = 0;
3984 } else if(!strnicmp(this_opt, "accel", 5)) {
3985 sisfb_accel = -1;
3986 } else if(!strnicmp(this_opt, "noypan", 6)) {
3987 sisfb_ypan = 0;
3988 } else if(!strnicmp(this_opt, "ypan", 4)) {
3989 sisfb_ypan = -1;
3990 } else if(!strnicmp(this_opt, "nomax", 5)) {
3991 sisfb_max = 0;
3992 } else if(!strnicmp(this_opt, "max", 3)) {
3993 sisfb_max = -1;
3994 } else if(!strnicmp(this_opt, "userom:", 7)) {
3995 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
3996 } else if(!strnicmp(this_opt, "useoem:", 7)) {
3997 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
3998 } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
3999 sisfb_nocrt2rate = 1;
4000 } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
4001 unsigned long temp = 2;
4002 temp = simple_strtoul(this_opt + 9, NULL, 0);
4003 if((temp == 0) || (temp == 1)) {
4004 sisfb_scalelcd = temp ^ 1;
4005 }
4006 } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
4007 int temp = 0;
4008 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
4009 if((temp >= -32) && (temp <= 32)) {
4010 sisfb_tvxposoffset = temp;
4011 }
4012 } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
4013 int temp = 0;
4014 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
4015 if((temp >= -32) && (temp <= 32)) {
4016 sisfb_tvyposoffset = temp;
4017 }
4018 } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
4019 sisfb_search_specialtiming(this_opt + 14);
4020 } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
4021 int temp = 4;
4022 temp = simple_strtoul(this_opt + 7, NULL, 0);
4023 if((temp >= 0) && (temp <= 3)) {
4024 sisfb_lvdshl = temp;
4025 }
4026 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
4027 sisfb_search_mode(this_opt, true);
4028#if !defined(__i386__) && !defined(__x86_64__)
4029 } else if(!strnicmp(this_opt, "resetcard", 9)) {
4030 sisfb_resetcard = 1;
4031 } else if(!strnicmp(this_opt, "videoram:", 9)) {
4032 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
4033#endif
4034 } else {
4035 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
4036 }
4037
4038 }
4039
4040 return 0;
4041}
4042#endif
4043
4044static int sisfb_check_rom(void __iomem *rom_base,
4045 struct sis_video_info *ivideo)
4046{
4047 void __iomem *rom;
4048 int romptr;
4049
4050 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa))
4051 return 0;
4052
4053 romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
4054 if(romptr > (0x10000 - 8))
4055 return 0;
4056
4057 rom = rom_base + romptr;
4058
4059 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
4060 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R'))
4061 return 0;
4062
4063 if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor)
4064 return 0;
4065
4066 if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id)
4067 return 0;
4068
4069 return 1;
4070}
4071
4072static unsigned char *sisfb_find_rom(struct pci_dev *pdev)
4073{
4074 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4075 void __iomem *rom_base;
4076 unsigned char *myrombase = NULL;
4077 size_t romsize;
4078
4079 /* First, try the official pci ROM functions (except
4080 * on integrated chipsets which have no ROM).
4081 */
4082
4083 if(!ivideo->nbridge) {
4084
4085 if((rom_base = pci_map_rom(pdev, &romsize))) {
4086
4087 if(sisfb_check_rom(rom_base, ivideo)) {
4088
4089 if((myrombase = vmalloc(65536))) {
4090 memcpy_fromio(myrombase, rom_base,
4091 (romsize > 65536) ? 65536 : romsize);
4092 }
4093 }
4094 pci_unmap_rom(pdev, rom_base);
4095 }
4096 }
4097
4098 if(myrombase) return myrombase;
4099
4100 /* Otherwise do it the conventional way. */
4101
4102#if defined(__i386__) || defined(__x86_64__)
4103 {
4104 u32 temp;
4105
4106 for (temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
4107
4108 rom_base = ioremap(temp, 65536);
4109 if (!rom_base)
4110 continue;
4111
4112 if (!sisfb_check_rom(rom_base, ivideo)) {
4113 iounmap(rom_base);
4114 continue;
4115 }
4116
4117 if ((myrombase = vmalloc(65536)))
4118 memcpy_fromio(myrombase, rom_base, 65536);
4119
4120 iounmap(rom_base);
4121 break;
4122
4123 }
4124
4125 }
4126#endif
4127
4128 return myrombase;
4129}
4130
4131static void sisfb_post_map_vram(struct sis_video_info *ivideo,
4132 unsigned int *mapsize, unsigned int min)
4133{
4134 if (*mapsize < (min << 20))
4135 return;
4136
4137 ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize));
4138
4139 if(!ivideo->video_vbase) {
4140 printk(KERN_ERR
4141 "sisfb: Unable to map maximum video RAM for size detection\n");
4142 (*mapsize) >>= 1;
4143 while((!(ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize))))) {
4144 (*mapsize) >>= 1;
4145 if((*mapsize) < (min << 20))
4146 break;
4147 }
4148 if(ivideo->video_vbase) {
4149 printk(KERN_ERR
4150 "sisfb: Video RAM size detection limited to %dMB\n",
4151 (int)((*mapsize) >> 20));
4152 }
4153 }
4154}
4155
4156#ifdef CONFIG_FB_SIS_300
4157static int sisfb_post_300_buswidth(struct sis_video_info *ivideo)
4158{
4159 void __iomem *FBAddress = ivideo->video_vbase;
4160 unsigned short temp;
4161 unsigned char reg;
4162 int i, j;
4163
4164 SiS_SetRegAND(SISSR, 0x15, 0xFB);
4165 SiS_SetRegOR(SISSR, 0x15, 0x04);
4166 SiS_SetReg(SISSR, 0x13, 0x00);
4167 SiS_SetReg(SISSR, 0x14, 0xBF);
4168
4169 for(i = 0; i < 2; i++) {
4170 temp = 0x1234;
4171 for(j = 0; j < 4; j++) {
4172 writew(temp, FBAddress);
4173 if(readw(FBAddress) == temp)
4174 break;
4175 SiS_SetRegOR(SISSR, 0x3c, 0x01);
4176 reg = SiS_GetReg(SISSR, 0x05);
4177 reg = SiS_GetReg(SISSR, 0x05);
4178 SiS_SetRegAND(SISSR, 0x3c, 0xfe);
4179 reg = SiS_GetReg(SISSR, 0x05);
4180 reg = SiS_GetReg(SISSR, 0x05);
4181 temp++;
4182 }
4183 }
4184
4185 writel(0x01234567L, FBAddress);
4186 writel(0x456789ABL, (FBAddress + 4));
4187 writel(0x89ABCDEFL, (FBAddress + 8));
4188 writel(0xCDEF0123L, (FBAddress + 12));
4189
4190 reg = SiS_GetReg(SISSR, 0x3b);
4191 if(reg & 0x01) {
4192 if(readl((FBAddress + 12)) == 0xCDEF0123L)
4193 return 4; /* Channel A 128bit */
4194 }
4195
4196 if(readl((FBAddress + 4)) == 0x456789ABL)
4197 return 2; /* Channel B 64bit */
4198
4199 return 1; /* 32bit */
4200}
4201
4202static const unsigned short SiS_DRAMType[17][5] = {
4203 {0x0C,0x0A,0x02,0x40,0x39},
4204 {0x0D,0x0A,0x01,0x40,0x48},
4205 {0x0C,0x09,0x02,0x20,0x35},
4206 {0x0D,0x09,0x01,0x20,0x44},
4207 {0x0C,0x08,0x02,0x10,0x31},
4208 {0x0D,0x08,0x01,0x10,0x40},
4209 {0x0C,0x0A,0x01,0x20,0x34},
4210 {0x0C,0x09,0x01,0x08,0x32},
4211 {0x0B,0x08,0x02,0x08,0x21},
4212 {0x0C,0x08,0x01,0x08,0x30},
4213 {0x0A,0x08,0x02,0x04,0x11},
4214 {0x0B,0x0A,0x01,0x10,0x28},
4215 {0x09,0x08,0x02,0x02,0x01},
4216 {0x0B,0x09,0x01,0x08,0x24},
4217 {0x0B,0x08,0x01,0x04,0x20},
4218 {0x0A,0x08,0x01,0x02,0x10},
4219 {0x09,0x08,0x01,0x01,0x00}
4220};
4221
4222static int sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration,
4223 int buswidth, int PseudoRankCapacity,
4224 int PseudoAdrPinCount, unsigned int mapsize)
4225{
4226 void __iomem *FBAddr = ivideo->video_vbase;
4227 unsigned short sr14;
4228 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
4229 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
4230
4231 for(k = 0; k < ARRAY_SIZE(SiS_DRAMType); k++) {
4232
4233 RankCapacity = buswidth * SiS_DRAMType[k][3];
4234
4235 if(RankCapacity != PseudoRankCapacity)
4236 continue;
4237
4238 if((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount)
4239 continue;
4240
4241 BankNumHigh = RankCapacity * 16 * iteration - 1;
4242 if(iteration == 3) { /* Rank No */
4243 BankNumMid = RankCapacity * 16 - 1;
4244 } else {
4245 BankNumMid = RankCapacity * 16 * iteration / 2 - 1;
4246 }
4247
4248 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
4249 PhysicalAdrHigh = BankNumHigh;
4250 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
4251 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
4252
4253 SiS_SetRegAND(SISSR, 0x15, 0xFB); /* Test */
4254 SiS_SetRegOR(SISSR, 0x15, 0x04); /* Test */
4255 sr14 = (SiS_DRAMType[k][3] * buswidth) - 1;
4256 if(buswidth == 4) sr14 |= 0x80;
4257 else if(buswidth == 2) sr14 |= 0x40;
4258 SiS_SetReg(SISSR, 0x13, SiS_DRAMType[k][4]);
4259 SiS_SetReg(SISSR, 0x14, sr14);
4260
4261 BankNumHigh <<= 16;
4262 BankNumMid <<= 16;
4263
4264 if((BankNumHigh + PhysicalAdrHigh >= mapsize) ||
4265 (BankNumMid + PhysicalAdrHigh >= mapsize) ||
4266 (BankNumHigh + PhysicalAdrHalfPage >= mapsize) ||
4267 (BankNumHigh + PhysicalAdrOtherPage >= mapsize))
4268 continue;
4269
4270 /* Write data */
4271 writew(((unsigned short)PhysicalAdrHigh),
4272 (FBAddr + BankNumHigh + PhysicalAdrHigh));
4273 writew(((unsigned short)BankNumMid),
4274 (FBAddr + BankNumMid + PhysicalAdrHigh));
4275 writew(((unsigned short)PhysicalAdrHalfPage),
4276 (FBAddr + BankNumHigh + PhysicalAdrHalfPage));
4277 writew(((unsigned short)PhysicalAdrOtherPage),
4278 (FBAddr + BankNumHigh + PhysicalAdrOtherPage));
4279
4280 /* Read data */
4281 if(readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh)
4282 return 1;
4283 }
4284
4285 return 0;
4286}
4287
4288static void sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
4289{
4290 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4291 int i, j, buswidth;
4292 int PseudoRankCapacity, PseudoAdrPinCount;
4293
4294 buswidth = sisfb_post_300_buswidth(ivideo);
4295
4296 for(i = 6; i >= 0; i--) {
4297 PseudoRankCapacity = 1 << i;
4298 for(j = 4; j >= 1; j--) {
4299 PseudoAdrPinCount = 15 - j;
4300 if((PseudoRankCapacity * j) <= 64) {
4301 if(sisfb_post_300_rwtest(ivideo,
4302 j,
4303 buswidth,
4304 PseudoRankCapacity,
4305 PseudoAdrPinCount,
4306 mapsize))
4307 return;
4308 }
4309 }
4310 }
4311}
4312
4313static void sisfb_post_sis300(struct pci_dev *pdev)
4314{
4315 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4316 unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
4317 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
4318 u16 index, rindex, memtype = 0;
4319 unsigned int mapsize;
4320
4321 if(!ivideo->SiS_Pr.UseROM)
4322 bios = NULL;
4323
4324 SiS_SetReg(SISSR, 0x05, 0x86);
4325
4326 if(bios) {
4327 if(bios[0x52] & 0x80) {
4328 memtype = bios[0x52];
4329 } else {
4330 memtype = SiS_GetReg(SISSR, 0x3a);
4331 }
4332 memtype &= 0x07;
4333 }
4334
4335 v3 = 0x80; v6 = 0x80;
4336 if(ivideo->revision_id <= 0x13) {
4337 v1 = 0x44; v2 = 0x42;
4338 v4 = 0x44; v5 = 0x42;
4339 } else {
4340 v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */
4341 v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */
4342 if(bios) {
4343 index = memtype * 5;
4344 rindex = index + 0x54;
4345 v1 = bios[rindex++];
4346 v2 = bios[rindex++];
4347 v3 = bios[rindex++];
4348 rindex = index + 0x7c;
4349 v4 = bios[rindex++];
4350 v5 = bios[rindex++];
4351 v6 = bios[rindex++];
4352 }
4353 }
4354 SiS_SetReg(SISSR, 0x28, v1);
4355 SiS_SetReg(SISSR, 0x29, v2);
4356 SiS_SetReg(SISSR, 0x2a, v3);
4357 SiS_SetReg(SISSR, 0x2e, v4);
4358 SiS_SetReg(SISSR, 0x2f, v5);
4359 SiS_SetReg(SISSR, 0x30, v6);
4360
4361 v1 = 0x10;
4362 if(bios)
4363 v1 = bios[0xa4];
4364 SiS_SetReg(SISSR, 0x07, v1); /* DAC speed */
4365
4366 SiS_SetReg(SISSR, 0x11, 0x0f); /* DDC, power save */
4367
4368 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
4369 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
4370 if(bios) {
4371 memtype += 0xa5;
4372 v1 = bios[memtype];
4373 v2 = bios[memtype + 8];
4374 v3 = bios[memtype + 16];
4375 v4 = bios[memtype + 24];
4376 v5 = bios[memtype + 32];
4377 v6 = bios[memtype + 40];
4378 v7 = bios[memtype + 48];
4379 v8 = bios[memtype + 56];
4380 }
4381 if(ivideo->revision_id >= 0x80)
4382 v3 &= 0xfd;
4383 SiS_SetReg(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
4384 SiS_SetReg(SISSR, 0x16, v2);
4385 SiS_SetReg(SISSR, 0x17, v3);
4386 SiS_SetReg(SISSR, 0x18, v4);
4387 SiS_SetReg(SISSR, 0x19, v5);
4388 SiS_SetReg(SISSR, 0x1a, v6);
4389 SiS_SetReg(SISSR, 0x1b, v7);
4390 SiS_SetReg(SISSR, 0x1c, v8); /* ---- */
4391 SiS_SetRegAND(SISSR, 0x15, 0xfb);
4392 SiS_SetRegOR(SISSR, 0x15, 0x04);
4393 if(bios) {
4394 if(bios[0x53] & 0x02) {
4395 SiS_SetRegOR(SISSR, 0x19, 0x20);
4396 }
4397 }
4398 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */
4399 if(ivideo->revision_id >= 0x80)
4400 v1 |= 0x01;
4401 SiS_SetReg(SISSR, 0x1f, v1);
4402 SiS_SetReg(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */
4403 v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
4404 if(bios) {
4405 v1 = bios[0xe8];
4406 v2 = bios[0xe9];
4407 v3 = bios[0xea];
4408 }
4409 SiS_SetReg(SISSR, 0x23, v1);
4410 SiS_SetReg(SISSR, 0x24, v2);
4411 SiS_SetReg(SISSR, 0x25, v3);
4412 SiS_SetReg(SISSR, 0x21, 0x84);
4413 SiS_SetReg(SISSR, 0x22, 0x00);
4414 SiS_SetReg(SISCR, 0x37, 0x00);
4415 SiS_SetRegOR(SISPART1, 0x24, 0x01); /* unlock crt2 */
4416 SiS_SetReg(SISPART1, 0x00, 0x00);
4417 v1 = 0x40; v2 = 0x11;
4418 if(bios) {
4419 v1 = bios[0xec];
4420 v2 = bios[0xeb];
4421 }
4422 SiS_SetReg(SISPART1, 0x02, v1);
4423
4424 if(ivideo->revision_id >= 0x80)
4425 v2 &= ~0x01;
4426
4427 reg = SiS_GetReg(SISPART4, 0x00);
4428 if((reg == 1) || (reg == 2)) {
4429 SiS_SetReg(SISCR, 0x37, 0x02);
4430 SiS_SetReg(SISPART2, 0x00, 0x1c);
4431 v4 = 0x00; v5 = 0x00; v6 = 0x10;
4432 if(ivideo->SiS_Pr.UseROM) {
4433 v4 = bios[0xf5];
4434 v5 = bios[0xf6];
4435 v6 = bios[0xf7];
4436 }
4437 SiS_SetReg(SISPART4, 0x0d, v4);
4438 SiS_SetReg(SISPART4, 0x0e, v5);
4439 SiS_SetReg(SISPART4, 0x10, v6);
4440 SiS_SetReg(SISPART4, 0x0f, 0x3f);
4441 reg = SiS_GetReg(SISPART4, 0x01);
4442 if(reg >= 0xb0) {
4443 reg = SiS_GetReg(SISPART4, 0x23);
4444 reg &= 0x20;
4445 reg <<= 1;
4446 SiS_SetReg(SISPART4, 0x23, reg);
4447 }
4448 } else {
4449 v2 &= ~0x10;
4450 }
4451 SiS_SetReg(SISSR, 0x32, v2);
4452
4453 SiS_SetRegAND(SISPART1, 0x24, 0xfe); /* Lock CRT2 */
4454
4455 reg = SiS_GetReg(SISSR, 0x16);
4456 reg &= 0xc3;
4457 SiS_SetReg(SISCR, 0x35, reg);
4458 SiS_SetReg(SISCR, 0x83, 0x00);
4459#if !defined(__i386__) && !defined(__x86_64__)
4460 if(sisfb_videoram) {
4461 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */
4462 reg = ((sisfb_videoram >> 10) - 1) | 0x40;
4463 SiS_SetReg(SISSR, 0x14, reg);
4464 } else {
4465#endif
4466 /* Need to map max FB size for finding out about RAM size */
4467 mapsize = ivideo->video_size;
4468 sisfb_post_map_vram(ivideo, &mapsize, 4);
4469
4470 if(ivideo->video_vbase) {
4471 sisfb_post_300_ramsize(pdev, mapsize);
4472 iounmap(ivideo->video_vbase);
4473 } else {
4474 printk(KERN_DEBUG
4475 "sisfb: Failed to map memory for size detection, assuming 8MB\n");
4476 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */
4477 SiS_SetReg(SISSR, 0x14, 0x47); /* 8MB, 64bit default */
4478 }
4479#if !defined(__i386__) && !defined(__x86_64__)
4480 }
4481#endif
4482 if(bios) {
4483 v1 = bios[0xe6];
4484 v2 = bios[0xe7];
4485 } else {
4486 reg = SiS_GetReg(SISSR, 0x3a);
4487 if((reg & 0x30) == 0x30) {
4488 v1 = 0x04; /* PCI */
4489 v2 = 0x92;
4490 } else {
4491 v1 = 0x14; /* AGP */
4492 v2 = 0xb2;
4493 }
4494 }
4495 SiS_SetReg(SISSR, 0x21, v1);
4496 SiS_SetReg(SISSR, 0x22, v2);
4497
4498 /* Sense CRT1 */
4499 sisfb_sense_crt1(ivideo);
4500
4501 /* Set default mode, don't clear screen */
4502 ivideo->SiS_Pr.SiS_UseOEM = false;
4503 SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
4504 SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
4505 ivideo->curFSTN = ivideo->curDSTN = 0;
4506 ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
4507 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
4508
4509 SiS_SetReg(SISSR, 0x05, 0x86);
4510
4511 /* Display off */
4512 SiS_SetRegOR(SISSR, 0x01, 0x20);
4513
4514 /* Save mode number in CR34 */
4515 SiS_SetReg(SISCR, 0x34, 0x2e);
4516
4517 /* Let everyone know what the current mode is */
4518 ivideo->modeprechange = 0x2e;
4519}
4520#endif
4521
4522#ifdef CONFIG_FB_SIS_315
4523#if 0
4524static void sisfb_post_sis315330(struct pci_dev *pdev)
4525{
4526 /* TODO */
4527}
4528#endif
4529
4530static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
4531{
4532 return ivideo->chip_real_id == XGI_21;
4533}
4534
4535static void sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4536{
4537 unsigned int i;
4538 u8 reg;
4539
4540 for(i = 0; i <= (delay * 10 * 36); i++) {
4541 reg = SiS_GetReg(SISSR, 0x05);
4542 reg++;
4543 }
4544}
4545
4546static int sisfb_find_host_bridge(struct sis_video_info *ivideo,
4547 struct pci_dev *mypdev,
4548 unsigned short pcivendor)
4549{
4550 struct pci_dev *pdev = NULL;
4551 unsigned short temp;
4552 int ret = 0;
4553
4554 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) {
4555 temp = pdev->vendor;
4556 if(temp == pcivendor) {
4557 ret = 1;
4558 pci_dev_put(pdev);
4559 break;
4560 }
4561 }
4562
4563 return ret;
4564}
4565
4566static int sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4567 unsigned int enda, unsigned int mapsize)
4568{
4569 unsigned int pos;
4570 int i;
4571
4572 writel(0, ivideo->video_vbase);
4573
4574 for(i = starta; i <= enda; i++) {
4575 pos = 1 << i;
4576 if(pos < mapsize)
4577 writel(pos, ivideo->video_vbase + pos);
4578 }
4579
4580 sisfb_post_xgi_delay(ivideo, 150);
4581
4582 if(readl(ivideo->video_vbase) != 0)
4583 return 0;
4584
4585 for(i = starta; i <= enda; i++) {
4586 pos = 1 << i;
4587 if(pos < mapsize) {
4588 if(readl(ivideo->video_vbase + pos) != pos)
4589 return 0;
4590 } else
4591 return 0;
4592 }
4593
4594 return 1;
4595}
4596
4597static int sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4598{
4599 unsigned int buswidth, ranksize, channelab, mapsize;
4600 int i, j, k, l, status;
4601 u8 reg, sr14;
4602 static const u8 dramsr13[12 * 5] = {
4603 0x02, 0x0e, 0x0b, 0x80, 0x5d,
4604 0x02, 0x0e, 0x0a, 0x40, 0x59,
4605 0x02, 0x0d, 0x0b, 0x40, 0x4d,
4606 0x02, 0x0e, 0x09, 0x20, 0x55,
4607 0x02, 0x0d, 0x0a, 0x20, 0x49,
4608 0x02, 0x0c, 0x0b, 0x20, 0x3d,
4609 0x02, 0x0e, 0x08, 0x10, 0x51,
4610 0x02, 0x0d, 0x09, 0x10, 0x45,
4611 0x02, 0x0c, 0x0a, 0x10, 0x39,
4612 0x02, 0x0d, 0x08, 0x08, 0x41,
4613 0x02, 0x0c, 0x09, 0x08, 0x35,
4614 0x02, 0x0c, 0x08, 0x04, 0x31
4615 };
4616 static const u8 dramsr13_4[4 * 5] = {
4617 0x02, 0x0d, 0x09, 0x40, 0x45,
4618 0x02, 0x0c, 0x09, 0x20, 0x35,
4619 0x02, 0x0c, 0x08, 0x10, 0x31,
4620 0x02, 0x0b, 0x08, 0x08, 0x21
4621 };
4622
4623 /* Enable linear mode, disable 0xa0000 address decoding */
4624 /* We disable a0000 address decoding, because
4625 * - if running on x86, if the card is disabled, it means
4626 * that another card is in the system. We don't want
4627 * to interphere with that primary card's textmode.
4628 * - if running on non-x86, there usually is no VGA window
4629 * at a0000.
4630 */
4631 SiS_SetRegOR(SISSR, 0x20, (0x80 | 0x04));
4632
4633 /* Need to map max FB size for finding out about RAM size */
4634 mapsize = ivideo->video_size;
4635 sisfb_post_map_vram(ivideo, &mapsize, 32);
4636
4637 if(!ivideo->video_vbase) {
4638 printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n");
4639 SiS_SetReg(SISSR, 0x13, 0x35);
4640 SiS_SetReg(SISSR, 0x14, 0x41);
4641 /* TODO */
4642 return -ENOMEM;
4643 }
4644
4645 /* Non-interleaving */
4646 SiS_SetReg(SISSR, 0x15, 0x00);
4647 /* No tiling */
4648 SiS_SetReg(SISSR, 0x1c, 0x00);
4649
4650 if(ivideo->chip == XGI_20) {
4651
4652 channelab = 1;
4653 reg = SiS_GetReg(SISCR, 0x97);
4654 if(!(reg & 0x01)) { /* Single 32/16 */
4655 buswidth = 32;
4656 SiS_SetReg(SISSR, 0x13, 0xb1);
4657 SiS_SetReg(SISSR, 0x14, 0x52);
4658 sisfb_post_xgi_delay(ivideo, 1);
4659 sr14 = 0x02;
4660 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4661 goto bail_out;
4662
4663 SiS_SetReg(SISSR, 0x13, 0x31);
4664 SiS_SetReg(SISSR, 0x14, 0x42);
4665 sisfb_post_xgi_delay(ivideo, 1);
4666 if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize))
4667 goto bail_out;
4668
4669 buswidth = 16;
4670 SiS_SetReg(SISSR, 0x13, 0xb1);
4671 SiS_SetReg(SISSR, 0x14, 0x41);
4672 sisfb_post_xgi_delay(ivideo, 1);
4673 sr14 = 0x01;
4674 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4675 goto bail_out;
4676 else
4677 SiS_SetReg(SISSR, 0x13, 0x31);
4678 } else { /* Dual 16/8 */
4679 buswidth = 16;
4680 SiS_SetReg(SISSR, 0x13, 0xb1);
4681 SiS_SetReg(SISSR, 0x14, 0x41);
4682 sisfb_post_xgi_delay(ivideo, 1);
4683 sr14 = 0x01;
4684 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4685 goto bail_out;
4686
4687 SiS_SetReg(SISSR, 0x13, 0x31);
4688 SiS_SetReg(SISSR, 0x14, 0x31);
4689 sisfb_post_xgi_delay(ivideo, 1);
4690 if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize))
4691 goto bail_out;
4692
4693 buswidth = 8;
4694 SiS_SetReg(SISSR, 0x13, 0xb1);
4695 SiS_SetReg(SISSR, 0x14, 0x30);
4696 sisfb_post_xgi_delay(ivideo, 1);
4697 sr14 = 0x00;
4698 if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize))
4699 goto bail_out;
4700 else
4701 SiS_SetReg(SISSR, 0x13, 0x31);
4702 }
4703
4704 } else { /* XGI_40 */
4705
4706 reg = SiS_GetReg(SISCR, 0x97);
4707 if(!(reg & 0x10)) {
4708 reg = SiS_GetReg(SISSR, 0x39);
4709 reg >>= 1;
4710 }
4711
4712 if(reg & 0x01) { /* DDRII */
4713 buswidth = 32;
4714 if(ivideo->revision_id == 2) {
4715 channelab = 2;
4716 SiS_SetReg(SISSR, 0x13, 0xa1);
4717 SiS_SetReg(SISSR, 0x14, 0x44);
4718 sr14 = 0x04;
4719 sisfb_post_xgi_delay(ivideo, 1);
4720 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4721 goto bail_out;
4722
4723 SiS_SetReg(SISSR, 0x13, 0x21);
4724 SiS_SetReg(SISSR, 0x14, 0x34);
4725 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4726 goto bail_out;
4727
4728 channelab = 1;
4729 SiS_SetReg(SISSR, 0x13, 0xa1);
4730 SiS_SetReg(SISSR, 0x14, 0x40);
4731 sr14 = 0x00;
4732 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4733 goto bail_out;
4734
4735 SiS_SetReg(SISSR, 0x13, 0x21);
4736 SiS_SetReg(SISSR, 0x14, 0x30);
4737 } else {
4738 channelab = 3;
4739 SiS_SetReg(SISSR, 0x13, 0xa1);
4740 SiS_SetReg(SISSR, 0x14, 0x4c);
4741 sr14 = 0x0c;
4742 sisfb_post_xgi_delay(ivideo, 1);
4743 if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize))
4744 goto bail_out;
4745
4746 channelab = 2;
4747 SiS_SetReg(SISSR, 0x14, 0x48);
4748 sisfb_post_xgi_delay(ivideo, 1);
4749 sr14 = 0x08;
4750 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4751 goto bail_out;
4752
4753 SiS_SetReg(SISSR, 0x13, 0x21);
4754 SiS_SetReg(SISSR, 0x14, 0x3c);
4755 sr14 = 0x0c;
4756
4757 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) {
4758 channelab = 3;
4759 } else {
4760 channelab = 2;
4761 SiS_SetReg(SISSR, 0x14, 0x38);
4762 sr14 = 0x08;
4763 }
4764 }
4765 sisfb_post_xgi_delay(ivideo, 1);
4766
4767 } else { /* DDR */
4768
4769 buswidth = 64;
4770 if(ivideo->revision_id == 2) {
4771 channelab = 1;
4772 SiS_SetReg(SISSR, 0x13, 0xa1);
4773 SiS_SetReg(SISSR, 0x14, 0x52);
4774 sisfb_post_xgi_delay(ivideo, 1);
4775 sr14 = 0x02;
4776 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4777 goto bail_out;
4778
4779 SiS_SetReg(SISSR, 0x13, 0x21);
4780 SiS_SetReg(SISSR, 0x14, 0x42);
4781 } else {
4782 channelab = 2;
4783 SiS_SetReg(SISSR, 0x13, 0xa1);
4784 SiS_SetReg(SISSR, 0x14, 0x5a);
4785 sisfb_post_xgi_delay(ivideo, 1);
4786 sr14 = 0x0a;
4787 if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize))
4788 goto bail_out;
4789
4790 SiS_SetReg(SISSR, 0x13, 0x21);
4791 SiS_SetReg(SISSR, 0x14, 0x4a);
4792 }
4793 sisfb_post_xgi_delay(ivideo, 1);
4794
4795 }
4796 }
4797
4798bail_out:
4799 SiS_SetRegANDOR(SISSR, 0x14, 0xf0, sr14);
4800 sisfb_post_xgi_delay(ivideo, 1);
4801
4802 j = (ivideo->chip == XGI_20) ? 5 : 9;
4803 k = (ivideo->chip == XGI_20) ? 12 : 4;
4804 status = -EIO;
4805
4806 for(i = 0; i < k; i++) {
4807
4808 reg = (ivideo->chip == XGI_20) ?
4809 dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4];
4810 SiS_SetRegANDOR(SISSR, 0x13, 0x80, reg);
4811 sisfb_post_xgi_delay(ivideo, 50);
4812
4813 ranksize = (ivideo->chip == XGI_20) ?
4814 dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3];
4815
4816 reg = SiS_GetReg(SISSR, 0x13);
4817 if(reg & 0x80) ranksize <<= 1;
4818
4819 if(ivideo->chip == XGI_20) {
4820 if(buswidth == 16) ranksize <<= 1;
4821 else if(buswidth == 32) ranksize <<= 2;
4822 } else {
4823 if(buswidth == 64) ranksize <<= 1;
4824 }
4825
4826 reg = 0;
4827 l = channelab;
4828 if(l == 3) l = 4;
4829 if((ranksize * l) <= 256) {
4830 while((ranksize >>= 1)) reg += 0x10;
4831 }
4832
4833 if(!reg) continue;
4834
4835 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
4836 sisfb_post_xgi_delay(ivideo, 1);
4837
4838 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4839 status = 0;
4840 break;
4841 }
4842 }
4843
4844 iounmap(ivideo->video_vbase);
4845
4846 return status;
4847}
4848
4849static void sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
4850{
4851 u8 v1, v2, v3;
4852 int index;
4853 static const u8 cs90[8 * 3] = {
4854 0x16, 0x01, 0x01,
4855 0x3e, 0x03, 0x01,
4856 0x7c, 0x08, 0x01,
4857 0x79, 0x06, 0x01,
4858 0x29, 0x01, 0x81,
4859 0x5c, 0x23, 0x01,
4860 0x5c, 0x23, 0x01,
4861 0x5c, 0x23, 0x01
4862 };
4863 static const u8 csb8[8 * 3] = {
4864 0x5c, 0x23, 0x01,
4865 0x29, 0x01, 0x01,
4866 0x7c, 0x08, 0x01,
4867 0x79, 0x06, 0x01,
4868 0x29, 0x01, 0x81,
4869 0x5c, 0x23, 0x01,
4870 0x5c, 0x23, 0x01,
4871 0x5c, 0x23, 0x01
4872 };
4873
4874 regb = 0; /* ! */
4875
4876 index = regb * 3;
4877 v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2];
4878 if(ivideo->haveXGIROM) {
4879 v1 = ivideo->bios_abase[0x90 + index];
4880 v2 = ivideo->bios_abase[0x90 + index + 1];
4881 v3 = ivideo->bios_abase[0x90 + index + 2];
4882 }
4883 SiS_SetReg(SISSR, 0x28, v1);
4884 SiS_SetReg(SISSR, 0x29, v2);
4885 SiS_SetReg(SISSR, 0x2a, v3);
4886 sisfb_post_xgi_delay(ivideo, 0x43);
4887 sisfb_post_xgi_delay(ivideo, 0x43);
4888 sisfb_post_xgi_delay(ivideo, 0x43);
4889 index = regb * 3;
4890 v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2];
4891 if(ivideo->haveXGIROM) {
4892 v1 = ivideo->bios_abase[0xb8 + index];
4893 v2 = ivideo->bios_abase[0xb8 + index + 1];
4894 v3 = ivideo->bios_abase[0xb8 + index + 2];
4895 }
4896 SiS_SetReg(SISSR, 0x2e, v1);
4897 SiS_SetReg(SISSR, 0x2f, v2);
4898 SiS_SetReg(SISSR, 0x30, v3);
4899 sisfb_post_xgi_delay(ivideo, 0x43);
4900 sisfb_post_xgi_delay(ivideo, 0x43);
4901 sisfb_post_xgi_delay(ivideo, 0x43);
4902}
4903
4904static void sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo,
4905 u8 regb)
4906{
4907 unsigned char *bios = ivideo->bios_abase;
4908 u8 v1;
4909
4910 SiS_SetReg(SISSR, 0x28, 0x64);
4911 SiS_SetReg(SISSR, 0x29, 0x63);
4912 sisfb_post_xgi_delay(ivideo, 15);
4913 SiS_SetReg(SISSR, 0x18, 0x00);
4914 SiS_SetReg(SISSR, 0x19, 0x20);
4915 SiS_SetReg(SISSR, 0x16, 0x00);
4916 SiS_SetReg(SISSR, 0x16, 0x80);
4917 SiS_SetReg(SISSR, 0x18, 0xc5);
4918 SiS_SetReg(SISSR, 0x19, 0x23);
4919 SiS_SetReg(SISSR, 0x16, 0x00);
4920 SiS_SetReg(SISSR, 0x16, 0x80);
4921 sisfb_post_xgi_delay(ivideo, 1);
4922 SiS_SetReg(SISCR, 0x97, 0x11);
4923 sisfb_post_xgi_setclocks(ivideo, regb);
4924 sisfb_post_xgi_delay(ivideo, 0x46);
4925 SiS_SetReg(SISSR, 0x18, 0xc5);
4926 SiS_SetReg(SISSR, 0x19, 0x23);
4927 SiS_SetReg(SISSR, 0x16, 0x00);
4928 SiS_SetReg(SISSR, 0x16, 0x80);
4929 sisfb_post_xgi_delay(ivideo, 1);
4930 SiS_SetReg(SISSR, 0x1b, 0x04);
4931 sisfb_post_xgi_delay(ivideo, 1);
4932 SiS_SetReg(SISSR, 0x1b, 0x00);
4933 sisfb_post_xgi_delay(ivideo, 1);
4934 v1 = 0x31;
4935 if (ivideo->haveXGIROM) {
4936 v1 = bios[0xf0];
4937 }
4938 SiS_SetReg(SISSR, 0x18, v1);
4939 SiS_SetReg(SISSR, 0x19, 0x06);
4940 SiS_SetReg(SISSR, 0x16, 0x04);
4941 SiS_SetReg(SISSR, 0x16, 0x84);
4942 sisfb_post_xgi_delay(ivideo, 1);
4943}
4944
4945static void sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
4946{
4947 sisfb_post_xgi_setclocks(ivideo, 1);
4948
4949 SiS_SetReg(SISCR, 0x97, 0x11);
4950 sisfb_post_xgi_delay(ivideo, 0x46);
4951
4952 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
4953 SiS_SetReg(SISSR, 0x19, 0x80);
4954 SiS_SetReg(SISSR, 0x16, 0x05);
4955 SiS_SetReg(SISSR, 0x16, 0x85);
4956
4957 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
4958 SiS_SetReg(SISSR, 0x19, 0xc0);
4959 SiS_SetReg(SISSR, 0x16, 0x05);
4960 SiS_SetReg(SISSR, 0x16, 0x85);
4961
4962 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
4963 SiS_SetReg(SISSR, 0x19, 0x40);
4964 SiS_SetReg(SISSR, 0x16, 0x05);
4965 SiS_SetReg(SISSR, 0x16, 0x85);
4966
4967 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
4968 SiS_SetReg(SISSR, 0x19, 0x02);
4969 SiS_SetReg(SISSR, 0x16, 0x05);
4970 SiS_SetReg(SISSR, 0x16, 0x85);
4971 sisfb_post_xgi_delay(ivideo, 1);
4972
4973 SiS_SetReg(SISSR, 0x1b, 0x04);
4974 sisfb_post_xgi_delay(ivideo, 1);
4975
4976 SiS_SetReg(SISSR, 0x1b, 0x00);
4977 sisfb_post_xgi_delay(ivideo, 1);
4978
4979 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
4980 SiS_SetReg(SISSR, 0x19, 0x00);
4981 SiS_SetReg(SISSR, 0x16, 0x05);
4982 SiS_SetReg(SISSR, 0x16, 0x85);
4983 sisfb_post_xgi_delay(ivideo, 1);
4984}
4985
4986static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
4987{
4988 unsigned char *bios = ivideo->bios_abase;
4989 static const u8 cs158[8] = {
4990 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
4991 };
4992 static const u8 cs160[8] = {
4993 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
4994 };
4995 static const u8 cs168[8] = {
4996 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
4997 };
4998 u8 reg;
4999 u8 v1;
5000 u8 v2;
5001 u8 v3;
5002
5003 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
5004 SiS_SetReg(SISCR, 0x82, 0x77);
5005 SiS_SetReg(SISCR, 0x86, 0x00);
5006 reg = SiS_GetReg(SISCR, 0x86);
5007 SiS_SetReg(SISCR, 0x86, 0x88);
5008 reg = SiS_GetReg(SISCR, 0x86);
5009 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5010 if (ivideo->haveXGIROM) {
5011 v1 = bios[regb + 0x168];
5012 v2 = bios[regb + 0x160];
5013 v3 = bios[regb + 0x158];
5014 }
5015 SiS_SetReg(SISCR, 0x86, v1);
5016 SiS_SetReg(SISCR, 0x82, 0x77);
5017 SiS_SetReg(SISCR, 0x85, 0x00);
5018 reg = SiS_GetReg(SISCR, 0x85);
5019 SiS_SetReg(SISCR, 0x85, 0x88);
5020 reg = SiS_GetReg(SISCR, 0x85);
5021 SiS_SetReg(SISCR, 0x85, v2);
5022 SiS_SetReg(SISCR, 0x82, v3);
5023 SiS_SetReg(SISCR, 0x98, 0x01);
5024 SiS_SetReg(SISCR, 0x9a, 0x02);
5025 if (sisfb_xgi_is21(ivideo))
5026 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5027 else
5028 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5029}
5030
5031static u8 sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
5032{
5033 unsigned char *bios = ivideo->bios_abase;
5034 u8 ramtype;
5035 u8 reg;
5036 u8 v1;
5037
5038 ramtype = 0x00; v1 = 0x10;
5039 if (ivideo->haveXGIROM) {
5040 ramtype = bios[0x62];
5041 v1 = bios[0x1d2];
5042 }
5043 if (!(ramtype & 0x80)) {
5044 if (sisfb_xgi_is21(ivideo)) {
5045 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
5046 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
5047 reg = SiS_GetReg(SISCR, 0x48);
5048 SiS_SetRegOR(SISCR, 0xb4, 0x02);
5049 ramtype = reg & 0x01; /* GPIOH */
5050 } else if (ivideo->chip == XGI_20) {
5051 SiS_SetReg(SISCR, 0x97, v1);
5052 reg = SiS_GetReg(SISCR, 0x97);
5053 if (reg & 0x10) {
5054 ramtype = (reg & 0x01) << 1;
5055 }
5056 } else {
5057 reg = SiS_GetReg(SISSR, 0x39);
5058 ramtype = reg & 0x02;
5059 if (!(ramtype)) {
5060 reg = SiS_GetReg(SISSR, 0x3a);
5061 ramtype = (reg >> 1) & 0x01;
5062 }
5063 }
5064 }
5065 ramtype &= 0x07;
5066
5067 return ramtype;
5068}
5069
5070static int sisfb_post_xgi(struct pci_dev *pdev)
5071{
5072 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
5073 unsigned char *bios = ivideo->bios_abase;
5074 struct pci_dev *mypdev = NULL;
5075 const u8 *ptr, *ptr2;
5076 u8 v1, v2, v3, v4, v5, reg, ramtype;
5077 u32 rega, regb, regd;
5078 int i, j, k, index;
5079 static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
5080 static const u8 cs76[2] = { 0xa3, 0xfb };
5081 static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
5082 static const u8 cs158[8] = {
5083 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5084 };
5085 static const u8 cs160[8] = {
5086 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5087 };
5088 static const u8 cs168[8] = {
5089 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5090 };
5091 static const u8 cs128[3 * 8] = {
5092 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
5093 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5094 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
5095 };
5096 static const u8 cs148[2 * 8] = {
5097 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
5098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5099 };
5100 static const u8 cs31a[8 * 4] = {
5101 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
5102 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
5103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5105 };
5106 static const u8 cs33a[8 * 4] = {
5107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5111 };
5112 static const u8 cs45a[8 * 2] = {
5113 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
5114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5115 };
5116 static const u8 cs170[7 * 8] = {
5117 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5118 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5119 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
5120 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5121 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
5122 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
5123 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
5124 };
5125 static const u8 cs1a8[3 * 8] = {
5126 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
5127 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
5128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5129 };
5130 static const u8 cs100[2 * 8] = {
5131 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
5132 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
5133 };
5134
5135 /* VGA enable */
5136 reg = SiS_GetRegByte(SISVGAENABLE) | 0x01;
5137 SiS_SetRegByte(SISVGAENABLE, reg);
5138
5139 /* Misc */
5140 reg = SiS_GetRegByte(SISMISCR) | 0x01;
5141 SiS_SetRegByte(SISMISCW, reg);
5142
5143 /* Unlock SR */
5144 SiS_SetReg(SISSR, 0x05, 0x86);
5145 reg = SiS_GetReg(SISSR, 0x05);
5146 if(reg != 0xa1)
5147 return 0;
5148
5149 /* Clear some regs */
5150 for(i = 0; i < 0x22; i++) {
5151 if(0x06 + i == 0x20) continue;
5152 SiS_SetReg(SISSR, 0x06 + i, 0x00);
5153 }
5154 for(i = 0; i < 0x0b; i++) {
5155 SiS_SetReg(SISSR, 0x31 + i, 0x00);
5156 }
5157 for(i = 0; i < 0x10; i++) {
5158 SiS_SetReg(SISCR, 0x30 + i, 0x00);
5159 }
5160
5161 ptr = cs78;
5162 if(ivideo->haveXGIROM) {
5163 ptr = (const u8 *)&bios[0x78];
5164 }
5165 for(i = 0; i < 3; i++) {
5166 SiS_SetReg(SISSR, 0x23 + i, ptr[i]);
5167 }
5168
5169 ptr = cs76;
5170 if(ivideo->haveXGIROM) {
5171 ptr = (const u8 *)&bios[0x76];
5172 }
5173 for(i = 0; i < 2; i++) {
5174 SiS_SetReg(SISSR, 0x21 + i, ptr[i]);
5175 }
5176
5177 v1 = 0x18; v2 = 0x00;
5178 if(ivideo->haveXGIROM) {
5179 v1 = bios[0x74];
5180 v2 = bios[0x75];
5181 }
5182 SiS_SetReg(SISSR, 0x07, v1);
5183 SiS_SetReg(SISSR, 0x11, 0x0f);
5184 SiS_SetReg(SISSR, 0x1f, v2);
5185 /* PCI linear mode, RelIO enabled, A0000 decoding disabled */
5186 SiS_SetReg(SISSR, 0x20, 0x80 | 0x20 | 0x04);
5187 SiS_SetReg(SISSR, 0x27, 0x74);
5188
5189 ptr = cs7b;
5190 if(ivideo->haveXGIROM) {
5191 ptr = (const u8 *)&bios[0x7b];
5192 }
5193 for(i = 0; i < 3; i++) {
5194 SiS_SetReg(SISSR, 0x31 + i, ptr[i]);
5195 }
5196
5197 if(ivideo->chip == XGI_40) {
5198 if(ivideo->revision_id == 2) {
5199 SiS_SetRegANDOR(SISSR, 0x3b, 0x3f, 0xc0);
5200 }
5201 SiS_SetReg(SISCR, 0x7d, 0xfe);
5202 SiS_SetReg(SISCR, 0x7e, 0x0f);
5203 }
5204 if(ivideo->revision_id == 0) { /* 40 *and* 20? */
5205 SiS_SetRegAND(SISCR, 0x58, 0xd7);
5206 reg = SiS_GetReg(SISCR, 0xcb);
5207 if(reg & 0x20) {
5208 SiS_SetRegANDOR(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */
5209 }
5210 }
5211
5212 reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00;
5213 SiS_SetRegANDOR(SISCR, 0x38, 0x1f, reg);
5214
5215 if(ivideo->chip == XGI_20) {
5216 SiS_SetReg(SISSR, 0x36, 0x70);
5217 } else {
5218 SiS_SetReg(SISVID, 0x00, 0x86);
5219 SiS_SetReg(SISVID, 0x32, 0x00);
5220 SiS_SetReg(SISVID, 0x30, 0x00);
5221 SiS_SetReg(SISVID, 0x32, 0x01);
5222 SiS_SetReg(SISVID, 0x30, 0x00);
5223 SiS_SetRegAND(SISVID, 0x2f, 0xdf);
5224 SiS_SetRegAND(SISCAP, 0x00, 0x3f);
5225
5226 SiS_SetReg(SISPART1, 0x2f, 0x01);
5227 SiS_SetReg(SISPART1, 0x00, 0x00);
5228 SiS_SetReg(SISPART1, 0x02, bios[0x7e]);
5229 SiS_SetReg(SISPART1, 0x2e, 0x08);
5230 SiS_SetRegAND(SISPART1, 0x35, 0x7f);
5231 SiS_SetRegAND(SISPART1, 0x50, 0xfe);
5232
5233 reg = SiS_GetReg(SISPART4, 0x00);
5234 if(reg == 1 || reg == 2) {
5235 SiS_SetReg(SISPART2, 0x00, 0x1c);
5236 SiS_SetReg(SISPART4, 0x0d, bios[0x7f]);
5237 SiS_SetReg(SISPART4, 0x0e, bios[0x80]);
5238 SiS_SetReg(SISPART4, 0x10, bios[0x81]);
5239 SiS_SetRegAND(SISPART4, 0x0f, 0x3f);
5240
5241 reg = SiS_GetReg(SISPART4, 0x01);
5242 if((reg & 0xf0) >= 0xb0) {
5243 reg = SiS_GetReg(SISPART4, 0x23);
5244 if(reg & 0x20) reg |= 0x40;
5245 SiS_SetReg(SISPART4, 0x23, reg);
5246 reg = (reg & 0x20) ? 0x02 : 0x00;
5247 SiS_SetRegANDOR(SISPART1, 0x1e, 0xfd, reg);
5248 }
5249 }
5250
5251 v1 = bios[0x77];
5252
5253 reg = SiS_GetReg(SISSR, 0x3b);
5254 if(reg & 0x02) {
5255 reg = SiS_GetReg(SISSR, 0x3a);
5256 v2 = (reg & 0x30) >> 3;
5257 if(!(v2 & 0x04)) v2 ^= 0x02;
5258 reg = SiS_GetReg(SISSR, 0x39);
5259 if(reg & 0x80) v2 |= 0x80;
5260 v2 |= 0x01;
5261
5262 if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
5263 pci_dev_put(mypdev);
5264 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
5265 v2 &= 0xf9;
5266 v2 |= 0x08;
5267 v1 &= 0xfe;
5268 } else {
5269 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL);
5270 if(!mypdev)
5271 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL);
5272 if(!mypdev)
5273 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL);
5274 if(mypdev) {
5275 pci_read_config_dword(mypdev, 0x94, &regd);
5276 regd &= 0xfffffeff;
5277 pci_write_config_dword(mypdev, 0x94, regd);
5278 v1 &= 0xfe;
5279 pci_dev_put(mypdev);
5280 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
5281 v1 &= 0xfe;
5282 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
5283 sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
5284 sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
5285 sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
5286 if((v2 & 0x06) == 4)
5287 v2 ^= 0x06;
5288 v2 |= 0x08;
5289 }
5290 }
5291 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, v2);
5292 }
5293 SiS_SetReg(SISSR, 0x22, v1);
5294
5295 if(ivideo->revision_id == 2) {
5296 v1 = SiS_GetReg(SISSR, 0x3b);
5297 v2 = SiS_GetReg(SISSR, 0x3a);
5298 regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
5299 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
5300 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01);
5301
5302 if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) {
5303 /* TODO: set CR5f &0xf1 | 0x01 for version 6570
5304 * of nforce 2 ROM
5305 */
5306 if(0)
5307 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01);
5308 pci_dev_put(mypdev);
5309 }
5310 }
5311
5312 v1 = 0x30;
5313 reg = SiS_GetReg(SISSR, 0x3b);
5314 v2 = SiS_GetReg(SISCR, 0x5f);
5315 if((!(reg & 0x02)) && (v2 & 0x0e))
5316 v1 |= 0x08;
5317 SiS_SetReg(SISSR, 0x27, v1);
5318
5319 if(bios[0x64] & 0x01) {
5320 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, bios[0x64]);
5321 }
5322
5323 v1 = bios[0x4f7];
5324 pci_read_config_dword(pdev, 0x50, &regd);
5325 regd = (regd >> 20) & 0x0f;
5326 if(regd == 1) {
5327 v1 &= 0xfc;
5328 SiS_SetRegOR(SISCR, 0x5f, 0x08);
5329 }
5330 SiS_SetReg(SISCR, 0x48, v1);
5331
5332 SiS_SetRegANDOR(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb);
5333 SiS_SetRegANDOR(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f);
5334 SiS_SetRegANDOR(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f);
5335 SiS_SetRegANDOR(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7);
5336 SiS_SetRegANDOR(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f);
5337 SiS_SetReg(SISCR, 0x70, bios[0x4fc]);
5338 SiS_SetRegANDOR(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f);
5339 SiS_SetReg(SISCR, 0x74, 0xd0);
5340 SiS_SetRegANDOR(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30);
5341 SiS_SetRegANDOR(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
5342 SiS_SetRegANDOR(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
5343 v1 = bios[0x501];
5344 if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) {
5345 v1 = 0xf0;
5346 pci_dev_put(mypdev);
5347 }
5348 SiS_SetReg(SISCR, 0x77, v1);
5349 }
5350
5351 /* RAM type:
5352 *
5353 * 0 == DDR1, 1 == DDR2, 2..7 == reserved?
5354 *
5355 * The code seems to written so that regb should equal ramtype,
5356 * however, so far it has been hardcoded to 0. Enable other values only
5357 * on XGI Z9, as it passes the POST, and add a warning for others.
5358 */
5359 ramtype = sisfb_post_xgi_ramtype(ivideo);
5360 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5361 dev_warn(&pdev->dev,
5362 "RAM type something else than expected: %d\n",
5363 ramtype);
5364 regb = 0;
5365 } else {
5366 regb = ramtype;
5367 }
5368
5369 v1 = 0xff;
5370 if(ivideo->haveXGIROM) {
5371 v1 = bios[0x140 + regb];
5372 }
5373 SiS_SetReg(SISCR, 0x6d, v1);
5374
5375 ptr = cs128;
5376 if(ivideo->haveXGIROM) {
5377 ptr = (const u8 *)&bios[0x128];
5378 }
5379 for(i = 0, j = 0; i < 3; i++, j += 8) {
5380 SiS_SetReg(SISCR, 0x68 + i, ptr[j + regb]);
5381 }
5382
5383 ptr = cs31a;
5384 ptr2 = cs33a;
5385 if(ivideo->haveXGIROM) {
5386 index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6;
5387 ptr = (const u8 *)&bios[index];
5388 ptr2 = (const u8 *)&bios[index + 0x20];
5389 }
5390 for(i = 0; i < 2; i++) {
5391 if(i == 0) {
5392 regd = le32_to_cpu(((u32 *)ptr)[regb]);
5393 rega = 0x6b;
5394 } else {
5395 regd = le32_to_cpu(((u32 *)ptr2)[regb]);
5396 rega = 0x6e;
5397 }
5398 reg = 0x00;
5399 for(j = 0; j < 16; j++) {
5400 reg &= 0xf3;
5401 if(regd & 0x01) reg |= 0x04;
5402 if(regd & 0x02) reg |= 0x08;
5403 regd >>= 2;
5404 SiS_SetReg(SISCR, rega, reg);
5405 reg = SiS_GetReg(SISCR, rega);
5406 reg = SiS_GetReg(SISCR, rega);
5407 reg += 0x10;
5408 }
5409 }
5410
5411 SiS_SetRegAND(SISCR, 0x6e, 0xfc);
5412
5413 ptr = NULL;
5414 if(ivideo->haveXGIROM) {
5415 index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6;
5416 ptr = (const u8 *)&bios[index];
5417 }
5418 for(i = 0; i < 4; i++) {
5419 SiS_SetRegANDOR(SISCR, 0x6e, 0xfc, i);
5420 reg = 0x00;
5421 for(j = 0; j < 2; j++) {
5422 regd = 0;
5423 if(ptr) {
5424 regd = le32_to_cpu(((u32 *)ptr)[regb * 8]);
5425 ptr += 4;
5426 }
5427 /* reg = 0x00; */
5428 for(k = 0; k < 16; k++) {
5429 reg &= 0xfc;
5430 if(regd & 0x01) reg |= 0x01;
5431 if(regd & 0x02) reg |= 0x02;
5432 regd >>= 2;
5433 SiS_SetReg(SISCR, 0x6f, reg);
5434 reg = SiS_GetReg(SISCR, 0x6f);
5435 reg = SiS_GetReg(SISCR, 0x6f);
5436 reg += 0x08;
5437 }
5438 }
5439 }
5440
5441 ptr = cs148;
5442 if(ivideo->haveXGIROM) {
5443 ptr = (const u8 *)&bios[0x148];
5444 }
5445 for(i = 0, j = 0; i < 2; i++, j += 8) {
5446 SiS_SetReg(SISCR, 0x80 + i, ptr[j + regb]);
5447 }
5448
5449 SiS_SetRegAND(SISCR, 0x89, 0x8f);
5450
5451 ptr = cs45a;
5452 if(ivideo->haveXGIROM) {
5453 index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6;
5454 ptr = (const u8 *)&bios[index];
5455 }
5456 regd = le16_to_cpu(((const u16 *)ptr)[regb]);
5457 reg = 0x80;
5458 for(i = 0; i < 5; i++) {
5459 reg &= 0xfc;
5460 if(regd & 0x01) reg |= 0x01;
5461 if(regd & 0x02) reg |= 0x02;
5462 regd >>= 2;
5463 SiS_SetReg(SISCR, 0x89, reg);
5464 reg = SiS_GetReg(SISCR, 0x89);
5465 reg = SiS_GetReg(SISCR, 0x89);
5466 reg += 0x10;
5467 }
5468
5469 v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
5470 if(ivideo->haveXGIROM) {
5471 v1 = bios[0x118 + regb];
5472 v2 = bios[0xf8 + regb];
5473 v3 = bios[0x120 + regb];
5474 v4 = bios[0x1ca];
5475 }
5476 SiS_SetReg(SISCR, 0x45, v1 & 0x0f);
5477 SiS_SetReg(SISCR, 0x99, (v1 >> 4) & 0x07);
5478 SiS_SetRegOR(SISCR, 0x40, v1 & 0x80);
5479 SiS_SetReg(SISCR, 0x41, v2);
5480
5481 ptr = cs170;
5482 if(ivideo->haveXGIROM) {
5483 ptr = (const u8 *)&bios[0x170];
5484 }
5485 for(i = 0, j = 0; i < 7; i++, j += 8) {
5486 SiS_SetReg(SISCR, 0x90 + i, ptr[j + regb]);
5487 }
5488
5489 SiS_SetReg(SISCR, 0x59, v3);
5490
5491 ptr = cs1a8;
5492 if(ivideo->haveXGIROM) {
5493 ptr = (const u8 *)&bios[0x1a8];
5494 }
5495 for(i = 0, j = 0; i < 3; i++, j += 8) {
5496 SiS_SetReg(SISCR, 0xc3 + i, ptr[j + regb]);
5497 }
5498
5499 ptr = cs100;
5500 if(ivideo->haveXGIROM) {
5501 ptr = (const u8 *)&bios[0x100];
5502 }
5503 for(i = 0, j = 0; i < 2; i++, j += 8) {
5504 SiS_SetReg(SISCR, 0x8a + i, ptr[j + regb]);
5505 }
5506
5507 SiS_SetReg(SISCR, 0xcf, v4);
5508
5509 SiS_SetReg(SISCR, 0x83, 0x09);
5510 SiS_SetReg(SISCR, 0x87, 0x00);
5511
5512 if(ivideo->chip == XGI_40) {
5513 if( (ivideo->revision_id == 1) ||
5514 (ivideo->revision_id == 2) ) {
5515 SiS_SetReg(SISCR, 0x8c, 0x87);
5516 }
5517 }
5518
5519 if (regb == 1)
5520 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
5521 else
5522 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
5523 SiS_SetReg(SISSR, 0x1a, 0x87);
5524
5525 if(ivideo->chip == XGI_20) {
5526 SiS_SetReg(SISSR, 0x15, 0x00);
5527 SiS_SetReg(SISSR, 0x1c, 0x00);
5528 }
5529
5530 switch(ramtype) {
5531 case 0:
5532 sisfb_post_xgi_setclocks(ivideo, regb);
5533 if((ivideo->chip == XGI_20) ||
5534 (ivideo->revision_id == 1) ||
5535 (ivideo->revision_id == 2)) {
5536 v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
5537 if(ivideo->haveXGIROM) {
5538 v1 = bios[regb + 0x158];
5539 v2 = bios[regb + 0x160];
5540 v3 = bios[regb + 0x168];
5541 }
5542 SiS_SetReg(SISCR, 0x82, v1);
5543 SiS_SetReg(SISCR, 0x85, v2);
5544 SiS_SetReg(SISCR, 0x86, v3);
5545 } else {
5546 SiS_SetReg(SISCR, 0x82, 0x88);
5547 SiS_SetReg(SISCR, 0x86, 0x00);
5548 reg = SiS_GetReg(SISCR, 0x86);
5549 SiS_SetReg(SISCR, 0x86, 0x88);
5550 reg = SiS_GetReg(SISCR, 0x86);
5551 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]);
5552 SiS_SetReg(SISCR, 0x82, 0x77);
5553 SiS_SetReg(SISCR, 0x85, 0x00);
5554 reg = SiS_GetReg(SISCR, 0x85);
5555 SiS_SetReg(SISCR, 0x85, 0x88);
5556 reg = SiS_GetReg(SISCR, 0x85);
5557 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]);
5558 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]);
5559 }
5560 if(ivideo->chip == XGI_40) {
5561 SiS_SetReg(SISCR, 0x97, 0x00);
5562 }
5563 SiS_SetReg(SISCR, 0x98, 0x01);
5564 SiS_SetReg(SISCR, 0x9a, 0x02);
5565
5566 SiS_SetReg(SISSR, 0x18, 0x01);
5567 if((ivideo->chip == XGI_20) ||
5568 (ivideo->revision_id == 2)) {
5569 SiS_SetReg(SISSR, 0x19, 0x40);
5570 } else {
5571 SiS_SetReg(SISSR, 0x19, 0x20);
5572 }
5573 SiS_SetReg(SISSR, 0x16, 0x00);
5574 SiS_SetReg(SISSR, 0x16, 0x80);
5575 if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) {
5576 sisfb_post_xgi_delay(ivideo, 0x43);
5577 sisfb_post_xgi_delay(ivideo, 0x43);
5578 sisfb_post_xgi_delay(ivideo, 0x43);
5579 SiS_SetReg(SISSR, 0x18, 0x00);
5580 if((ivideo->chip == XGI_20) ||
5581 (ivideo->revision_id == 2)) {
5582 SiS_SetReg(SISSR, 0x19, 0x40);
5583 } else {
5584 SiS_SetReg(SISSR, 0x19, 0x20);
5585 }
5586 } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) {
5587 /* SiS_SetReg(SISSR, 0x16, 0x0c); */ /* ? */
5588 }
5589 SiS_SetReg(SISSR, 0x16, 0x00);
5590 SiS_SetReg(SISSR, 0x16, 0x80);
5591 sisfb_post_xgi_delay(ivideo, 4);
5592 v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
5593 if(ivideo->haveXGIROM) {
5594 v1 = bios[0xf0];
5595 index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e;
5596 v2 = bios[index];
5597 v3 = bios[index + 1];
5598 v4 = bios[index + 2];
5599 v5 = bios[index + 3];
5600 }
5601 SiS_SetReg(SISSR, 0x18, v1);
5602 SiS_SetReg(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01));
5603 SiS_SetReg(SISSR, 0x16, v2);
5604 SiS_SetReg(SISSR, 0x16, v3);
5605 sisfb_post_xgi_delay(ivideo, 0x43);
5606 SiS_SetReg(SISSR, 0x1b, 0x03);
5607 sisfb_post_xgi_delay(ivideo, 0x22);
5608 SiS_SetReg(SISSR, 0x18, v1);
5609 SiS_SetReg(SISSR, 0x19, 0x00);
5610 SiS_SetReg(SISSR, 0x16, v4);
5611 SiS_SetReg(SISSR, 0x16, v5);
5612 SiS_SetReg(SISSR, 0x1b, 0x00);
5613 break;
5614 case 1:
5615 sisfb_post_xgi_ddr2(ivideo, regb);
5616 break;
5617 default:
5618 sisfb_post_xgi_setclocks(ivideo, regb);
5619 if((ivideo->chip == XGI_40) &&
5620 ((ivideo->revision_id == 1) ||
5621 (ivideo->revision_id == 2))) {
5622 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]);
5623 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]);
5624 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]);
5625 } else {
5626 SiS_SetReg(SISCR, 0x82, 0x88);
5627 SiS_SetReg(SISCR, 0x86, 0x00);
5628 reg = SiS_GetReg(SISCR, 0x86);
5629 SiS_SetReg(SISCR, 0x86, 0x88);
5630 SiS_SetReg(SISCR, 0x82, 0x77);
5631 SiS_SetReg(SISCR, 0x85, 0x00);
5632 reg = SiS_GetReg(SISCR, 0x85);
5633 SiS_SetReg(SISCR, 0x85, 0x88);
5634 reg = SiS_GetReg(SISCR, 0x85);
5635 v1 = cs160[regb]; v2 = cs158[regb];
5636 if(ivideo->haveXGIROM) {
5637 v1 = bios[regb + 0x160];
5638 v2 = bios[regb + 0x158];
5639 }
5640 SiS_SetReg(SISCR, 0x85, v1);
5641 SiS_SetReg(SISCR, 0x82, v2);
5642 }
5643 if(ivideo->chip == XGI_40) {
5644 SiS_SetReg(SISCR, 0x97, 0x11);
5645 }
5646 if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) {
5647 SiS_SetReg(SISCR, 0x98, 0x01);
5648 } else {
5649 SiS_SetReg(SISCR, 0x98, 0x03);
5650 }
5651 SiS_SetReg(SISCR, 0x9a, 0x02);
5652
5653 if(ivideo->chip == XGI_40) {
5654 SiS_SetReg(SISSR, 0x18, 0x01);
5655 } else {
5656 SiS_SetReg(SISSR, 0x18, 0x00);
5657 }
5658 SiS_SetReg(SISSR, 0x19, 0x40);
5659 SiS_SetReg(SISSR, 0x16, 0x00);
5660 SiS_SetReg(SISSR, 0x16, 0x80);
5661 if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) {
5662 sisfb_post_xgi_delay(ivideo, 0x43);
5663 sisfb_post_xgi_delay(ivideo, 0x43);
5664 sisfb_post_xgi_delay(ivideo, 0x43);
5665 SiS_SetReg(SISSR, 0x18, 0x00);
5666 SiS_SetReg(SISSR, 0x19, 0x40);
5667 SiS_SetReg(SISSR, 0x16, 0x00);
5668 SiS_SetReg(SISSR, 0x16, 0x80);
5669 }
5670 sisfb_post_xgi_delay(ivideo, 4);
5671 v1 = 0x31;
5672 if(ivideo->haveXGIROM) {
5673 v1 = bios[0xf0];
5674 }
5675 SiS_SetReg(SISSR, 0x18, v1);
5676 SiS_SetReg(SISSR, 0x19, 0x01);
5677 if(ivideo->chip == XGI_40) {
5678 SiS_SetReg(SISSR, 0x16, bios[0x53e]);
5679 SiS_SetReg(SISSR, 0x16, bios[0x53f]);
5680 } else {
5681 SiS_SetReg(SISSR, 0x16, 0x05);
5682 SiS_SetReg(SISSR, 0x16, 0x85);
5683 }
5684 sisfb_post_xgi_delay(ivideo, 0x43);
5685 if(ivideo->chip == XGI_40) {
5686 SiS_SetReg(SISSR, 0x1b, 0x01);
5687 } else {
5688 SiS_SetReg(SISSR, 0x1b, 0x03);
5689 }
5690 sisfb_post_xgi_delay(ivideo, 0x22);
5691 SiS_SetReg(SISSR, 0x18, v1);
5692 SiS_SetReg(SISSR, 0x19, 0x00);
5693 if(ivideo->chip == XGI_40) {
5694 SiS_SetReg(SISSR, 0x16, bios[0x540]);
5695 SiS_SetReg(SISSR, 0x16, bios[0x541]);
5696 } else {
5697 SiS_SetReg(SISSR, 0x16, 0x05);
5698 SiS_SetReg(SISSR, 0x16, 0x85);
5699 }
5700 SiS_SetReg(SISSR, 0x1b, 0x00);
5701 }
5702
5703 regb = 0; /* ! */
5704 v1 = 0x03;
5705 if(ivideo->haveXGIROM) {
5706 v1 = bios[0x110 + regb];
5707 }
5708 SiS_SetReg(SISSR, 0x1b, v1);
5709
5710 /* RAM size */
5711 v1 = 0x00; v2 = 0x00;
5712 if(ivideo->haveXGIROM) {
5713 v1 = bios[0x62];
5714 v2 = bios[0x63];
5715 }
5716 regb = 0; /* ! */
5717 regd = 1 << regb;
5718 if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) {
5719
5720 SiS_SetReg(SISSR, 0x13, bios[regb + 0xe0]);
5721 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5722
5723 } else {
5724 int err;
5725
5726 /* Set default mode, don't clear screen */
5727 ivideo->SiS_Pr.SiS_UseOEM = false;
5728 SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
5729 SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
5730 ivideo->curFSTN = ivideo->curDSTN = 0;
5731 ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
5732 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
5733
5734 SiS_SetReg(SISSR, 0x05, 0x86);
5735
5736 /* Disable read-cache */
5737 SiS_SetRegAND(SISSR, 0x21, 0xdf);
5738 err = sisfb_post_xgi_ramsize(ivideo);
5739 /* Enable read-cache */
5740 SiS_SetRegOR(SISSR, 0x21, 0x20);
5741
5742 if (err) {
5743 dev_err(&pdev->dev,
5744 "%s: RAM size detection failed: %d\n",
5745 __func__, err);
5746 return 0;
5747 }
5748 }
5749
5750#if 0
5751 printk(KERN_DEBUG "-----------------\n");
5752 for(i = 0; i < 0xff; i++) {
5753 reg = SiS_GetReg(SISCR, i);
5754 printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg);
5755 }
5756 for(i = 0; i < 0x40; i++) {
5757 reg = SiS_GetReg(SISSR, i);
5758 printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg);
5759 }
5760 printk(KERN_DEBUG "-----------------\n");
5761#endif
5762
5763 /* Sense CRT1 */
5764 if(ivideo->chip == XGI_20) {
5765 SiS_SetRegOR(SISCR, 0x32, 0x20);
5766 } else {
5767 reg = SiS_GetReg(SISPART4, 0x00);
5768 if((reg == 1) || (reg == 2)) {
5769 sisfb_sense_crt1(ivideo);
5770 } else {
5771 SiS_SetRegOR(SISCR, 0x32, 0x20);
5772 }
5773 }
5774
5775 /* Set default mode, don't clear screen */
5776 ivideo->SiS_Pr.SiS_UseOEM = false;
5777 SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
5778 SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
5779 ivideo->curFSTN = ivideo->curDSTN = 0;
5780 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
5781
5782 SiS_SetReg(SISSR, 0x05, 0x86);
5783
5784 /* Display off */
5785 SiS_SetRegOR(SISSR, 0x01, 0x20);
5786
5787 /* Save mode number in CR34 */
5788 SiS_SetReg(SISCR, 0x34, 0x2e);
5789
5790 /* Let everyone know what the current mode is */
5791 ivideo->modeprechange = 0x2e;
5792
5793 if(ivideo->chip == XGI_40) {
5794 reg = SiS_GetReg(SISCR, 0xca);
5795 v1 = SiS_GetReg(SISCR, 0xcc);
5796 if((reg & 0x10) && (!(v1 & 0x04))) {
5797 printk(KERN_ERR
5798 "sisfb: Please connect power to the card.\n");
5799 return 0;
5800 }
5801 }
5802
5803 return 1;
5804}
5805#endif
5806
5807static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5808{
5809 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
5810 struct sis_video_info *ivideo = NULL;
5811 struct fb_info *sis_fb_info = NULL;
5812 u16 reg16;
5813 u8 reg;
5814 int i, ret;
5815
5816 if(sisfb_off)
5817 return -ENXIO;
5818
5819 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
5820 if(!sis_fb_info)
5821 return -ENOMEM;
5822
5823 ivideo = (struct sis_video_info *)sis_fb_info->par;
5824 ivideo->memyselfandi = sis_fb_info;
5825
5826 ivideo->sisfb_id = SISFB_ID;
5827
5828 if(card_list == NULL) {
5829 ivideo->cardnumber = 0;
5830 } else {
5831 struct sis_video_info *countvideo = card_list;
5832 ivideo->cardnumber = 1;
5833 while((countvideo = countvideo->next) != NULL)
5834 ivideo->cardnumber++;
5835 }
5836
5837 strncpy(ivideo->myid, chipinfo->chip_name, 30);
5838
5839 ivideo->warncount = 0;
5840 ivideo->chip_id = pdev->device;
5841 ivideo->chip_vendor = pdev->vendor;
5842 ivideo->revision_id = pdev->revision;
5843 ivideo->SiS_Pr.ChipRevision = ivideo->revision_id;
5844 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
5845 ivideo->sisvga_enabled = reg16 & 0x01;
5846 ivideo->pcibus = pdev->bus->number;
5847 ivideo->pcislot = PCI_SLOT(pdev->devfn);
5848 ivideo->pcifunc = PCI_FUNC(pdev->devfn);
5849 ivideo->subsysvendor = pdev->subsystem_vendor;
5850 ivideo->subsysdevice = pdev->subsystem_device;
5851
5852#ifndef MODULE
5853 if(sisfb_mode_idx == -1) {
5854 sisfb_get_vga_mode_from_kernel();
5855 }
5856#endif
5857
5858 ivideo->chip = chipinfo->chip;
5859 ivideo->chip_real_id = chipinfo->chip;
5860 ivideo->sisvga_engine = chipinfo->vgaengine;
5861 ivideo->hwcursor_size = chipinfo->hwcursor_size;
5862 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
5863 ivideo->mni = chipinfo->mni;
5864
5865 ivideo->detectedpdc = 0xff;
5866 ivideo->detectedpdca = 0xff;
5867 ivideo->detectedlcda = 0xff;
5868
5869 ivideo->sisfb_thismonitor.datavalid = false;
5870
5871 ivideo->current_base = 0;
5872
5873 ivideo->engineok = 0;
5874
5875 ivideo->sisfb_was_boot_device = 0;
5876
5877 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) {
5878 if(ivideo->sisvga_enabled)
5879 ivideo->sisfb_was_boot_device = 1;
5880 else {
5881 printk(KERN_DEBUG "sisfb: PCI device is disabled, "
5882 "but marked as boot video device ???\n");
5883 printk(KERN_DEBUG "sisfb: I will not accept this "
5884 "as the primary VGA device\n");
5885 }
5886 }
5887
5888 ivideo->sisfb_parm_mem = sisfb_parm_mem;
5889 ivideo->sisfb_accel = sisfb_accel;
5890 ivideo->sisfb_ypan = sisfb_ypan;
5891 ivideo->sisfb_max = sisfb_max;
5892 ivideo->sisfb_userom = sisfb_userom;
5893 ivideo->sisfb_useoem = sisfb_useoem;
5894 ivideo->sisfb_mode_idx = sisfb_mode_idx;
5895 ivideo->sisfb_parm_rate = sisfb_parm_rate;
5896 ivideo->sisfb_crt1off = sisfb_crt1off;
5897 ivideo->sisfb_forcecrt1 = sisfb_forcecrt1;
5898 ivideo->sisfb_crt2type = sisfb_crt2type;
5899 ivideo->sisfb_crt2flags = sisfb_crt2flags;
5900 /* pdc(a), scalelcd, special timing, lvdshl handled below */
5901 ivideo->sisfb_dstn = sisfb_dstn;
5902 ivideo->sisfb_fstn = sisfb_fstn;
5903 ivideo->sisfb_tvplug = sisfb_tvplug;
5904 ivideo->sisfb_tvstd = sisfb_tvstd;
5905 ivideo->tvxpos = sisfb_tvxposoffset;
5906 ivideo->tvypos = sisfb_tvyposoffset;
5907 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
5908 ivideo->refresh_rate = 0;
5909 if(ivideo->sisfb_parm_rate != -1) {
5910 ivideo->refresh_rate = ivideo->sisfb_parm_rate;
5911 }
5912
5913 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
5914 ivideo->SiS_Pr.CenterScreen = -1;
5915 ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming;
5916 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
5917
5918 ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
5919 ivideo->SiS_Pr.SiS_CHOverScan = -1;
5920 ivideo->SiS_Pr.SiS_ChSW = false;
5921 ivideo->SiS_Pr.SiS_UseLCDA = false;
5922 ivideo->SiS_Pr.HaveEMI = false;
5923 ivideo->SiS_Pr.HaveEMILCD = false;
5924 ivideo->SiS_Pr.OverruleEMI = false;
5925 ivideo->SiS_Pr.SiS_SensibleSR11 = false;
5926 ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
5927 ivideo->SiS_Pr.PDC = -1;
5928 ivideo->SiS_Pr.PDCA = -1;
5929 ivideo->SiS_Pr.DDCPortMixup = false;
5930#ifdef CONFIG_FB_SIS_315
5931 if(ivideo->chip >= SIS_330) {
5932 ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
5933 if(ivideo->chip >= SIS_661) {
5934 ivideo->SiS_Pr.SiS_SensibleSR11 = true;
5935 }
5936 }
5937#endif
5938
5939 memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var));
5940
5941 pci_set_drvdata(pdev, ivideo);
5942
5943 /* Patch special cases */
5944 if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) {
5945 switch(ivideo->nbridge->device) {
5946#ifdef CONFIG_FB_SIS_300
5947 case PCI_DEVICE_ID_SI_730:
5948 ivideo->chip = SIS_730;
5949 strcpy(ivideo->myid, "SiS 730");
5950 break;
5951#endif
5952#ifdef CONFIG_FB_SIS_315
5953 case PCI_DEVICE_ID_SI_651:
5954 /* ivideo->chip is ok */
5955 strcpy(ivideo->myid, "SiS 651");
5956 break;
5957 case PCI_DEVICE_ID_SI_740:
5958 ivideo->chip = SIS_740;
5959 strcpy(ivideo->myid, "SiS 740");
5960 break;
5961 case PCI_DEVICE_ID_SI_661:
5962 ivideo->chip = SIS_661;
5963 strcpy(ivideo->myid, "SiS 661");
5964 break;
5965 case PCI_DEVICE_ID_SI_741:
5966 ivideo->chip = SIS_741;
5967 strcpy(ivideo->myid, "SiS 741");
5968 break;
5969 case PCI_DEVICE_ID_SI_760:
5970 ivideo->chip = SIS_760;
5971 strcpy(ivideo->myid, "SiS 760");
5972 break;
5973 case PCI_DEVICE_ID_SI_761:
5974 ivideo->chip = SIS_761;
5975 strcpy(ivideo->myid, "SiS 761");
5976 break;
5977#endif
5978 default:
5979 break;
5980 }
5981 }
5982
5983 ivideo->SiS_Pr.ChipType = ivideo->chip;
5984
5985 ivideo->SiS_Pr.ivideo = (void *)ivideo;
5986
5987#ifdef CONFIG_FB_SIS_315
5988 if((ivideo->SiS_Pr.ChipType == SIS_315PRO) ||
5989 (ivideo->SiS_Pr.ChipType == SIS_315)) {
5990 ivideo->SiS_Pr.ChipType = SIS_315H;
5991 }
5992#endif
5993
5994 if(!ivideo->sisvga_enabled) {
5995 if(pci_enable_device(pdev)) {
5996 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
5997 framebuffer_release(sis_fb_info);
5998 return -EIO;
5999 }
6000 }
6001
6002 ivideo->video_base = pci_resource_start(pdev, 0);
6003 ivideo->video_size = pci_resource_len(pdev, 0);
6004 ivideo->mmio_base = pci_resource_start(pdev, 1);
6005 ivideo->mmio_size = pci_resource_len(pdev, 1);
6006 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
6007 ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
6008
6009 SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress);
6010
6011#ifdef CONFIG_FB_SIS_300
6012 /* Find PCI systems for Chrontel/GPIO communication setup */
6013 if(ivideo->chip == SIS_630) {
6014 i = 0;
6015 do {
6016 if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
6017 mychswtable[i].subsysCard == ivideo->subsysdevice) {
6018 ivideo->SiS_Pr.SiS_ChSW = true;
6019 printk(KERN_DEBUG "sisfb: Identified [%s %s] "
6020 "requiring Chrontel/GPIO setup\n",
6021 mychswtable[i].vendorName,
6022 mychswtable[i].cardName);
6023 ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL);
6024 break;
6025 }
6026 i++;
6027 } while(mychswtable[i].subsysVendor != 0);
6028 }
6029#endif
6030
6031#ifdef CONFIG_FB_SIS_315
6032 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
6033 ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3));
6034 }
6035#endif
6036
6037 SiS_SetReg(SISSR, 0x05, 0x86);
6038
6039 if( (!ivideo->sisvga_enabled)
6040#if !defined(__i386__) && !defined(__x86_64__)
6041 || (sisfb_resetcard)
6042#endif
6043 ) {
6044 for(i = 0x30; i <= 0x3f; i++) {
6045 SiS_SetReg(SISCR, i, 0x00);
6046 }
6047 }
6048
6049 /* Find out about current video mode */
6050 ivideo->modeprechange = 0x03;
6051 reg = SiS_GetReg(SISCR, 0x34);
6052 if(reg & 0x7f) {
6053 ivideo->modeprechange = reg & 0x7f;
6054 } else if(ivideo->sisvga_enabled) {
6055#if defined(__i386__) || defined(__x86_64__)
6056 unsigned char __iomem *tt = ioremap(0x400, 0x100);
6057 if(tt) {
6058 ivideo->modeprechange = readb(tt + 0x49);
6059 iounmap(tt);
6060 }
6061#endif
6062 }
6063
6064 /* Search and copy ROM image */
6065 ivideo->bios_abase = NULL;
6066 ivideo->SiS_Pr.VirtualRomBase = NULL;
6067 ivideo->SiS_Pr.UseROM = false;
6068 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = false;
6069 if(ivideo->sisfb_userom) {
6070 ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
6071 ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase;
6072 ivideo->SiS_Pr.UseROM = (bool)(ivideo->SiS_Pr.VirtualRomBase);
6073 printk(KERN_INFO "sisfb: Video ROM %sfound\n",
6074 ivideo->SiS_Pr.UseROM ? "" : "not ");
6075 if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) {
6076 ivideo->SiS_Pr.UseROM = false;
6077 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = true;
6078 if( (ivideo->revision_id == 2) &&
6079 (!(ivideo->bios_abase[0x1d1] & 0x01)) ) {
6080 ivideo->SiS_Pr.DDCPortMixup = true;
6081 }
6082 }
6083 } else {
6084 printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
6085 }
6086
6087 /* Find systems for special custom timing */
6088 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
6089 sisfb_detect_custom_timing(ivideo);
6090 }
6091
6092#ifdef CONFIG_FB_SIS_315
6093 if (ivideo->chip == XGI_20) {
6094 /* Check if our Z7 chip is actually Z9 */
6095 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
6096 reg = SiS_GetReg(SISCR, 0x48);
6097 if (reg & 0x02) { /* GPIOG */
6098 ivideo->chip_real_id = XGI_21;
6099 dev_info(&pdev->dev, "Z9 detected\n");
6100 }
6101 }
6102#endif
6103
6104 /* POST card in case this has not been done by the BIOS */
6105 if( (!ivideo->sisvga_enabled)
6106#if !defined(__i386__) && !defined(__x86_64__)
6107 || (sisfb_resetcard)
6108#endif
6109 ) {
6110#ifdef CONFIG_FB_SIS_300
6111 if(ivideo->sisvga_engine == SIS_300_VGA) {
6112 if(ivideo->chip == SIS_300) {
6113 sisfb_post_sis300(pdev);
6114 ivideo->sisfb_can_post = 1;
6115 }
6116 }
6117#endif
6118
6119#ifdef CONFIG_FB_SIS_315
6120 if(ivideo->sisvga_engine == SIS_315_VGA) {
6121 int result = 1;
6122 /* if((ivideo->chip == SIS_315H) ||
6123 (ivideo->chip == SIS_315) ||
6124 (ivideo->chip == SIS_315PRO) ||
6125 (ivideo->chip == SIS_330)) {
6126 sisfb_post_sis315330(pdev);
6127 } else */ if(ivideo->chip == XGI_20) {
6128 result = sisfb_post_xgi(pdev);
6129 ivideo->sisfb_can_post = 1;
6130 } else if((ivideo->chip == XGI_40) && ivideo->haveXGIROM) {
6131 result = sisfb_post_xgi(pdev);
6132 ivideo->sisfb_can_post = 1;
6133 } else {
6134 printk(KERN_INFO "sisfb: Card is not "
6135 "POSTed and sisfb can't do this either.\n");
6136 }
6137 if(!result) {
6138 printk(KERN_ERR "sisfb: Failed to POST card\n");
6139 ret = -ENODEV;
6140 goto error_3;
6141 }
6142 }
6143#endif
6144 }
6145
6146 ivideo->sisfb_card_posted = 1;
6147
6148 /* Find out about RAM size */
6149 if(sisfb_get_dram_size(ivideo)) {
6150 printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n");
6151 ret = -ENODEV;
6152 goto error_3;
6153 }
6154
6155
6156 /* Enable PCI addressing and MMIO */
6157 if((ivideo->sisfb_mode_idx < 0) ||
6158 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
6159 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
6160 SiS_SetRegOR(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
6161 /* Enable 2D accelerator engine */
6162 SiS_SetRegOR(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
6163 }
6164
6165 if(sisfb_pdc != 0xff) {
6166 if(ivideo->sisvga_engine == SIS_300_VGA)
6167 sisfb_pdc &= 0x3c;
6168 else
6169 sisfb_pdc &= 0x1f;
6170 ivideo->SiS_Pr.PDC = sisfb_pdc;
6171 }
6172#ifdef CONFIG_FB_SIS_315
6173 if(ivideo->sisvga_engine == SIS_315_VGA) {
6174 if(sisfb_pdca != 0xff)
6175 ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
6176 }
6177#endif
6178
6179 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
6180 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n",
6181 (int)(ivideo->video_size >> 20));
6182 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
6183 ret = -ENODEV;
6184 goto error_3;
6185 }
6186
6187 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
6188 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
6189 ret = -ENODEV;
6190 goto error_2;
6191 }
6192
6193 ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size);
6194 ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase;
6195 if(!ivideo->video_vbase) {
6196 printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
6197 ret = -ENODEV;
6198 goto error_1;
6199 }
6200
6201 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size);
6202 if(!ivideo->mmio_vbase) {
6203 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
6204 ret = -ENODEV;
6205error_0: iounmap(ivideo->video_vbase);
6206error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
6207error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6208error_3: vfree(ivideo->bios_abase);
6209 if(ivideo->lpcdev)
6210 pci_dev_put(ivideo->lpcdev);
6211 if(ivideo->nbridge)
6212 pci_dev_put(ivideo->nbridge);
6213 if(!ivideo->sisvga_enabled)
6214 pci_disable_device(pdev);
6215 framebuffer_release(sis_fb_info);
6216 return ret;
6217 }
6218
6219 printk(KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n",
6220 ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024);
6221
6222 if(ivideo->video_offset) {
6223 printk(KERN_INFO "sisfb: Viewport offset %ldk\n",
6224 ivideo->video_offset / 1024);
6225 }
6226
6227 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
6228 ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
6229
6230
6231 /* Determine the size of the command queue */
6232 if(ivideo->sisvga_engine == SIS_300_VGA) {
6233 ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE;
6234 } else {
6235 if(ivideo->chip == XGI_20) {
6236 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7;
6237 } else {
6238 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE;
6239 }
6240 }
6241
6242 /* Engines are no longer initialized here; this is
6243 * now done after the first mode-switch (if the
6244 * submitted var has its acceleration flags set).
6245 */
6246
6247 /* Calculate the base of the (unused) hw cursor */
6248 ivideo->hwcursor_vbase = ivideo->video_vbase
6249 + ivideo->video_size
6250 - ivideo->cmdQueueSize
6251 - ivideo->hwcursor_size;
6252 ivideo->caps |= HW_CURSOR_CAP;
6253
6254 /* Initialize offscreen memory manager */
6255 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
6256 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
6257 }
6258
6259 /* Used for clearing the screen only, therefore respect our mem limit */
6260 ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset;
6261 ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem;
6262
6263 ivideo->mtrr = -1;
6264
6265 ivideo->vbflags = 0;
6266 ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
6267 ivideo->tvdefmodeidx = DEFAULT_TVMODE;
6268 ivideo->defmodeidx = DEFAULT_MODE;
6269
6270 ivideo->newrom = 0;
6271 if(ivideo->chip < XGI_20) {
6272 if(ivideo->bios_abase) {
6273 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr);
6274 }
6275 }
6276
6277 if((ivideo->sisfb_mode_idx < 0) ||
6278 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
6279
6280 sisfb_sense_crt1(ivideo);
6281
6282 sisfb_get_VB_type(ivideo);
6283
6284 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
6285 sisfb_detect_VB_connect(ivideo);
6286 }
6287
6288 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
6289
6290 /* Decide on which CRT2 device to use */
6291 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
6292 if(ivideo->sisfb_crt2type != -1) {
6293 if((ivideo->sisfb_crt2type == CRT2_LCD) &&
6294 (ivideo->vbflags & CRT2_LCD)) {
6295 ivideo->currentvbflags |= CRT2_LCD;
6296 } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
6297 ivideo->currentvbflags |= ivideo->sisfb_crt2type;
6298 }
6299 } else {
6300 /* Chrontel 700x TV detection often unreliable, therefore
6301 * use a different default order on such machines
6302 */
6303 if((ivideo->sisvga_engine == SIS_300_VGA) &&
6304 (ivideo->vbflags2 & VB2_CHRONTEL)) {
6305 if(ivideo->vbflags & CRT2_LCD)
6306 ivideo->currentvbflags |= CRT2_LCD;
6307 else if(ivideo->vbflags & CRT2_TV)
6308 ivideo->currentvbflags |= CRT2_TV;
6309 else if(ivideo->vbflags & CRT2_VGA)
6310 ivideo->currentvbflags |= CRT2_VGA;
6311 } else {
6312 if(ivideo->vbflags & CRT2_TV)
6313 ivideo->currentvbflags |= CRT2_TV;
6314 else if(ivideo->vbflags & CRT2_LCD)
6315 ivideo->currentvbflags |= CRT2_LCD;
6316 else if(ivideo->vbflags & CRT2_VGA)
6317 ivideo->currentvbflags |= CRT2_VGA;
6318 }
6319 }
6320 }
6321
6322 if(ivideo->vbflags & CRT2_LCD) {
6323 sisfb_detect_lcd_type(ivideo);
6324 }
6325
6326 sisfb_save_pdc_emi(ivideo);
6327
6328 if(!ivideo->sisfb_crt1off) {
6329 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
6330 } else {
6331 if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) &&
6332 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
6333 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
6334 }
6335 }
6336
6337 if(ivideo->sisfb_mode_idx >= 0) {
6338 int bu = ivideo->sisfb_mode_idx;
6339 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
6340 ivideo->sisfb_mode_idx, ivideo->currentvbflags);
6341 if(bu != ivideo->sisfb_mode_idx) {
6342 printk(KERN_ERR "Mode %dx%dx%d failed validation\n",
6343 sisbios_mode[bu].xres,
6344 sisbios_mode[bu].yres,
6345 sisbios_mode[bu].bpp);
6346 }
6347 }
6348
6349 if(ivideo->sisfb_mode_idx < 0) {
6350 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
6351 case CRT2_LCD:
6352 ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx;
6353 break;
6354 case CRT2_TV:
6355 ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx;
6356 break;
6357 default:
6358 ivideo->sisfb_mode_idx = ivideo->defmodeidx;
6359 break;
6360 }
6361 }
6362
6363 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
6364
6365 if(ivideo->refresh_rate != 0) {
6366 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate,
6367 ivideo->sisfb_mode_idx);
6368 }
6369
6370 if(ivideo->rate_idx == 0) {
6371 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
6372 ivideo->refresh_rate = 60;
6373 }
6374
6375 if(ivideo->sisfb_thismonitor.datavalid) {
6376 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor,
6377 ivideo->sisfb_mode_idx,
6378 ivideo->rate_idx,
6379 ivideo->refresh_rate)) {
6380 printk(KERN_INFO "sisfb: WARNING: Refresh rate "
6381 "exceeds monitor specs!\n");
6382 }
6383 }
6384
6385 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
6386 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
6387 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
6388
6389 sisfb_set_vparms(ivideo);
6390
6391 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
6392 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
6393 ivideo->refresh_rate);
6394
6395 /* Set up the default var according to chosen default display mode */
6396 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
6397 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
6398 ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
6399
6400 sisfb_bpp_to_var(ivideo, &ivideo->default_var);
6401
6402 ivideo->default_var.pixclock = (u32) (1000000000 /
6403 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx));
6404
6405 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no,
6406 ivideo->rate_idx, &ivideo->default_var)) {
6407 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
6408 ivideo->default_var.pixclock <<= 1;
6409 }
6410 }
6411
6412 if(ivideo->sisfb_ypan) {
6413 /* Maximize regardless of sisfb_max at startup */
6414 ivideo->default_var.yres_virtual =
6415 sisfb_calc_maxyres(ivideo, &ivideo->default_var);
6416 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
6417 ivideo->default_var.yres_virtual = ivideo->default_var.yres;
6418 }
6419 }
6420
6421 sisfb_calc_pitch(ivideo, &ivideo->default_var);
6422
6423 ivideo->accel = 0;
6424 if(ivideo->sisfb_accel) {
6425 ivideo->accel = -1;
6426#ifdef STUPID_ACCELF_TEXT_SHIT
6427 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
6428#endif
6429 }
6430 sisfb_initaccel(ivideo);
6431
6432#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
6433 sis_fb_info->flags = FBINFO_DEFAULT |
6434 FBINFO_HWACCEL_YPAN |
6435 FBINFO_HWACCEL_XPAN |
6436 FBINFO_HWACCEL_COPYAREA |
6437 FBINFO_HWACCEL_FILLRECT |
6438 ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED);
6439#else
6440 sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
6441#endif
6442 sis_fb_info->var = ivideo->default_var;
6443 sis_fb_info->fix = ivideo->sisfb_fix;
6444 sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
6445 sis_fb_info->fbops = &sisfb_ops;
6446 sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
6447
6448 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
6449
6450 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
6451
6452#ifdef CONFIG_MTRR
6453 ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
6454 MTRR_TYPE_WRCOMB, 1);
6455 if(ivideo->mtrr < 0) {
6456 printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
6457 }
6458#endif
6459
6460 if(register_framebuffer(sis_fb_info) < 0) {
6461 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
6462 ret = -EINVAL;
6463 iounmap(ivideo->mmio_vbase);
6464 goto error_0;
6465 }
6466
6467 ivideo->registered = 1;
6468
6469 /* Enlist us */
6470 ivideo->next = card_list;
6471 card_list = ivideo;
6472
6473 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
6474 ivideo->sisfb_accel ? "enabled" : "disabled",
6475 ivideo->sisfb_ypan ?
6476 (ivideo->sisfb_max ? "enabled (auto-max)" :
6477 "enabled (no auto-max)") :
6478 "disabled");
6479
6480
6481 fb_info(sis_fb_info, "%s frame buffer device version %d.%d.%d\n",
6482 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
6483
6484 printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
6485
6486 } /* if mode = "none" */
6487
6488 return 0;
6489}
6490
6491/*****************************************************/
6492/* PCI DEVICE HANDLING */
6493/*****************************************************/
6494
6495static void sisfb_remove(struct pci_dev *pdev)
6496{
6497 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
6498 struct fb_info *sis_fb_info = ivideo->memyselfandi;
6499 int registered = ivideo->registered;
6500 int modechanged = ivideo->modechanged;
6501
6502 /* Unmap */
6503 iounmap(ivideo->mmio_vbase);
6504 iounmap(ivideo->video_vbase);
6505
6506 /* Release mem regions */
6507 release_mem_region(ivideo->video_base, ivideo->video_size);
6508 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6509
6510 vfree(ivideo->bios_abase);
6511
6512 if(ivideo->lpcdev)
6513 pci_dev_put(ivideo->lpcdev);
6514
6515 if(ivideo->nbridge)
6516 pci_dev_put(ivideo->nbridge);
6517
6518#ifdef CONFIG_MTRR
6519 /* Release MTRR region */
6520 if(ivideo->mtrr >= 0)
6521 mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
6522#endif
6523
6524 /* If device was disabled when starting, disable
6525 * it when quitting.
6526 */
6527 if(!ivideo->sisvga_enabled)
6528 pci_disable_device(pdev);
6529
6530 /* Unregister the framebuffer */
6531 if(ivideo->registered) {
6532 unregister_framebuffer(sis_fb_info);
6533 framebuffer_release(sis_fb_info);
6534 }
6535
6536 /* OK, our ivideo is gone for good from here. */
6537
6538 /* TODO: Restore the initial mode
6539 * This sounds easy but is as good as impossible
6540 * on many machines with SiS chip and video bridge
6541 * since text modes are always set up differently
6542 * from machine to machine. Depends on the type
6543 * of integration between chipset and bridge.
6544 */
6545 if(registered && modechanged)
6546 printk(KERN_INFO
6547 "sisfb: Restoring of text mode not supported yet\n");
6548};
6549
6550static struct pci_driver sisfb_driver = {
6551 .name = "sisfb",
6552 .id_table = sisfb_pci_table,
6553 .probe = sisfb_probe,
6554 .remove = sisfb_remove,
6555};
6556
6557static int __init sisfb_init(void)
6558{
6559#ifndef MODULE
6560 char *options = NULL;
6561
6562 if(fb_get_options("sisfb", &options))
6563 return -ENODEV;
6564
6565 sisfb_setup(options);
6566#endif
6567 return pci_register_driver(&sisfb_driver);
6568}
6569
6570#ifndef MODULE
6571module_init(sisfb_init);
6572#endif
6573
6574/*****************************************************/
6575/* MODULE */
6576/*****************************************************/
6577
6578#ifdef MODULE
6579
6580static char *mode = NULL;
6581static int vesa = -1;
6582static unsigned int rate = 0;
6583static unsigned int crt1off = 1;
6584static unsigned int mem = 0;
6585static char *forcecrt2type = NULL;
6586static int forcecrt1 = -1;
6587static int pdc = -1;
6588static int pdc1 = -1;
6589static int noaccel = -1;
6590static int noypan = -1;
6591static int nomax = -1;
6592static int userom = -1;
6593static int useoem = -1;
6594static char *tvstandard = NULL;
6595static int nocrt2rate = 0;
6596static int scalelcd = -1;
6597static char *specialtiming = NULL;
6598static int lvdshl = -1;
6599static int tvxposoffset = 0, tvyposoffset = 0;
6600#if !defined(__i386__) && !defined(__x86_64__)
6601static int resetcard = 0;
6602static int videoram = 0;
6603#endif
6604
6605static int __init sisfb_init_module(void)
6606{
6607 sisfb_setdefaultparms();
6608
6609 if(rate)
6610 sisfb_parm_rate = rate;
6611
6612 if((scalelcd == 0) || (scalelcd == 1))
6613 sisfb_scalelcd = scalelcd ^ 1;
6614
6615 /* Need to check crt2 type first for fstn/dstn */
6616
6617 if(forcecrt2type)
6618 sisfb_search_crt2type(forcecrt2type);
6619
6620 if(tvstandard)
6621 sisfb_search_tvstd(tvstandard);
6622
6623 if(mode)
6624 sisfb_search_mode(mode, false);
6625 else if(vesa != -1)
6626 sisfb_search_vesamode(vesa, false);
6627
6628 sisfb_crt1off = (crt1off == 0) ? 1 : 0;
6629
6630 sisfb_forcecrt1 = forcecrt1;
6631 if(forcecrt1 == 1)
6632 sisfb_crt1off = 0;
6633 else if(forcecrt1 == 0)
6634 sisfb_crt1off = 1;
6635
6636 if(noaccel == 1)
6637 sisfb_accel = 0;
6638 else if(noaccel == 0)
6639 sisfb_accel = 1;
6640
6641 if(noypan == 1)
6642 sisfb_ypan = 0;
6643 else if(noypan == 0)
6644 sisfb_ypan = 1;
6645
6646 if(nomax == 1)
6647 sisfb_max = 0;
6648 else if(nomax == 0)
6649 sisfb_max = 1;
6650
6651 if(mem)
6652 sisfb_parm_mem = mem;
6653
6654 if(userom != -1)
6655 sisfb_userom = userom;
6656
6657 if(useoem != -1)
6658 sisfb_useoem = useoem;
6659
6660 if(pdc != -1)
6661 sisfb_pdc = (pdc & 0x7f);
6662
6663 if(pdc1 != -1)
6664 sisfb_pdca = (pdc1 & 0x1f);
6665
6666 sisfb_nocrt2rate = nocrt2rate;
6667
6668 if(specialtiming)
6669 sisfb_search_specialtiming(specialtiming);
6670
6671 if((lvdshl >= 0) && (lvdshl <= 3))
6672 sisfb_lvdshl = lvdshl;
6673
6674 sisfb_tvxposoffset = tvxposoffset;
6675 sisfb_tvyposoffset = tvyposoffset;
6676
6677#if !defined(__i386__) && !defined(__x86_64__)
6678 sisfb_resetcard = (resetcard) ? 1 : 0;
6679 if(videoram)
6680 sisfb_videoram = videoram;
6681#endif
6682
6683 return sisfb_init();
6684}
6685
6686static void __exit sisfb_remove_module(void)
6687{
6688 pci_unregister_driver(&sisfb_driver);
6689 printk(KERN_DEBUG "sisfb: Module unloaded\n");
6690}
6691
6692module_init(sisfb_init_module);
6693module_exit(sisfb_remove_module);
6694
6695MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver");
6696MODULE_LICENSE("GPL");
6697MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
6698
6699module_param(mem, int, 0);
6700module_param(noaccel, int, 0);
6701module_param(noypan, int, 0);
6702module_param(nomax, int, 0);
6703module_param(userom, int, 0);
6704module_param(useoem, int, 0);
6705module_param(mode, charp, 0);
6706module_param(vesa, int, 0);
6707module_param(rate, int, 0);
6708module_param(forcecrt1, int, 0);
6709module_param(forcecrt2type, charp, 0);
6710module_param(scalelcd, int, 0);
6711module_param(pdc, int, 0);
6712module_param(pdc1, int, 0);
6713module_param(specialtiming, charp, 0);
6714module_param(lvdshl, int, 0);
6715module_param(tvstandard, charp, 0);
6716module_param(tvxposoffset, int, 0);
6717module_param(tvyposoffset, int, 0);
6718module_param(nocrt2rate, int, 0);
6719#if !defined(__i386__) && !defined(__x86_64__)
6720module_param(resetcard, int, 0);
6721module_param(videoram, int, 0);
6722#endif
6723
6724MODULE_PARM_DESC(mem,
6725 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
6726 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
6727 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
6728 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
6729 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
6730 "The value is to be specified without 'KB'.\n");
6731
6732MODULE_PARM_DESC(noaccel,
6733 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
6734 "(default: 0)\n");
6735
6736MODULE_PARM_DESC(noypan,
6737 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
6738 "will be performed by redrawing the screen. (default: 0)\n");
6739
6740MODULE_PARM_DESC(nomax,
6741 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
6742 "memory for the virtual screen in order to optimize scrolling performance. If\n"
6743 "this is set to anything other than 0, sisfb will not do this and thereby \n"
6744 "enable the user to positively specify a virtual Y size of the screen using\n"
6745 "fbset. (default: 0)\n");
6746
6747MODULE_PARM_DESC(mode,
6748 "\nSelects the desired default display mode in the format XxYxDepth,\n"
6749 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
6750 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
6751 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
6752
6753MODULE_PARM_DESC(vesa,
6754 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
6755 "0x117 (default: 0x0103)\n");
6756
6757MODULE_PARM_DESC(rate,
6758 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
6759 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
6760 "will be ignored (default: 60)\n");
6761
6762MODULE_PARM_DESC(forcecrt1,
6763 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
6764 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
6765 "0=CRT1 OFF) (default: [autodetected])\n");
6766
6767MODULE_PARM_DESC(forcecrt2type,
6768 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
6769 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
6770 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
6771 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
6772 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
6773 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
6774 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
6775 "depends on the very hardware in use. (default: [autodetected])\n");
6776
6777MODULE_PARM_DESC(scalelcd,
6778 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
6779 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
6780 "show black bars around the image, TMDS panels will probably do the scaling\n"
6781 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
6782
6783MODULE_PARM_DESC(pdc,
6784 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
6785 "should detect this correctly in most cases; however, sometimes this is not\n"
6786 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
6787 "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n"
6788 "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n"
6789 "value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
6790
6791#ifdef CONFIG_FB_SIS_315
6792MODULE_PARM_DESC(pdc1,
6793 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n"
6794 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
6795 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
6796 "implemented yet.\n");
6797#endif
6798
6799MODULE_PARM_DESC(specialtiming,
6800 "\nPlease refer to documentation for more information on this option.\n");
6801
6802MODULE_PARM_DESC(lvdshl,
6803 "\nPlease refer to documentation for more information on this option.\n");
6804
6805MODULE_PARM_DESC(tvstandard,
6806 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
6807 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
6808
6809MODULE_PARM_DESC(tvxposoffset,
6810 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
6811 "Default: 0\n");
6812
6813MODULE_PARM_DESC(tvyposoffset,
6814 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
6815 "Default: 0\n");
6816
6817MODULE_PARM_DESC(nocrt2rate,
6818 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
6819 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
6820
6821#if !defined(__i386__) && !defined(__x86_64__)
6822#ifdef CONFIG_FB_SIS_300
6823MODULE_PARM_DESC(resetcard,
6824 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
6825 "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n"
6826 "currently). Default: 0\n");
6827
6828MODULE_PARM_DESC(videoram,
6829 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
6830 "some non-x86 architectures where the memory auto detection fails. Only\n"
6831 "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n");
6832#endif
6833#endif
6834
6835#endif /* /MODULE */
6836
6837/* _GPL only for new symbols. */
6838EXPORT_SYMBOL(sis_malloc);
6839EXPORT_SYMBOL(sis_free);
6840EXPORT_SYMBOL_GPL(sis_malloc_new);
6841EXPORT_SYMBOL_GPL(sis_free_new);
6842
6843
6844
diff --git a/drivers/video/fbdev/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h
new file mode 100644
index 000000000000..32e23c209430
--- /dev/null
+++ b/drivers/video/fbdev/sis/sis_main.h
@@ -0,0 +1,781 @@
1/*
2 * SiS 300/305/540/630(S)/730(S),
3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
6 *
7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the named License,
12 * or any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
22 */
23
24#ifndef _SISFB_MAIN
25#define _SISFB_MAIN
26
27#include "vstruct.h"
28#include "sis.h"
29
30/* Fbcon stuff */
31static struct fb_var_screeninfo my_default_var = {
32 .xres = 0,
33 .yres = 0,
34 .xres_virtual = 0,
35 .yres_virtual = 0,
36 .xoffset = 0,
37 .yoffset = 0,
38 .bits_per_pixel = 0,
39 .grayscale = 0,
40 .red = {0, 8, 0},
41 .green = {0, 8, 0},
42 .blue = {0, 8, 0},
43 .transp = {0, 0, 0},
44 .nonstd = 0,
45 .activate = FB_ACTIVATE_NOW,
46 .height = -1,
47 .width = -1,
48 .accel_flags = 0,
49 .pixclock = 0,
50 .left_margin = 0,
51 .right_margin = 0,
52 .upper_margin = 0,
53 .lower_margin = 0,
54 .hsync_len = 0,
55 .vsync_len = 0,
56 .sync = 0,
57 .vmode = FB_VMODE_NONINTERLACED,
58};
59
60#define MODE_INDEX_NONE 0 /* index for mode=none */
61
62/* Boot-time parameters */
63static int sisfb_off = 0;
64static int sisfb_parm_mem = 0;
65static int sisfb_accel = -1;
66static int sisfb_ypan = -1;
67static int sisfb_max = -1;
68static int sisfb_userom = 1;
69static int sisfb_useoem = -1;
70static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
71static int sisfb_parm_rate = -1;
72static int sisfb_crt1off = 0;
73static int sisfb_forcecrt1 = -1;
74static int sisfb_crt2type = -1; /* CRT2 type (for overriding autodetection) */
75static int sisfb_crt2flags = 0;
76static int sisfb_pdc = 0xff;
77static int sisfb_pdca = 0xff;
78static int sisfb_scalelcd = -1;
79static int sisfb_specialtiming = CUT_NONE;
80static int sisfb_lvdshl = -1;
81static int sisfb_dstn = 0;
82static int sisfb_fstn = 0;
83static int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
84static int sisfb_tvstd = -1;
85static int sisfb_tvxposoffset = 0;
86static int sisfb_tvyposoffset = 0;
87static int sisfb_nocrt2rate = 0;
88#if !defined(__i386__) && !defined(__x86_64__)
89static int sisfb_resetcard = 0;
90static int sisfb_videoram = 0;
91#endif
92
93/* List of supported chips */
94static struct sisfb_chip_info {
95 int chip;
96 int vgaengine;
97 int mni;
98 int hwcursor_size;
99 int CRT2_write_enable;
100 const char *chip_name;
101} sisfb_chip_info[] = {
102 { SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
103 { SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
104 { SIS_630, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 630" },
105 { SIS_315H, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315H" },
106 { SIS_315, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315" },
107 { SIS_315PRO, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315PRO" },
108 { SIS_550, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 55x" },
109 { SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
110 { SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
111 { SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
112 { XGI_20, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI Z7" },
113 { XGI_40, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI V3XT/V5/V8" },
114};
115
116static struct pci_device_id sisfb_pci_table[] = {
117#ifdef CONFIG_FB_SIS_300
118 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
120 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
121#endif
122#ifdef CONFIG_FB_SIS_315
123 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
124 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
125 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
126 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
127 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
128 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
129 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
130 { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0,10},
131 { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0,11},
132#endif
133 { 0 }
134};
135
136MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
137
138static struct sis_video_info *card_list = NULL;
139
140/* The memory heap is now handled card-wise, by using
141 sis_malloc_new/sis_free_new. However, the DRM does
142 not do this yet. Until it does, we keep a "global"
143 heap which is actually the first card's one.
144 */
145static struct SIS_HEAP *sisfb_heap;
146
147#define MD_SIS300 1
148#define MD_SIS315 2
149
150/* Mode table */
151static const struct _sisbios_mode {
152 char name[15];
153 u8 mode_no[2];
154 u16 vesa_mode_no_1; /* "SiS defined" VESA mode number */
155 u16 vesa_mode_no_2; /* Real VESA mode numbers */
156 u16 xres;
157 u16 yres;
158 u16 bpp;
159 u16 rate_idx;
160 u16 cols;
161 u16 rows;
162 u8 chipset;
163} sisbios_mode[] = {
164/*0*/ {"none", {0xff,0xff}, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315},
165 {"320x200x8", {0x59,0x59}, 0x0138, 0x0000, 320, 200, 8, 1, 40, 12, MD_SIS300|MD_SIS315},
166 {"320x200x16", {0x41,0x41}, 0x010e, 0x0000, 320, 200, 16, 1, 40, 12, MD_SIS300|MD_SIS315},
167 {"320x200x24", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315}, /* That's for people who mix up color- and fb depth */
168 {"320x200x32", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315},
169 {"320x240x8", {0x50,0x50}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS300|MD_SIS315},
170 {"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
171 {"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
172 {"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
173#define MODE_FSTN_8 9
174#define MODE_FSTN_16 10
175 {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS315}, /* FSTN */
176/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS315}, /* FSTN */
177 {"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
178 {"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
179 {"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
180 {"400x300x32", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
181 {"512x384x8", {0x52,0x52}, 0x0000, 0x0000, 512, 384, 8, 1, 64, 24, MD_SIS300|MD_SIS315},
182 {"512x384x16", {0x58,0x58}, 0x0000, 0x0000, 512, 384, 16, 1, 64, 24, MD_SIS300|MD_SIS315},
183 {"512x384x24", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
184 {"512x384x32", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
185 {"640x400x8", {0x2f,0x2f}, 0x0000, 0x0000, 640, 400, 8, 1, 80, 25, MD_SIS300|MD_SIS315},
186/*20*/ {"640x400x16", {0x5d,0x5d}, 0x0000, 0x0000, 640, 400, 16, 1, 80, 25, MD_SIS300|MD_SIS315},
187 {"640x400x24", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
188 {"640x400x32", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
189 {"640x480x8", {0x2e,0x2e}, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
190 {"640x480x16", {0x44,0x44}, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_SIS300|MD_SIS315},
191 {"640x480x24", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
192 {"640x480x32", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
193 {"720x480x8", {0x31,0x31}, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_SIS300|MD_SIS315},
194 {"720x480x16", {0x33,0x33}, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_SIS300|MD_SIS315},
195 {"720x480x24", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
196/*30*/ {"720x480x32", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
197 {"720x576x8", {0x32,0x32}, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, MD_SIS300|MD_SIS315},
198 {"720x576x16", {0x34,0x34}, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_SIS300|MD_SIS315},
199 {"720x576x24", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
200 {"720x576x32", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
201 {"768x576x8", {0x5f,0x5f}, 0x0000, 0x0000, 768, 576, 8, 1, 96, 36, MD_SIS300|MD_SIS315},
202 {"768x576x16", {0x60,0x60}, 0x0000, 0x0000, 768, 576, 16, 1, 96, 36, MD_SIS300|MD_SIS315},
203 {"768x576x24", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
204 {"768x576x32", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
205 {"800x480x8", {0x70,0x70}, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_SIS300|MD_SIS315},
206/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
207 {"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
208 {"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
209#define DEFAULT_MODE 43 /* index for 800x600x8 */
210#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
211#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
212 {"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
213 {"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
214 {"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
215 {"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
216 {"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
217#define DEFAULT_MODE_848 48
218 {"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
219 {"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
220/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
221 {"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
222#define DEFAULT_MODE_856 52
223 {"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
224 {"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
225 {"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
226 {"960x540x8", {0x1d,0x1d}, 0x0000, 0x0000, 960, 540, 8, 1, 120, 33, MD_SIS315},
227 {"960x540x16", {0x1e,0x1e}, 0x0000, 0x0000, 960, 540, 16, 1, 120, 33, MD_SIS315},
228 {"960x540x24", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
229 {"960x540x32", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
230 {"960x600x8", {0x20,0x20}, 0x0000, 0x0000, 960, 600, 8, 1, 120, 37, MD_SIS315},
231/*60*/ {"960x600x16", {0x21,0x21}, 0x0000, 0x0000, 960, 600, 16, 1, 120, 37, MD_SIS315},
232 {"960x600x24", {0x22,0x22}, 0x0000, 0x0000, 960, 600, 32, 1, 120, 37, MD_SIS315},
233 {"960x600x32", {0x22,0x22}, 0x0000, 0x0000, 960, 600, 32, 1, 120, 37, MD_SIS315},
234 {"1024x576x8", {0x71,0x71}, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_SIS300|MD_SIS315},
235 {"1024x576x16", {0x74,0x74}, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
236 {"1024x576x24", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
237 {"1024x576x32", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
238 {"1024x600x8", {0x20,0x20}, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 },
239 {"1024x600x16", {0x21,0x21}, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_SIS300 },
240 {"1024x600x24", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
241/*70*/ {"1024x600x32", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
242 {"1024x768x8", {0x38,0x38}, 0x0105, 0x0105, 1024, 768, 8, 2, 128, 48, MD_SIS300|MD_SIS315},
243 {"1024x768x16", {0x4a,0x4a}, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
244 {"1024x768x24", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
245 {"1024x768x32", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
246 {"1152x768x8", {0x23,0x23}, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 },
247 {"1152x768x16", {0x24,0x24}, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_SIS300 },
248 {"1152x768x24", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
249 {"1152x768x32", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
250 {"1152x864x8", {0x29,0x29}, 0x0000, 0x0000, 1152, 864, 8, 1, 144, 54, MD_SIS300|MD_SIS315},
251/*80*/ {"1152x864x16", {0x2a,0x2a}, 0x0000, 0x0000, 1152, 864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
252 {"1152x864x24", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
253 {"1152x864x32", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
254 {"1280x720x8", {0x79,0x79}, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_SIS300|MD_SIS315},
255 {"1280x720x16", {0x75,0x75}, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
256 {"1280x720x24", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
257 {"1280x720x32", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
258 {"1280x768x8", {0x55,0x23}, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS300|MD_SIS315},
259 {"1280x768x16", {0x5a,0x24}, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
260 {"1280x768x24", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
261/*90*/ {"1280x768x32", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
262 {"1280x800x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 800, 8, 1, 160, 50, MD_SIS315},
263 {"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315},
264 {"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
265 {"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
266 {"1280x854x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 854, 8, 1, 160, 53, MD_SIS315},
267 {"1280x854x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 854, 16, 1, 160, 53, MD_SIS315},
268 {"1280x854x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
269 {"1280x854x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
270 {"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
271/*100*/ {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
272 {"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
273 {"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
274 {"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
275 {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
276 {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
277 {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
278 {"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
279 {"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
280 {"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
281/*110*/ {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
282 {"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
283#define DEFAULT_MODE_1360 112
284 {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
285 {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
286 {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
287 {"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
288 {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
289 {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
290 {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
291 {"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
292/*120*/ {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
293 {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
294 {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
295 {"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315},
296 {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
297 {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
298 {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
299 {"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315},
300 {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315},
301 {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
302/*130*/ {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
303 {"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
304 {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
305 {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
306 {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
307 {"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
308 {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
309 {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
310 {"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
311 {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
312};
313
314#define SIS_LCD_NUMBER 18
315static struct _sis_lcd_data {
316 u32 lcdtype;
317 u16 xres;
318 u16 yres;
319 u8 default_mode_idx;
320} sis_lcd_data[] = {
321 { LCD_640x480, 640, 480, 23 },
322 { LCD_800x600, 800, 600, 43 },
323 { LCD_1024x600, 1024, 600, 67 },
324 { LCD_1024x768, 1024, 768, 71 },
325 { LCD_1152x768, 1152, 768, 75 },
326 { LCD_1152x864, 1152, 864, 79 },
327 { LCD_1280x720, 1280, 720, 83 },
328 { LCD_1280x768, 1280, 768, 87 },
329 { LCD_1280x800, 1280, 800, 91 },
330 { LCD_1280x854, 1280, 854, 95 },
331 { LCD_1280x960, 1280, 960, 99 },
332 { LCD_1280x1024, 1280, 1024, 103 },
333 { LCD_1400x1050, 1400, 1050, 115 },
334 { LCD_1680x1050, 1680, 1050, 123 },
335 { LCD_1600x1200, 1600, 1200, 119 },
336 { LCD_320x240_2, 320, 240, 9 },
337 { LCD_320x240_3, 320, 240, 9 },
338 { LCD_320x240, 320, 240, 9 },
339};
340
341/* CR36 evaluation */
342static unsigned short sis300paneltype[] = {
343 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
344 LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
345 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
346 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN
347};
348
349static unsigned short sis310paneltype[] = {
350 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
351 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
352 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
353 LCD_320x240_2, LCD_320x240_3, LCD_UNKNOWN, LCD_UNKNOWN
354};
355
356static unsigned short sis661paneltype[] = {
357 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
358 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
359 LCD_1280x854, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
360 LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN
361};
362
363#define FL_550_DSTN 0x01
364#define FL_550_FSTN 0x02
365#define FL_300 0x04
366#define FL_315 0x08
367
368static struct _sis_crt2type {
369 char name[32];
370 u32 type_no;
371 u32 tvplug_no;
372 u16 flags;
373} sis_crt2type[] __initdata = {
374 {"NONE", 0, -1, FL_300|FL_315},
375 {"LCD", CRT2_LCD, -1, FL_300|FL_315},
376 {"TV", CRT2_TV, -1, FL_300|FL_315},
377 {"VGA", CRT2_VGA, -1, FL_300|FL_315},
378 {"SVIDEO", CRT2_TV, TV_SVIDEO, FL_300|FL_315},
379 {"COMPOSITE", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
380 {"CVBS", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
381 {"SVIDEO+COMPOSITE", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
382 {"COMPOSITE+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
383 {"SVIDEO+CVBS", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
384 {"CVBS+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
385 {"SCART", CRT2_TV, TV_SCART, FL_300|FL_315},
386 {"HIVISION", CRT2_TV, TV_HIVISION, FL_315},
387 {"YPBPR480I", CRT2_TV, TV_YPBPR|TV_YPBPR525I, FL_315},
388 {"YPBPR480P", CRT2_TV, TV_YPBPR|TV_YPBPR525P, FL_315},
389 {"YPBPR720P", CRT2_TV, TV_YPBPR|TV_YPBPR750P, FL_315},
390 {"YPBPR1080I", CRT2_TV, TV_YPBPR|TV_YPBPR1080I, FL_315},
391 {"DSTN", CRT2_LCD, -1, FL_315|FL_550_DSTN},
392 {"FSTN", CRT2_LCD, -1, FL_315|FL_550_FSTN},
393 {"\0", -1, -1, 0}
394};
395
396/* TV standard */
397static struct _sis_tvtype {
398 char name[6];
399 u32 type_no;
400} sis_tvtype[] __initdata = {
401 {"PAL", TV_PAL},
402 {"NTSC", TV_NTSC},
403 {"PALM", TV_PAL|TV_PALM},
404 {"PALN", TV_PAL|TV_PALN},
405 {"NTSCJ", TV_NTSC|TV_NTSCJ},
406 {"\0", -1}
407};
408
409static const struct _sis_vrate {
410 u16 idx;
411 u16 xres;
412 u16 yres;
413 u16 refresh;
414 bool SiS730valid32bpp;
415} sisfb_vrate[] = {
416 {1, 320, 200, 70, true},
417 {1, 320, 240, 60, true},
418 {1, 400, 300, 60, true},
419 {1, 512, 384, 60, true},
420 {1, 640, 400, 72, true},
421 {1, 640, 480, 60, true}, {2, 640, 480, 72, true}, {3, 640, 480, 75, true},
422 {4, 640, 480, 85, true}, {5, 640, 480, 100, true}, {6, 640, 480, 120, true},
423 {7, 640, 480, 160, true}, {8, 640, 480, 200, true},
424 {1, 720, 480, 60, true},
425 {1, 720, 576, 58, true},
426 {1, 768, 576, 58, true},
427 {1, 800, 480, 60, true}, {2, 800, 480, 75, true}, {3, 800, 480, 85, true},
428 {1, 800, 600, 56, true}, {2, 800, 600, 60, true}, {3, 800, 600, 72, true},
429 {4, 800, 600, 75, true}, {5, 800, 600, 85, true}, {6, 800, 600, 105, true},
430 {7, 800, 600, 120, true}, {8, 800, 600, 160, true},
431 {1, 848, 480, 39, true}, {2, 848, 480, 60, true},
432 {1, 856, 480, 39, true}, {2, 856, 480, 60, true},
433 {1, 960, 540, 60, true},
434 {1, 960, 600, 60, true},
435 {1, 1024, 576, 60, true}, {2, 1024, 576, 75, true}, {3, 1024, 576, 85, true},
436 {1, 1024, 600, 60, true},
437 {1, 1024, 768, 43, true}, {2, 1024, 768, 60, true}, {3, 1024, 768, 70, false},
438 {4, 1024, 768, 75, false}, {5, 1024, 768, 85, true}, {6, 1024, 768, 100, true},
439 {7, 1024, 768, 120, true},
440 {1, 1152, 768, 60, true},
441 {1, 1152, 864, 60, true}, {2, 1152, 864, 75, true}, {3, 1152, 864, 84, true},
442 {1, 1280, 720, 60, true}, {2, 1280, 720, 75, true}, {3, 1280, 720, 85, true},
443 {1, 1280, 768, 60, true},
444 {1, 1280, 800, 60, true},
445 {1, 1280, 854, 60, true},
446 {1, 1280, 960, 60, true}, {2, 1280, 960, 85, true},
447 {1, 1280, 1024, 43, true}, {2, 1280, 1024, 60, true}, {3, 1280, 1024, 75, true},
448 {4, 1280, 1024, 85, true},
449 {1, 1360, 768, 60, true},
450 {1, 1360, 1024, 59, true},
451 {1, 1400, 1050, 60, true}, {2, 1400, 1050, 75, true},
452 {1, 1600, 1200, 60, true}, {2, 1600, 1200, 65, true}, {3, 1600, 1200, 70, true},
453 {4, 1600, 1200, 75, true}, {5, 1600, 1200, 85, true}, {6, 1600, 1200, 100, true},
454 {7, 1600, 1200, 120, true},
455 {1, 1680, 1050, 60, true},
456 {1, 1920, 1080, 30, true},
457 {1, 1920, 1440, 60, true}, {2, 1920, 1440, 65, true}, {3, 1920, 1440, 70, true},
458 {4, 1920, 1440, 75, true}, {5, 1920, 1440, 85, true}, {6, 1920, 1440, 100, true},
459 {1, 2048, 1536, 60, true}, {2, 2048, 1536, 65, true}, {3, 2048, 1536, 70, true},
460 {4, 2048, 1536, 75, true}, {5, 2048, 1536, 85, true},
461 {0, 0, 0, 0, false}
462};
463
464static struct _sisfbddcsmodes {
465 u32 mask;
466 u16 h;
467 u16 v;
468 u32 d;
469} sisfb_ddcsmodes[] = {
470 { 0x10000, 67, 75, 108000},
471 { 0x08000, 48, 72, 50000},
472 { 0x04000, 46, 75, 49500},
473 { 0x01000, 35, 43, 44900},
474 { 0x00800, 48, 60, 65000},
475 { 0x00400, 56, 70, 75000},
476 { 0x00200, 60, 75, 78800},
477 { 0x00100, 80, 75, 135000},
478 { 0x00020, 31, 60, 25200},
479 { 0x00008, 38, 72, 31500},
480 { 0x00004, 37, 75, 31500},
481 { 0x00002, 35, 56, 36000},
482 { 0x00001, 38, 60, 40000}
483};
484
485static struct _sisfbddcfmodes {
486 u16 x;
487 u16 y;
488 u16 v;
489 u16 h;
490 u32 d;
491} sisfb_ddcfmodes[] = {
492 { 1280, 1024, 85, 92, 157500},
493 { 1600, 1200, 60, 75, 162000},
494 { 1600, 1200, 65, 82, 175500},
495 { 1600, 1200, 70, 88, 189000},
496 { 1600, 1200, 75, 94, 202500},
497 { 1600, 1200, 85, 107,229500},
498 { 1920, 1440, 60, 90, 234000},
499 { 1920, 1440, 75, 113,297000}
500};
501
502#ifdef CONFIG_FB_SIS_300
503static struct _chswtable {
504 u16 subsysVendor;
505 u16 subsysCard;
506 char *vendorName;
507 char *cardName;
508} mychswtable[] = {
509 { 0x1631, 0x1002, "Mitachi", "0x1002" },
510 { 0x1071, 0x7521, "Mitac" , "7521P" },
511 { 0, 0, "" , "" }
512};
513#endif
514
515static struct _customttable {
516 u16 chipID;
517 char *biosversion;
518 char *biosdate;
519 u32 bioschksum;
520 u16 biosFootprintAddr[5];
521 u8 biosFootprintData[5];
522 u16 pcisubsysvendor;
523 u16 pcisubsyscard;
524 char *vendorName;
525 char *cardName;
526 u32 SpecialID;
527 char *optionName;
528} mycustomttable[] = {
529 { SIS_630, "2.00.07", "09/27/2002-13:38:25",
530 0x3240A8,
531 { 0x220, 0x227, 0x228, 0x229, 0x0ee },
532 { 0x01, 0xe3, 0x9a, 0x6a, 0xef },
533 0x1039, 0x6300,
534 "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO_1366"
535 },
536 { SIS_630, "2.00.07", "09/27/2002-13:38:25",
537 0x323FBD,
538 { 0x220, 0x227, 0x228, 0x229, 0x0ee },
539 { 0x00, 0x5a, 0x64, 0x41, 0xef },
540 0x1039, 0x6300,
541 "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO_1024"
542 },
543 { SIS_650, "", "",
544 0,
545 { 0, 0, 0, 0, 0 },
546 { 0, 0, 0, 0, 0 },
547 0x0e11, 0x083c,
548 "Inventec (Compaq)", "3017cl/3045US", CUT_COMPAQ12802, "COMPAQ_1280"
549 },
550 { SIS_650, "", "",
551 0,
552 { 0x00c, 0, 0, 0, 0 },
553 { 'e' , 0, 0, 0, 0 },
554 0x1558, 0x0287,
555 "Clevo", "L285/L287 (Version 1)", CUT_CLEVO1024, "CLEVO_L28X_1"
556 },
557 { SIS_650, "", "",
558 0,
559 { 0x00c, 0, 0, 0, 0 },
560 { 'y' , 0, 0, 0, 0 },
561 0x1558, 0x0287,
562 "Clevo", "L285/L287 (Version 2)", CUT_CLEVO10242, "CLEVO_L28X_2"
563 },
564 { SIS_650, "", "",
565 0,
566 { 0, 0, 0, 0, 0 },
567 { 0, 0, 0, 0, 0 },
568 0x1558, 0x0400, /* possibly 401 and 402 as well; not panelsize specific (?) */
569 "Clevo", "D400S/D410S/D400H/D410H", CUT_CLEVO1400, "CLEVO_D4X0"
570 },
571 { SIS_650, "", "",
572 0, /* Shift LCD in LCD-via-CRT1 mode */
573 { 0, 0, 0, 0, 0 },
574 { 0, 0, 0, 0, 0 },
575 0x1558, 0x2263,
576 "Clevo", "D22ES/D27ES", CUT_UNIWILL1024, "CLEVO_D2X0ES"
577 },
578 { SIS_650, "", "",
579 0, /* Shift LCD in LCD-via-CRT1 mode */
580 { 0, 0, 0, 0, 0 },
581 { 0, 0, 0, 0, 0 },
582 0x1734, 0x101f,
583 "Uniwill", "N243S9", CUT_UNIWILL1024, "UNIWILL_N243S9"
584 },
585 { SIS_650, "", "",
586 0, /* Shift LCD in LCD-via-CRT1 mode */
587 { 0, 0, 0, 0, 0 },
588 { 0, 0, 0, 0, 0 },
589 0x1584, 0x5103,
590 "Uniwill", "N35BS1", CUT_UNIWILL10242, "UNIWILL_N35BS1"
591 },
592 { SIS_650, "1.09.2c", "", /* Other versions, too? */
593 0, /* Shift LCD in LCD-via-CRT1 mode */
594 { 0, 0, 0, 0, 0 },
595 { 0, 0, 0, 0, 0 },
596 0x1019, 0x0f05,
597 "ECS", "A928", CUT_UNIWILL1024, "ECS_A928"
598 },
599 { SIS_740, "1.11.27a", "",
600 0,
601 { 0, 0, 0, 0, 0 },
602 { 0, 0, 0, 0, 0 },
603 0x1043, 0x1612,
604 "Asus", "L3000D/L3500D", CUT_ASUSL3000D, "ASUS_L3X00"
605 },
606 { SIS_650, "1.10.9k", "",
607 0,
608 { 0, 0, 0, 0, 0 },
609 { 0, 0, 0, 0, 0 },
610 0x1025, 0x0028,
611 "Acer", "Aspire 1700", CUT_ACER1280, "ACER_ASPIRE1700"
612 },
613 { SIS_650, "1.10.7w", "",
614 0,
615 { 0, 0, 0, 0, 0 },
616 { 0, 0, 0, 0, 0 },
617 0x14c0, 0x0012,
618 "Compal", "??? (V1)", CUT_COMPAL1400_1, "COMPAL_1400_1"
619 },
620 { SIS_650, "1.10.7x", "",
621 0,
622 { 0, 0, 0, 0, 0 },
623 { 0, 0, 0, 0, 0 },
624 0x14c0, 0x0012,
625 "Compal", "??? (V2)", CUT_COMPAL1400_2, "COMPAL_1400_2"
626 },
627 { SIS_650, "1.10.8o", "",
628 0, /* For EMI (unknown) */
629 { 0, 0, 0, 0, 0 },
630 { 0, 0, 0, 0, 0 },
631 0x1043, 0x1612,
632 "Asus", "A2H (V1)", CUT_ASUSA2H_1, "ASUS_A2H_1"
633 },
634 { SIS_650, "1.10.8q", "",
635 0, /* For EMI */
636 { 0, 0, 0, 0, 0 },
637 { 0, 0, 0, 0, 0 },
638 0x1043, 0x1612,
639 "Asus", "A2H (V2)", CUT_ASUSA2H_2, "ASUS_A2H_2"
640 },
641 { 4321, "", "", /* never autodetected */
642 0,
643 { 0, 0, 0, 0, 0 },
644 { 0, 0, 0, 0, 0 },
645 0, 0,
646 "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
647 },
648 { 4322, "", "", /* never autodetected */
649 0,
650 { 0, 0, 0, 0, 0 },
651 { 0, 0, 0, 0, 0 },
652 0, 0,
653 "Generic", "LVDS/Parallel 856x480", CUT_PANEL856, "PANEL856x480"
654 },
655 { 0, "", "",
656 0,
657 { 0, 0, 0, 0 },
658 { 0, 0, 0, 0 },
659 0, 0,
660 "", "", CUT_NONE, ""
661 }
662};
663
664/* ---------------------- Prototypes ------------------------- */
665
666/* Interface used by the world */
667#ifndef MODULE
668static int sisfb_setup(char *options);
669#endif
670
671/* Interface to the low level console driver */
672static int sisfb_init(void);
673
674/* fbdev routines */
675static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
676 struct fb_info *info);
677
678static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
679 unsigned long arg);
680static int sisfb_set_par(struct fb_info *info);
681static int sisfb_blank(int blank,
682 struct fb_info *info);
683extern void fbcon_sis_fillrect(struct fb_info *info,
684 const struct fb_fillrect *rect);
685extern void fbcon_sis_copyarea(struct fb_info *info,
686 const struct fb_copyarea *area);
687extern int fbcon_sis_sync(struct fb_info *info);
688
689/* Internal 2D accelerator functions */
690extern int sisfb_initaccel(struct sis_video_info *ivideo);
691extern void sisfb_syncaccel(struct sis_video_info *ivideo);
692
693/* Internal general routines */
694static void sisfb_search_mode(char *name, bool quiet);
695static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
696static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
697 int index);
698static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
699 unsigned blue, unsigned transp,
700 struct fb_info *fb_info);
701static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
702 struct fb_info *info);
703static void sisfb_pre_setmode(struct sis_video_info *ivideo);
704static void sisfb_post_setmode(struct sis_video_info *ivideo);
705static bool sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
706static bool sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
707static bool sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
708static bool sisfb_bridgeisslave(struct sis_video_info *ivideo);
709static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
710static void sisfb_get_VB_type(struct sis_video_info *ivideo);
711static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
712static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
713#ifdef CONFIG_FB_SIS_300
714unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
715void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val);
716unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
717#endif
718#ifdef CONFIG_FB_SIS_315
719void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val);
720unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
721#endif
722
723/* SiS-specific exported functions */
724void sis_malloc(struct sis_memreq *req);
725void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
726void sis_free(u32 base);
727void sis_free_new(struct pci_dev *pdev, u32 base);
728
729/* Internal heap routines */
730static int sisfb_heap_init(struct sis_video_info *ivideo);
731static struct SIS_OH * sisfb_poh_new_node(struct SIS_HEAP *memheap);
732static struct SIS_OH * sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size);
733static void sisfb_delete_node(struct SIS_OH *poh);
734static void sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh);
735static struct SIS_OH * sisfb_poh_free(struct SIS_HEAP *memheap, u32 base);
736static void sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh);
737
738/* Routines from init.c/init301.c */
739extern unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
740 int VDisplay, int Depth, bool FSTN, unsigned short CustomT,
741 int LCDwith, int LCDheight, unsigned int VBFlags2);
742extern unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
743 int VDisplay, int Depth, unsigned int VBFlags2);
744extern unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
745 int VDisplay, int Depth, unsigned int VBFlags2);
746extern void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
747extern bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
748extern void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
749extern void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
750
751extern bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
752
753extern bool sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
754 int *htotal, int *vtotal, unsigned char rateindex);
755extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
756 unsigned char modeno, unsigned char rateindex);
757extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
758 unsigned char rateindex, struct fb_var_screeninfo *var);
759
760/* Chrontel TV, DDC and DPMS functions */
761extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
762extern void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
763extern unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg);
764extern void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
765extern void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
766 unsigned char myor, unsigned char myand);
767extern void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
768extern void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
769extern unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
770 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
771 unsigned int VBFlags2);
772extern unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
773#ifdef CONFIG_FB_SIS_315
774extern void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
775extern void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
776#endif
777extern void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
778extern void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
779#endif
780
781
diff --git a/drivers/video/fbdev/sis/vgatypes.h b/drivers/video/fbdev/sis/vgatypes.h
new file mode 100644
index 000000000000..e3f9976cfef0
--- /dev/null
+++ b/drivers/video/fbdev/sis/vgatypes.h
@@ -0,0 +1,97 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * General type definitions for universal mode switching modules
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _VGATYPES_H_
54#define _VGATYPES_H_
55
56#define SISIOMEMTYPE
57
58typedef unsigned long SISIOADDRESS;
59#include <linux/types.h> /* Need __iomem */
60#undef SISIOMEMTYPE
61#define SISIOMEMTYPE __iomem
62
63typedef enum _SIS_CHIP_TYPE {
64 SIS_VGALegacy = 0,
65 SIS_530,
66 SIS_OLD,
67 SIS_300,
68 SIS_630,
69 SIS_730,
70 SIS_540,
71 SIS_315H, /* SiS 310 */
72 SIS_315,
73 SIS_315PRO, /* SiS 325 */
74 SIS_550,
75 SIS_650,
76 SIS_740,
77 SIS_330,
78 SIS_661,
79 SIS_741,
80 SIS_670,
81 SIS_660 = 35,
82 SIS_760,
83 SIS_761,
84 SIS_762,
85 SIS_770,
86 SIS_340 = 55,
87 SIS_341,
88 SIS_342,
89 XGI_20 = 75,
90 XGI_21,
91 XGI_40,
92 MAX_SIS_CHIP
93} SIS_CHIP_TYPE;
94
95
96#endif
97
diff --git a/drivers/video/fbdev/sis/vstruct.h b/drivers/video/fbdev/sis/vstruct.h
new file mode 100644
index 000000000000..ea94d214dcff
--- /dev/null
+++ b/drivers/video/fbdev/sis/vstruct.h
@@ -0,0 +1,551 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * General structure definitions for universal mode switching modules
5 *
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _VSTRUCT_H_
54#define _VSTRUCT_H_
55
56struct SiS_PanelDelayTbl {
57 unsigned char timer[2];
58};
59
60struct SiS_LCDData {
61 unsigned short RVBHCMAX;
62 unsigned short RVBHCFACT;
63 unsigned short VGAHT;
64 unsigned short VGAVT;
65 unsigned short LCDHT;
66 unsigned short LCDVT;
67};
68
69struct SiS_TVData {
70 unsigned short RVBHCMAX;
71 unsigned short RVBHCFACT;
72 unsigned short VGAHT;
73 unsigned short VGAVT;
74 unsigned short TVHDE;
75 unsigned short TVVDE;
76 unsigned short RVBHRS;
77 unsigned char FlickerMode;
78 unsigned short HALFRVBHRS;
79 unsigned short RVBHRS2;
80 unsigned char RY1COE;
81 unsigned char RY2COE;
82 unsigned char RY3COE;
83 unsigned char RY4COE;
84};
85
86struct SiS_LVDSData {
87 unsigned short VGAHT;
88 unsigned short VGAVT;
89 unsigned short LCDHT;
90 unsigned short LCDVT;
91};
92
93struct SiS_LVDSDes {
94 unsigned short LCDHDES;
95 unsigned short LCDVDES;
96};
97
98struct SiS_LVDSCRT1Data {
99 unsigned char CR[15];
100};
101
102struct SiS_CHTVRegData {
103 unsigned char Reg[16];
104};
105
106struct SiS_St {
107 unsigned char St_ModeID;
108 unsigned short St_ModeFlag;
109 unsigned char St_StTableIndex;
110 unsigned char St_CRT2CRTC;
111 unsigned char St_ResInfo;
112 unsigned char VB_StTVFlickerIndex;
113 unsigned char VB_StTVEdgeIndex;
114 unsigned char VB_StTVYFilterIndex;
115 unsigned char St_PDC;
116};
117
118struct SiS_VBMode {
119 unsigned char ModeID;
120 unsigned char VB_TVDelayIndex;
121 unsigned char VB_TVFlickerIndex;
122 unsigned char VB_TVPhaseIndex;
123 unsigned char VB_TVYFilterIndex;
124 unsigned char VB_LCDDelayIndex;
125 unsigned char _VB_LCDHIndex;
126 unsigned char _VB_LCDVIndex;
127};
128
129struct SiS_StandTable_S {
130 unsigned char CRT_COLS;
131 unsigned char ROWS;
132 unsigned char CHAR_HEIGHT;
133 unsigned short CRT_LEN;
134 unsigned char SR[4];
135 unsigned char MISC;
136 unsigned char CRTC[0x19];
137 unsigned char ATTR[0x14];
138 unsigned char GRC[9];
139};
140
141struct SiS_Ext {
142 unsigned char Ext_ModeID;
143 unsigned short Ext_ModeFlag;
144 unsigned short Ext_VESAID;
145 unsigned char Ext_RESINFO;
146 unsigned char VB_ExtTVFlickerIndex;
147 unsigned char VB_ExtTVEdgeIndex;
148 unsigned char VB_ExtTVYFilterIndex;
149 unsigned char VB_ExtTVYFilterIndexROM661;
150 unsigned char REFindex;
151 char ROMMODEIDX661;
152};
153
154struct SiS_Ext2 {
155 unsigned short Ext_InfoFlag;
156 unsigned char Ext_CRT1CRTC;
157 unsigned char Ext_CRTVCLK;
158 unsigned char Ext_CRT2CRTC;
159 unsigned char Ext_CRT2CRTC_NS;
160 unsigned char ModeID;
161 unsigned short XRes;
162 unsigned short YRes;
163 unsigned char Ext_PDC;
164 unsigned char Ext_FakeCRT2CRTC;
165 unsigned char Ext_FakeCRT2Clk;
166 unsigned char Ext_CRT1CRTC_NORM;
167 unsigned char Ext_CRTVCLK_NORM;
168 unsigned char Ext_CRT1CRTC_WIDE;
169 unsigned char Ext_CRTVCLK_WIDE;
170};
171
172struct SiS_Part2PortTbl {
173 unsigned char CR[12];
174};
175
176struct SiS_CRT1Table {
177 unsigned char CR[17];
178};
179
180struct SiS_MCLKData {
181 unsigned char SR28,SR29,SR2A;
182 unsigned short CLOCK;
183};
184
185struct SiS_VCLKData {
186 unsigned char SR2B,SR2C;
187 unsigned short CLOCK;
188};
189
190struct SiS_VBVCLKData {
191 unsigned char Part4_A,Part4_B;
192 unsigned short CLOCK;
193};
194
195struct SiS_StResInfo_S {
196 unsigned short HTotal;
197 unsigned short VTotal;
198};
199
200struct SiS_ModeResInfo_S {
201 unsigned short HTotal;
202 unsigned short VTotal;
203 unsigned char XChar;
204 unsigned char YChar;
205};
206
207/* Defines for SiS_CustomT */
208/* Never change these for sisfb compatibility */
209#define CUT_NONE 0
210#define CUT_FORCENONE 1
211#define CUT_BARCO1366 2
212#define CUT_BARCO1024 3
213#define CUT_COMPAQ1280 4
214#define CUT_COMPAQ12802 5
215#define CUT_PANEL848 6
216#define CUT_CLEVO1024 7
217#define CUT_CLEVO10242 8
218#define CUT_CLEVO1400 9
219#define CUT_CLEVO14002 10
220#define CUT_UNIWILL1024 11
221#define CUT_ASUSL3000D 12
222#define CUT_UNIWILL10242 13
223#define CUT_ACER1280 14
224#define CUT_COMPAL1400_1 15
225#define CUT_COMPAL1400_2 16
226#define CUT_ASUSA2H_1 17
227#define CUT_ASUSA2H_2 18
228#define CUT_UNKNOWNLCD 19
229#define CUT_AOP8060 20
230#define CUT_PANEL856 21
231
232struct SiS_Private
233{
234 unsigned char ChipType;
235 unsigned char ChipRevision;
236 void *ivideo;
237 unsigned char *VirtualRomBase;
238 bool UseROM;
239 unsigned char SISIOMEMTYPE *VideoMemoryAddress;
240 unsigned int VideoMemorySize;
241 SISIOADDRESS IOAddress;
242 SISIOADDRESS IOAddress2; /* For dual chip XGI volari */
243
244 SISIOADDRESS RelIO;
245 SISIOADDRESS SiS_P3c4;
246 SISIOADDRESS SiS_P3d4;
247 SISIOADDRESS SiS_P3c0;
248 SISIOADDRESS SiS_P3ce;
249 SISIOADDRESS SiS_P3c2;
250 SISIOADDRESS SiS_P3ca;
251 SISIOADDRESS SiS_P3c6;
252 SISIOADDRESS SiS_P3c7;
253 SISIOADDRESS SiS_P3c8;
254 SISIOADDRESS SiS_P3c9;
255 SISIOADDRESS SiS_P3cb;
256 SISIOADDRESS SiS_P3cc;
257 SISIOADDRESS SiS_P3cd;
258 SISIOADDRESS SiS_P3da;
259 SISIOADDRESS SiS_Part1Port;
260 SISIOADDRESS SiS_Part2Port;
261 SISIOADDRESS SiS_Part3Port;
262 SISIOADDRESS SiS_Part4Port;
263 SISIOADDRESS SiS_Part5Port;
264 SISIOADDRESS SiS_VidCapt;
265 SISIOADDRESS SiS_VidPlay;
266 unsigned short SiS_IF_DEF_LVDS;
267 unsigned short SiS_IF_DEF_CH70xx;
268 unsigned short SiS_IF_DEF_CONEX;
269 unsigned short SiS_IF_DEF_TRUMPION;
270 unsigned short SiS_IF_DEF_DSTN;
271 unsigned short SiS_IF_DEF_FSTN;
272 unsigned short SiS_SysFlags;
273 unsigned char SiS_VGAINFO;
274 bool SiS_UseROM;
275 bool SiS_ROMNew;
276 bool SiS_XGIROM;
277 bool SiS_NeedRomModeData;
278 bool PanelSelfDetected;
279 bool DDCPortMixup;
280 int SiS_CHOverScan;
281 bool SiS_CHSOverScan;
282 bool SiS_ChSW;
283 bool SiS_UseLCDA;
284 int SiS_UseOEM;
285 unsigned int SiS_CustomT;
286 int SiS_UseWide, SiS_UseWideCRT2;
287 int SiS_TVBlue;
288 unsigned short SiS_Backup70xx;
289 bool HaveEMI;
290 bool HaveEMILCD;
291 bool OverruleEMI;
292 unsigned char EMI_30,EMI_31,EMI_32,EMI_33;
293 unsigned short SiS_EMIOffset;
294 unsigned short SiS_PWDOffset;
295 short PDC, PDCA;
296 unsigned char SiS_MyCR63;
297 unsigned short SiS_CRT1Mode;
298 unsigned short SiS_flag_clearbuffer;
299 int SiS_RAMType;
300 unsigned char SiS_ChannelAB;
301 unsigned char SiS_DataBusWidth;
302 unsigned short SiS_ModeType;
303 unsigned short SiS_VBInfo;
304 unsigned short SiS_TVMode;
305 unsigned short SiS_LCDResInfo;
306 unsigned short SiS_LCDTypeInfo;
307 unsigned short SiS_LCDInfo;
308 unsigned short SiS_LCDInfo661;
309 unsigned short SiS_VBType;
310 unsigned short SiS_VBExtInfo;
311 unsigned short SiS_YPbPr;
312 unsigned short SiS_SelectCRT2Rate;
313 unsigned short SiS_SetFlag;
314 unsigned short SiS_RVBHCFACT;
315 unsigned short SiS_RVBHCMAX;
316 unsigned short SiS_RVBHRS;
317 unsigned short SiS_RVBHRS2;
318 unsigned short SiS_VGAVT;
319 unsigned short SiS_VGAHT;
320 unsigned short SiS_VT;
321 unsigned short SiS_HT;
322 unsigned short SiS_VGAVDE;
323 unsigned short SiS_VGAHDE;
324 unsigned short SiS_VDE;
325 unsigned short SiS_HDE;
326 unsigned short SiS_NewFlickerMode;
327 unsigned short SiS_RY1COE;
328 unsigned short SiS_RY2COE;
329 unsigned short SiS_RY3COE;
330 unsigned short SiS_RY4COE;
331 unsigned short SiS_LCDHDES;
332 unsigned short SiS_LCDVDES;
333 SISIOADDRESS SiS_DDC_Port;
334 unsigned short SiS_DDC_Index;
335 unsigned short SiS_DDC_Data;
336 unsigned short SiS_DDC_NData;
337 unsigned short SiS_DDC_Clk;
338 unsigned short SiS_DDC_NClk;
339 unsigned short SiS_DDC_DeviceAddr;
340 unsigned short SiS_DDC_ReadAddr;
341 unsigned short SiS_DDC_SecAddr;
342 unsigned short SiS_ChrontelInit;
343 bool SiS_SensibleSR11;
344 unsigned short SiS661LCD2TableSize;
345
346 unsigned short SiS_PanelMinLVDS;
347 unsigned short SiS_PanelMin301;
348
349 const struct SiS_St *SiS_SModeIDTable;
350 const struct SiS_StandTable_S *SiS_StandTable;
351 const struct SiS_Ext *SiS_EModeIDTable;
352 const struct SiS_Ext2 *SiS_RefIndex;
353 const struct SiS_VBMode *SiS_VBModeIDTable;
354 const struct SiS_CRT1Table *SiS_CRT1Table;
355 const struct SiS_MCLKData *SiS_MCLKData_0;
356 const struct SiS_MCLKData *SiS_MCLKData_1;
357 struct SiS_VCLKData *SiS_VCLKData;
358 struct SiS_VBVCLKData *SiS_VBVCLKData;
359 const struct SiS_StResInfo_S *SiS_StResInfo;
360 const struct SiS_ModeResInfo_S *SiS_ModeResInfo;
361
362 const unsigned char *pSiS_OutputSelect;
363 const unsigned char *pSiS_SoftSetting;
364
365 const unsigned char *SiS_SR15;
366
367 const struct SiS_PanelDelayTbl *SiS_PanelDelayTbl;
368 const struct SiS_PanelDelayTbl *SiS_PanelDelayTblLVDS;
369
370 /* SiS bridge */
371
372 const struct SiS_LCDData *SiS_ExtLCD1024x768Data;
373 const struct SiS_LCDData *SiS_St2LCD1024x768Data;
374 const struct SiS_LCDData *SiS_LCD1280x720Data;
375 const struct SiS_LCDData *SiS_StLCD1280x768_2Data;
376 const struct SiS_LCDData *SiS_ExtLCD1280x768_2Data;
377 const struct SiS_LCDData *SiS_LCD1280x800Data;
378 const struct SiS_LCDData *SiS_LCD1280x800_2Data;
379 const struct SiS_LCDData *SiS_LCD1280x854Data;
380 const struct SiS_LCDData *SiS_LCD1280x960Data;
381 const struct SiS_LCDData *SiS_ExtLCD1280x1024Data;
382 const struct SiS_LCDData *SiS_St2LCD1280x1024Data;
383 const struct SiS_LCDData *SiS_StLCD1400x1050Data;
384 const struct SiS_LCDData *SiS_ExtLCD1400x1050Data;
385 const struct SiS_LCDData *SiS_StLCD1600x1200Data;
386 const struct SiS_LCDData *SiS_ExtLCD1600x1200Data;
387 const struct SiS_LCDData *SiS_LCD1680x1050Data;
388 const struct SiS_LCDData *SiS_NoScaleData;
389 const struct SiS_TVData *SiS_StPALData;
390 const struct SiS_TVData *SiS_ExtPALData;
391 const struct SiS_TVData *SiS_StNTSCData;
392 const struct SiS_TVData *SiS_ExtNTSCData;
393 const struct SiS_TVData *SiS_St1HiTVData;
394 const struct SiS_TVData *SiS_St2HiTVData;
395 const struct SiS_TVData *SiS_ExtHiTVData;
396 const struct SiS_TVData *SiS_St525iData;
397 const struct SiS_TVData *SiS_St525pData;
398 const struct SiS_TVData *SiS_St750pData;
399 const struct SiS_TVData *SiS_Ext525iData;
400 const struct SiS_TVData *SiS_Ext525pData;
401 const struct SiS_TVData *SiS_Ext750pData;
402 const unsigned char *SiS_NTSCTiming;
403 const unsigned char *SiS_PALTiming;
404 const unsigned char *SiS_HiTVExtTiming;
405 const unsigned char *SiS_HiTVSt1Timing;
406 const unsigned char *SiS_HiTVSt2Timing;
407 const unsigned char *SiS_HiTVGroup3Data;
408 const unsigned char *SiS_HiTVGroup3Simu;
409#if 0
410 const unsigned char *SiS_HiTVTextTiming;
411 const unsigned char *SiS_HiTVGroup3Text;
412#endif
413
414 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_1;
415 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_2;
416 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_3;
417
418 /* LVDS, Chrontel */
419
420 const struct SiS_LVDSData *SiS_LVDS320x240Data_1;
421 const struct SiS_LVDSData *SiS_LVDS320x240Data_2;
422 const struct SiS_LVDSData *SiS_LVDS640x480Data_1;
423 const struct SiS_LVDSData *SiS_LVDS800x600Data_1;
424 const struct SiS_LVDSData *SiS_LVDS1024x600Data_1;
425 const struct SiS_LVDSData *SiS_LVDS1024x768Data_1;
426 const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_1;
427 const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_2;
428 const struct SiS_LVDSData *SiS_LVDSBARCO1024Data_1;
429 const struct SiS_LVDSData *SiS_LVDS848x480Data_1;
430 const struct SiS_LVDSData *SiS_LVDS848x480Data_2;
431 const struct SiS_LVDSData *SiS_CHTVUNTSCData;
432 const struct SiS_LVDSData *SiS_CHTVONTSCData;
433 const struct SiS_LVDSData *SiS_CHTVUPALData;
434 const struct SiS_LVDSData *SiS_CHTVOPALData;
435 const struct SiS_LVDSData *SiS_CHTVUPALMData;
436 const struct SiS_LVDSData *SiS_CHTVOPALMData;
437 const struct SiS_LVDSData *SiS_CHTVUPALNData;
438 const struct SiS_LVDSData *SiS_CHTVOPALNData;
439 const struct SiS_LVDSData *SiS_CHTVSOPALData;
440
441 const struct SiS_LVDSDes *SiS_PanelType04_1a;
442 const struct SiS_LVDSDes *SiS_PanelType04_2a;
443 const struct SiS_LVDSDes *SiS_PanelType04_1b;
444 const struct SiS_LVDSDes *SiS_PanelType04_2b;
445
446 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_1;
447 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2;
448 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2_H;
449 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3;
450 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3_H;
451 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1;
452 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1_H;
453 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UNTSC;
454 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1ONTSC;
455 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UPAL;
456 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1OPAL;
457 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1SOPAL;
458
459 const struct SiS_CHTVRegData *SiS_CHTVReg_UNTSC;
460 const struct SiS_CHTVRegData *SiS_CHTVReg_ONTSC;
461 const struct SiS_CHTVRegData *SiS_CHTVReg_UPAL;
462 const struct SiS_CHTVRegData *SiS_CHTVReg_OPAL;
463 const struct SiS_CHTVRegData *SiS_CHTVReg_UPALM;
464 const struct SiS_CHTVRegData *SiS_CHTVReg_OPALM;
465 const struct SiS_CHTVRegData *SiS_CHTVReg_UPALN;
466 const struct SiS_CHTVRegData *SiS_CHTVReg_OPALN;
467 const struct SiS_CHTVRegData *SiS_CHTVReg_SOPAL;
468
469 const unsigned char *SiS_CHTVVCLKUNTSC;
470 const unsigned char *SiS_CHTVVCLKONTSC;
471 const unsigned char *SiS_CHTVVCLKUPAL;
472 const unsigned char *SiS_CHTVVCLKOPAL;
473 const unsigned char *SiS_CHTVVCLKUPALM;
474 const unsigned char *SiS_CHTVVCLKOPALM;
475 const unsigned char *SiS_CHTVVCLKUPALN;
476 const unsigned char *SiS_CHTVVCLKOPALN;
477 const unsigned char *SiS_CHTVVCLKSOPAL;
478
479 unsigned short PanelXRes, PanelHT;
480 unsigned short PanelYRes, PanelVT;
481 unsigned short PanelHRS, PanelHRE;
482 unsigned short PanelVRS, PanelVRE;
483 unsigned short PanelVCLKIdx300;
484 unsigned short PanelVCLKIdx315;
485 bool Alternate1600x1200;
486
487 bool UseCustomMode;
488 bool CRT1UsesCustomMode;
489 unsigned short CHDisplay;
490 unsigned short CHSyncStart;
491 unsigned short CHSyncEnd;
492 unsigned short CHTotal;
493 unsigned short CHBlankStart;
494 unsigned short CHBlankEnd;
495 unsigned short CVDisplay;
496 unsigned short CVSyncStart;
497 unsigned short CVSyncEnd;
498 unsigned short CVTotal;
499 unsigned short CVBlankStart;
500 unsigned short CVBlankEnd;
501 unsigned int CDClock;
502 unsigned int CFlags;
503 unsigned char CCRT1CRTC[17];
504 unsigned char CSR2B;
505 unsigned char CSR2C;
506 unsigned short CSRClock;
507 unsigned short CSRClock_CRT1;
508 unsigned short CModeFlag;
509 unsigned short CModeFlag_CRT1;
510 unsigned short CInfoFlag;
511
512 int LVDSHL;
513
514 bool Backup;
515 unsigned char Backup_Mode;
516 unsigned char Backup_14;
517 unsigned char Backup_15;
518 unsigned char Backup_16;
519 unsigned char Backup_17;
520 unsigned char Backup_18;
521 unsigned char Backup_19;
522 unsigned char Backup_1a;
523 unsigned char Backup_1b;
524 unsigned char Backup_1c;
525 unsigned char Backup_1d;
526
527 unsigned char Init_P4_0E;
528
529 int UsePanelScaler;
530 int CenterScreen;
531
532 unsigned short CP_Vendor, CP_Product;
533 bool CP_HaveCustomData;
534 int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
535 int CP_MaxX, CP_MaxY, CP_MaxClock;
536 unsigned char CP_PrefSR2B, CP_PrefSR2C;
537 unsigned short CP_PrefClock;
538 bool CP_Supports64048075;
539 int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
540 int CP_HTotal[7], CP_VTotal[7];
541 int CP_HSyncStart[7], CP_VSyncStart[7];
542 int CP_HSyncEnd[7], CP_VSyncEnd[7];
543 int CP_HBlankStart[7], CP_VBlankStart[7];
544 int CP_HBlankEnd[7], CP_VBlankEnd[7];
545 int CP_Clock[7];
546 bool CP_DataValid[7];
547 bool CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
548};
549
550#endif
551