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
85 static const unsigned char SiS_YPbPrTable[3][64] = {
86 {
87 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
88 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
89 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
90 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
91 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
92 0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
93 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
94 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
95 },
96 {
97 0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
98 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
99 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
100 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
101 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
102 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
103 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
104 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
105 },
106 {
107 #if 0 /* OK, but sticks to left edge */
108 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
109 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
110 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
111 0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
112 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
113 0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
114 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
115 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
116 #endif
117 #if 1 /* Perfect */
118 0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
119 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
120 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
121 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
122 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
123 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
124 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
125 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
126 #endif
127 }
128 };
129
130 static const unsigned char SiS_TVPhase[] =
131 {
132 0x21,0xED,0xBA,0x08, /* 0x00 SiS_NTSCPhase */
133 0x2A,0x05,0xE3,0x00, /* 0x01 SiS_PALPhase */
134 0x21,0xE4,0x2E,0x9B, /* 0x02 SiS_PALMPhase */
135 0x21,0xF4,0x3E,0xBA, /* 0x03 SiS_PALNPhase */
136 0x1E,0x8B,0xA2,0xA7,
137 0x1E,0x83,0x0A,0xE0, /* 0x05 SiS_SpecialPhaseM */
138 0x00,0x00,0x00,0x00,
139 0x00,0x00,0x00,0x00,
140 0x21,0xF0,0x7B,0xD6, /* 0x08 SiS_NTSCPhase2 */
141 0x2A,0x09,0x86,0xE9, /* 0x09 SiS_PALPhase2 */
142 0x21,0xE6,0xEF,0xA4, /* 0x0a SiS_PALMPhase2 */
143 0x21,0xF6,0x94,0x46, /* 0x0b SiS_PALNPhase2 */
144 0x1E,0x8B,0xA2,0xA7,
145 0x1E,0x83,0x0A,0xE0, /* 0x0d SiS_SpecialPhaseM */
146 0x00,0x00,0x00,0x00,
147 0x00,0x00,0x00,0x00,
148 0x1e,0x8c,0x5c,0x7a, /* 0x10 SiS_SpecialPhase */
149 0x25,0xd4,0xfd,0x5e /* 0x11 SiS_SpecialPhaseJ */
150 };
151
152 static const unsigned char SiS_HiTVGroup3_1[] = {
153 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
154 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
155 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
156 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
157 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
158 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
159 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
160 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
161 };
162
163 static const unsigned char SiS_HiTVGroup3_2[] = {
164 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
165 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
166 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
167 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
168 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
169 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
170 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
171 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
172 };
173
174 /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
175 #ifdef CONFIG_FB_SIS_315
176 static const unsigned char SiS_Part2CLVX_1[] = {
177 0x00,0x00,
178 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
179 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
180 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
181 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
182 };
183
184 static const unsigned char SiS_Part2CLVX_2[] = {
185 0x00,0x00,
186 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
187 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
188 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
189 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
190 };
191
192 static const unsigned char SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
193 0xE0,0x01,
194 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
195 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
196 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
197 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
198 0x58,0x02,
199 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
200 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
201 0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
202 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
203 0x00,0x03,
204 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
205 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
206 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
207 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
208 0xFF,0xFF
209 };
210
211 static const unsigned char SiS_Part2CLVX_4[] = { /* PAL */
212 0x58,0x02,
213 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
214 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
215 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
216 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
217 0x00,0x03,
218 0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
219 0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
220 0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
221 0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
222 0x40,0x02,
223 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
224 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
225 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
226 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
227 0xFF,0xFF
228 };
229
230 static const unsigned char SiS_Part2CLVX_5[] = { /* 750p */
231 0x00,0x03,
232 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
233 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
234 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
235 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
236 0xFF,0xFF
237 };
238
239 static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
240 0x00,0x04,
241 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
242 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
243 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
244 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
245 0xFF,0xFF,
246 };
247
248 /* 661 et al LCD data structure (2.03.00) */
249 static const unsigned char SiS_LCDStruct661[] = {
250 /* 1024x768 */
251 /* type|CR37| HDE | VDE | HT | VT | hss | hse */
252 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
253 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
254 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
255 /* VESA non-VESA noscale */
256 /* 1280x1024 */
257 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
258 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
259 /* 1400x1050 */
260 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
261 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
262 /* 1600x1200 */
263 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
264 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
265 /* 1280x768 (_2) */
266 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
267 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
268 /* 1280x720 */
269 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
270 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
271 /* 1280x800 (_2) */
272 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
273 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
274 /* 1680x1050 */
275 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
276 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
277 /* 1280x800_3 */
278 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
279 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
280 /* 800x600 */
281 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
282 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
283 /* 1280x854 */
284 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
285 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
286 };
287 #endif
288
289 #ifdef CONFIG_FB_SIS_300
290 static unsigned char SiS300_TrumpionData[14][80] = {
291 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
292 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
293 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
294 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
295 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
296 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
297 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
298 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
299 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
300 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
301 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
302 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
303 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
304 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
305 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
306 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
307 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
308 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
309 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
310 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
311 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
312 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
313 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
314 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
315 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
316 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
317 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
318 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
319 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
320 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
321 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
322 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
323 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
324 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
325 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
326 /* variant 2 */
327 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
328 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
329 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
330 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
331 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
332 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
333 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
334 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
335 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
336 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
337 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
338 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
339 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
340 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
341 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
342 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
343 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
344 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
345 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
346 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
347 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
348 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
349 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
350 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
351 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
352 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
353 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
354 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
355 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
356 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
357 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
358 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
359 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
360 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
361 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
362 };
363 #endif
364
365 #ifdef CONFIG_FB_SIS_315
366 static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
367 static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
368 static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
369 static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
370 #endif /* 315 */
371
372 #ifdef CONFIG_FB_SIS_300
373 static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
374 #endif
375
376 static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
377 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
378 bool checkcr32, unsigned int VBFlags2);
379 static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
380 static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
381 unsigned char *buffer);
382 static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
383 static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
384 static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
385 static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
386 static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
387 static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
388 static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
389 static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
390 static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
391 static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
392 static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
393 static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
394 static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
395
396 #ifdef CONFIG_FB_SIS_300
397 static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
398 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
399 static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
400 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
401 #endif
402 #ifdef CONFIG_FB_SIS_315
403 static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
404 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
405 static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
406 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
407 static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
408 #endif
409
410 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
411 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
412
413 /*********************************************/
414 /* HELPER: Lock/Unlock CRT2 */
415 /*********************************************/
416
417 void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)418 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
419 {
420 if(SiS_Pr->ChipType == XGI_20)
421 return;
422 else if(SiS_Pr->ChipType >= SIS_315H)
423 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
424 else
425 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
426 }
427
428 static
429 void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)430 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
431 {
432 if(SiS_Pr->ChipType == XGI_20)
433 return;
434 else if(SiS_Pr->ChipType >= SIS_315H)
435 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
436 else
437 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
438 }
439
440 /*********************************************/
441 /* HELPER: Write SR11 */
442 /*********************************************/
443
444 static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)445 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
446 {
447 if(SiS_Pr->ChipType >= SIS_661) {
448 DataAND &= 0x0f;
449 DataOR &= 0x0f;
450 }
451 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
452 }
453
454 /*********************************************/
455 /* HELPER: Get Pointer to LCD structure */
456 /*********************************************/
457
458 #ifdef CONFIG_FB_SIS_315
459 static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)460 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
461 {
462 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
463 unsigned char *myptr = NULL;
464 unsigned short romindex = 0, reg = 0, idx = 0;
465
466 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
467 * due to the variaty of panels the BIOS doesn't know about.
468 * Exception: If the BIOS has better knowledge (such as in case
469 * of machines with a 301C and a panel that does not support DDC)
470 * use the BIOS data as well.
471 */
472
473 if((SiS_Pr->SiS_ROMNew) &&
474 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
475
476 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
477 else reg = 0x7d;
478
479 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
480
481 if(idx < (8*26)) {
482 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
483 }
484 romindex = SISGETROMW(0x100);
485 if(romindex) {
486 romindex += idx;
487 myptr = &ROMAddr[romindex];
488 }
489 }
490 return myptr;
491 }
492
493 static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)494 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
495 {
496 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
497 unsigned short romptr = 0;
498
499 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
500 * due to the variaty of panels the BIOS doesn't know about.
501 * Exception: If the BIOS has better knowledge (such as in case
502 * of machines with a 301C and a panel that does not support DDC)
503 * use the BIOS data as well.
504 */
505
506 if((SiS_Pr->SiS_ROMNew) &&
507 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
508 romptr = SISGETROMW(0x102);
509 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
510 }
511
512 return romptr;
513 }
514 #endif
515
516 /*********************************************/
517 /* Adjust Rate for CRT2 */
518 /*********************************************/
519
520 static bool
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)521 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
522 unsigned short RRTI, unsigned short *i)
523 {
524 unsigned short checkmask=0, modeid, infoflag;
525
526 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
527
528 if(SiS_Pr->SiS_VBType & VB_SISVB) {
529
530 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
531
532 checkmask |= SupportRAMDAC2;
533 if(SiS_Pr->ChipType >= SIS_315H) {
534 checkmask |= SupportRAMDAC2_135;
535 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
536 checkmask |= SupportRAMDAC2_162;
537 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
538 checkmask |= SupportRAMDAC2_202;
539 }
540 }
541 }
542
543 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
544
545 checkmask |= SupportLCD;
546 if(SiS_Pr->ChipType >= SIS_315H) {
547 if(SiS_Pr->SiS_VBType & VB_SISVB) {
548 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
549 if(modeid == 0x2e) checkmask |= Support64048060Hz;
550 }
551 }
552 }
553
554 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
555
556 checkmask |= SupportHiVision;
557
558 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
559
560 checkmask |= SupportTV;
561 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
562 checkmask |= SupportTV1024;
563 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
564 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
565 checkmask |= SupportYPbPr750p;
566 }
567 }
568 }
569
570 }
571
572 } else { /* LVDS */
573
574 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
575 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
576 checkmask |= SupportCHTV;
577 }
578 }
579
580 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
581 checkmask |= SupportLCD;
582 }
583
584 }
585
586 /* Look backwards in table for matching CRT2 mode */
587 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
588 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
589 if(infoflag & checkmask) return true;
590 if((*i) == 0) break;
591 }
592
593 /* Look through the whole mode-section of the table from the beginning
594 * for a matching CRT2 mode if no mode was found yet.
595 */
596 for((*i) = 0; ; (*i)++) {
597 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
598 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
599 if(infoflag & checkmask) return true;
600 }
601 return false;
602 }
603
604 /*********************************************/
605 /* Get rate index */
606 /*********************************************/
607
608 unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)609 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
610 {
611 unsigned short RRTI,i,backup_i;
612 unsigned short modeflag,index,temp,backupindex;
613 static const unsigned short LCDRefreshIndex[] = {
614 0x00, 0x00, 0x01, 0x01,
615 0x01, 0x01, 0x01, 0x01,
616 0x01, 0x01, 0x01, 0x01,
617 0x01, 0x01, 0x01, 0x01,
618 0x00, 0x00, 0x00, 0x00
619 };
620
621 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
622 if(ModeNo == 0xfe) return 0;
623
624 if(ModeNo <= 0x13) {
625 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
626 } else {
627 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
628 }
629
630 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
631 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
632 if(modeflag & HalfDCLK) return 0;
633 }
634 }
635
636 if(ModeNo < 0x14) return 0xFFFF;
637
638 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
639 backupindex = index;
640
641 if(index > 0) index--;
642
643 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
644 if(SiS_Pr->SiS_VBType & VB_SISVB) {
645 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
646 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
647 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
648 }
649 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
650 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
651 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
652 if(index > temp) index = temp;
653 }
654 }
655 } else {
656 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
657 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
658 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
659 }
660 }
661 }
662
663 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
664 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
665
666 if(SiS_Pr->ChipType >= SIS_315H) {
667 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
668 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
669 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
670 if(backupindex <= 1) RRTI++;
671 }
672 }
673 }
674
675 i = 0;
676 do {
677 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
678 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
679 temp &= ModeTypeMask;
680 if(temp < SiS_Pr->SiS_ModeType) break;
681 i++;
682 index--;
683 } while(index != 0xFFFF);
684
685 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
686 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
687 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
688 if(temp & InterlaceMode) i++;
689 }
690 }
691
692 i--;
693
694 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
695 backup_i = i;
696 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
697 i = backup_i;
698 }
699 }
700
701 return (RRTI + i);
702 }
703
704 /*********************************************/
705 /* STORE CRT2 INFO in CR34 */
706 /*********************************************/
707
708 static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)709 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
710 {
711 unsigned short temp1, temp2;
712
713 /* Store CRT1 ModeNo in CR34 */
714 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
715 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
716 temp2 = ~(SetInSlaveMode >> 8);
717 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
718 }
719
720 /*********************************************/
721 /* HELPER: GET SOME DATA FROM BIOS ROM */
722 /*********************************************/
723
724 #ifdef CONFIG_FB_SIS_300
725 static bool
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)726 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
727 {
728 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
729 unsigned short temp,temp1;
730
731 if(SiS_Pr->SiS_UseROM) {
732 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
733 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
734 temp1 = SISGETROMW(0x23b);
735 if(temp1 & temp) return true;
736 }
737 }
738 return false;
739 }
740
741 static bool
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)742 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
743 {
744 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
745 unsigned short temp,temp1;
746
747 if(SiS_Pr->SiS_UseROM) {
748 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
749 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
750 temp1 = SISGETROMW(0x23d);
751 if(temp1 & temp) return true;
752 }
753 }
754 return false;
755 }
756 #endif
757
758 /*********************************************/
759 /* HELPER: DELAY FUNCTIONS */
760 /*********************************************/
761
762 void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)763 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
764 {
765 while (delaytime-- > 0)
766 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
767 }
768
769 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
770 static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)771 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
772 {
773 SiS_DDC2Delay(SiS_Pr, delay * 36);
774 }
775 #endif
776
777 #ifdef CONFIG_FB_SIS_315
778 static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)779 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
780 {
781 while(delay--) {
782 SiS_GenericDelay(SiS_Pr, 6623);
783 }
784 }
785 #endif
786
787 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
788 static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)789 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
790 {
791 while(delay--) {
792 SiS_GenericDelay(SiS_Pr, 66);
793 }
794 }
795 #endif
796
797 static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)798 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
799 {
800 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
801 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
802 unsigned short PanelID, DelayIndex, Delay=0;
803 #endif
804
805 if(SiS_Pr->ChipType < SIS_315H) {
806
807 #ifdef CONFIG_FB_SIS_300
808
809 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
810 if(SiS_Pr->SiS_VBType & VB_SISVB) {
811 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
812 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
813 }
814 DelayIndex = PanelID >> 4;
815 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
816 Delay = 3;
817 } else {
818 if(DelayTime >= 2) DelayTime -= 2;
819 if(!(DelayTime & 0x01)) {
820 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
821 } else {
822 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
823 }
824 if(SiS_Pr->SiS_UseROM) {
825 if(ROMAddr[0x220] & 0x40) {
826 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
827 else Delay = (unsigned short)ROMAddr[0x226];
828 }
829 }
830 }
831 SiS_ShortDelay(SiS_Pr, Delay);
832
833 #endif /* CONFIG_FB_SIS_300 */
834
835 } else {
836
837 #ifdef CONFIG_FB_SIS_315
838
839 if((SiS_Pr->ChipType >= SIS_661) ||
840 (SiS_Pr->ChipType <= SIS_315PRO) ||
841 (SiS_Pr->ChipType == SIS_330) ||
842 (SiS_Pr->SiS_ROMNew)) {
843
844 if(!(DelayTime & 0x01)) {
845 SiS_DDC2Delay(SiS_Pr, 0x1000);
846 } else {
847 SiS_DDC2Delay(SiS_Pr, 0x4000);
848 }
849
850 } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS; Special */
851
852 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
853 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
854 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
855 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
856 }
857 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
858 DelayIndex = PanelID & 0x0f;
859 } else {
860 DelayIndex = PanelID >> 4;
861 }
862 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
863 Delay = 3;
864 } else {
865 if(DelayTime >= 2) DelayTime -= 2;
866 if(!(DelayTime & 0x01)) {
867 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
868 } else {
869 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
870 }
871 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
872 if(ROMAddr[0x13c] & 0x40) {
873 if(!(DelayTime & 0x01)) {
874 Delay = (unsigned short)ROMAddr[0x17e];
875 } else {
876 Delay = (unsigned short)ROMAddr[0x17f];
877 }
878 }
879 }
880 }
881 SiS_ShortDelay(SiS_Pr, Delay);
882 }
883
884 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
885
886 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
887 if(!(DelayTime & 0x01)) {
888 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
889 } else {
890 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
891 }
892 Delay <<= 8;
893 SiS_DDC2Delay(SiS_Pr, Delay);
894
895 }
896
897 #endif /* CONFIG_FB_SIS_315 */
898
899 }
900 }
901
902 #ifdef CONFIG_FB_SIS_315
903 static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)904 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
905 {
906 int i;
907 for(i = 0; i < DelayLoop; i++) {
908 SiS_PanelDelay(SiS_Pr, DelayTime);
909 }
910 }
911 #endif
912
913 /*********************************************/
914 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
915 /*********************************************/
916
917 void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)918 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
919 {
920 unsigned short watchdog;
921
922 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
923 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
924
925 watchdog = 65535;
926 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
927 watchdog = 65535;
928 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
929 }
930
931 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
932 static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)933 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
934 {
935 unsigned short watchdog;
936
937 watchdog = 65535;
938 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
939 watchdog = 65535;
940 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
941 }
942 #endif
943
944 static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)945 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
946 {
947 if(SiS_Pr->ChipType < SIS_315H) {
948 #ifdef CONFIG_FB_SIS_300
949 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
950 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
951 }
952 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
953 SiS_WaitRetrace1(SiS_Pr);
954 } else {
955 SiS_WaitRetrace2(SiS_Pr, 0x25);
956 }
957 #endif
958 } else {
959 #ifdef CONFIG_FB_SIS_315
960 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
961 SiS_WaitRetrace1(SiS_Pr);
962 } else {
963 SiS_WaitRetrace2(SiS_Pr, 0x30);
964 }
965 #endif
966 }
967 }
968
969 static void
SiS_VBWait(struct SiS_Private * SiS_Pr)970 SiS_VBWait(struct SiS_Private *SiS_Pr)
971 {
972 unsigned short tempal,temp,i,j;
973
974 temp = 0;
975 for(i = 0; i < 3; i++) {
976 for(j = 0; j < 100; j++) {
977 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
978 if(temp & 0x01) {
979 if((tempal & 0x08)) continue;
980 else break;
981 } else {
982 if(!(tempal & 0x08)) continue;
983 else break;
984 }
985 }
986 temp ^= 0x01;
987 }
988 }
989
990 static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)991 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
992 {
993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
994 SiS_VBWait(SiS_Pr);
995 } else {
996 SiS_WaitRetrace1(SiS_Pr);
997 }
998 }
999
1000 /*********************************************/
1001 /* HELPER: MISC */
1002 /*********************************************/
1003
1004 #ifdef CONFIG_FB_SIS_300
1005 static bool
SiS_Is301B(struct SiS_Private * SiS_Pr)1006 SiS_Is301B(struct SiS_Private *SiS_Pr)
1007 {
1008 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1009 return false;
1010 }
1011 #endif
1012
1013 static bool
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)1014 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1015 {
1016 if(SiS_Pr->ChipType == SIS_730) {
1017 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1018 }
1019 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1020 return false;
1021 }
1022
1023 bool
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)1024 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1025 {
1026 #ifdef CONFIG_FB_SIS_315
1027 if(SiS_Pr->ChipType >= SIS_315H) {
1028 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1029 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1030 }
1031 }
1032 #endif
1033 return false;
1034 }
1035
1036 bool
SiS_IsVAMode(struct SiS_Private * SiS_Pr)1037 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1038 {
1039 #ifdef CONFIG_FB_SIS_315
1040 unsigned short flag;
1041
1042 if(SiS_Pr->ChipType >= SIS_315H) {
1043 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1044 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1045 }
1046 #endif
1047 return false;
1048 }
1049
1050 #ifdef CONFIG_FB_SIS_315
1051 static bool
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)1052 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1053 {
1054 if(SiS_IsVAMode(SiS_Pr)) return true;
1055 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1056 return false;
1057 }
1058 #endif
1059
1060 static bool
SiS_IsDualLink(struct SiS_Private * SiS_Pr)1061 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1062 {
1063 #ifdef CONFIG_FB_SIS_315
1064 if(SiS_Pr->ChipType >= SIS_315H) {
1065 if((SiS_CRT2IsLCD(SiS_Pr)) ||
1066 (SiS_IsVAMode(SiS_Pr))) {
1067 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1068 }
1069 }
1070 #endif
1071 return false;
1072 }
1073
1074 #ifdef CONFIG_FB_SIS_315
1075 static bool
SiS_TVEnabled(struct SiS_Private * SiS_Pr)1076 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1077 {
1078 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1079 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1080 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1081 }
1082 return false;
1083 }
1084 #endif
1085
1086 #ifdef CONFIG_FB_SIS_315
1087 static bool
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)1088 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1089 {
1090 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1091 return false;
1092 }
1093 #endif
1094
1095 #ifdef CONFIG_FB_SIS_315
1096 static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)1097 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1098 {
1099 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1100 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1101 }
1102 return false;
1103 }
1104 #endif
1105
1106 #ifdef CONFIG_FB_SIS_315
1107 static bool
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)1108 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1109 {
1110 unsigned short flag;
1111
1112 if(SiS_Pr->ChipType == SIS_650) {
1113 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1114 /* Check for revision != A0 only */
1115 if((flag == 0xe0) || (flag == 0xc0) ||
1116 (flag == 0xb0) || (flag == 0x90)) return false;
1117 } else if(SiS_Pr->ChipType >= SIS_661) return false;
1118 return true;
1119 }
1120 #endif
1121
1122 #ifdef CONFIG_FB_SIS_315
1123 static bool
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)1124 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1125 {
1126 if(SiS_Pr->ChipType >= SIS_315H) {
1127 /* YPrPb = 0x08 */
1128 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1129 }
1130 return false;
1131 }
1132 #endif
1133
1134 #ifdef CONFIG_FB_SIS_315
1135 static bool
SiS_IsChScart(struct SiS_Private * SiS_Pr)1136 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1137 {
1138 if(SiS_Pr->ChipType >= SIS_315H) {
1139 /* Scart = 0x04 */
1140 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1141 }
1142 return false;
1143 }
1144 #endif
1145
1146 #ifdef CONFIG_FB_SIS_315
1147 static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)1148 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1149 {
1150 unsigned short flag;
1151
1152 if(SiS_Pr->ChipType >= SIS_315H) {
1153 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1154 if(flag & SetCRT2ToTV) return true;
1155 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1156 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
1157 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
1158 } else {
1159 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1160 if(flag & SetCRT2ToTV) return true;
1161 }
1162 return false;
1163 }
1164 #endif
1165
1166 #ifdef CONFIG_FB_SIS_315
1167 static bool
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)1168 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1169 {
1170 unsigned short flag;
1171
1172 if(SiS_Pr->ChipType >= SIS_315H) {
1173 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1174 if(flag & SetCRT2ToLCD) return true;
1175 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1176 if(flag & SetToLCDA) return true;
1177 } else {
1178 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1179 if(flag & SetCRT2ToLCD) return true;
1180 }
1181 return false;
1182 }
1183 #endif
1184
1185 static bool
SiS_HaveBridge(struct SiS_Private * SiS_Pr)1186 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1187 {
1188 unsigned short flag;
1189
1190 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1191 return true;
1192 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1193 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1194 if((flag == 1) || (flag == 2)) return true;
1195 }
1196 return false;
1197 }
1198
1199 static bool
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)1200 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1201 {
1202 unsigned short flag;
1203
1204 if(SiS_HaveBridge(SiS_Pr)) {
1205 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1206 if(SiS_Pr->ChipType < SIS_315H) {
1207 flag &= 0xa0;
1208 if((flag == 0x80) || (flag == 0x20)) return true;
1209 } else {
1210 flag &= 0x50;
1211 if((flag == 0x40) || (flag == 0x10)) return true;
1212 }
1213 }
1214 return false;
1215 }
1216
1217 static bool
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)1218 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1219 {
1220 unsigned short flag1;
1221
1222 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1223 if(flag1 & (SetInSlaveMode >> 8)) return true;
1224 return false;
1225 }
1226
1227 /*********************************************/
1228 /* GET VIDEO BRIDGE CONFIG INFO */
1229 /*********************************************/
1230
1231 /* Setup general purpose IO for Chrontel communication */
1232 #ifdef CONFIG_FB_SIS_300
1233 void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)1234 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1235 {
1236 unsigned int acpibase;
1237 unsigned short temp;
1238
1239 if(!(SiS_Pr->SiS_ChSW)) return;
1240
1241 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1242 acpibase &= 0xFFFF;
1243 if(!acpibase) return;
1244 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
1245 temp &= 0xFEFF;
1246 SiS_SetRegShort((acpibase + 0x3c), temp);
1247 temp = SiS_GetRegShort((acpibase + 0x3c));
1248 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
1249 temp &= 0xFEFF;
1250 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1251 SiS_SetRegShort((acpibase + 0x3a), temp);
1252 temp = SiS_GetRegShort((acpibase + 0x3a));
1253 }
1254 #endif
1255
1256 void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)1257 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1258 unsigned short ModeIdIndex, int checkcrt2mode)
1259 {
1260 unsigned short tempax, tempbx, temp;
1261 unsigned short modeflag, resinfo = 0;
1262
1263 SiS_Pr->SiS_SetFlag = 0;
1264
1265 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1266
1267 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1268
1269 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1270 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1271 }
1272
1273 tempbx = 0;
1274
1275 if(SiS_HaveBridge(SiS_Pr)) {
1276
1277 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1278 tempbx |= temp;
1279 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1280 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1281 tempbx |= tempax;
1282
1283 #ifdef CONFIG_FB_SIS_315
1284 if(SiS_Pr->ChipType >= SIS_315H) {
1285 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1286 if(ModeNo == 0x03) {
1287 /* Mode 0x03 is never in driver mode */
1288 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1289 }
1290 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1291 /* Reset LCDA setting if not driver mode */
1292 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1293 }
1294 if(IS_SIS650) {
1295 if(SiS_Pr->SiS_UseLCDA) {
1296 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1297 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1298 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1299 }
1300 }
1301 }
1302 }
1303 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1304 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1305 tempbx |= SetCRT2ToLCDA;
1306 }
1307 }
1308
1309 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1310 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1311 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1312 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1313 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1314 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1315 tempbx |= SetCRT2ToYPbPr525750;
1316 }
1317 }
1318 }
1319
1320 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1321 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1322 if(temp & SetToLCDA) {
1323 tempbx |= SetCRT2ToLCDA;
1324 }
1325 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1326 if(temp & EnableCHYPbPr) {
1327 tempbx |= SetCRT2ToCHYPbPr;
1328 }
1329 }
1330 }
1331 }
1332
1333 #endif /* CONFIG_FB_SIS_315 */
1334
1335 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1336 tempbx &= ~(SetCRT2ToRAMDAC);
1337 }
1338
1339 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1340 temp = SetCRT2ToSVIDEO |
1341 SetCRT2ToAVIDEO |
1342 SetCRT2ToSCART |
1343 SetCRT2ToLCDA |
1344 SetCRT2ToLCD |
1345 SetCRT2ToRAMDAC |
1346 SetCRT2ToHiVision |
1347 SetCRT2ToYPbPr525750;
1348 } else {
1349 if(SiS_Pr->ChipType >= SIS_315H) {
1350 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1351 temp = SetCRT2ToAVIDEO |
1352 SetCRT2ToSVIDEO |
1353 SetCRT2ToSCART |
1354 SetCRT2ToLCDA |
1355 SetCRT2ToLCD |
1356 SetCRT2ToCHYPbPr;
1357 } else {
1358 temp = SetCRT2ToLCDA |
1359 SetCRT2ToLCD;
1360 }
1361 } else {
1362 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1363 temp = SetCRT2ToTV | SetCRT2ToLCD;
1364 } else {
1365 temp = SetCRT2ToLCD;
1366 }
1367 }
1368 }
1369
1370 if(!(tempbx & temp)) {
1371 tempax = DisableCRT2Display;
1372 tempbx = 0;
1373 }
1374
1375 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1376
1377 unsigned short clearmask = ( DriverMode |
1378 DisableCRT2Display |
1379 LoadDACFlag |
1380 SetNotSimuMode |
1381 SetInSlaveMode |
1382 SetPALTV |
1383 SwitchCRT2 |
1384 SetSimuScanMode );
1385
1386 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1387 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1388 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1389 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1390 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1391 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1392
1393 } else {
1394
1395 if(SiS_Pr->ChipType >= SIS_315H) {
1396 if(tempbx & SetCRT2ToLCDA) {
1397 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1398 }
1399 }
1400 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1401 if(tempbx & SetCRT2ToTV) {
1402 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1403 }
1404 }
1405 if(tempbx & SetCRT2ToLCD) {
1406 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1407 }
1408 if(SiS_Pr->ChipType >= SIS_315H) {
1409 if(tempbx & SetCRT2ToLCDA) {
1410 tempbx |= SetCRT2ToLCD;
1411 }
1412 }
1413
1414 }
1415
1416 if(tempax & DisableCRT2Display) {
1417 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1418 tempbx = SetSimuScanMode | DisableCRT2Display;
1419 }
1420 }
1421
1422 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1423
1424 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1425 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1426 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1427 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1428 modeflag &= (~CRT2Mode);
1429 }
1430 }
1431
1432 if(!(tempbx & SetSimuScanMode)) {
1433 if(tempbx & SwitchCRT2) {
1434 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1435 if(resinfo != SIS_RI_1600x1200) {
1436 tempbx |= SetSimuScanMode;
1437 }
1438 }
1439 } else {
1440 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1441 if(!(tempbx & DriverMode)) {
1442 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1443 tempbx |= SetSimuScanMode;
1444 }
1445 }
1446 }
1447 }
1448 }
1449
1450 if(!(tempbx & DisableCRT2Display)) {
1451 if(tempbx & DriverMode) {
1452 if(tempbx & SetSimuScanMode) {
1453 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1454 if(resinfo != SIS_RI_1600x1200) {
1455 tempbx |= SetInSlaveMode;
1456 }
1457 }
1458 }
1459 } else {
1460 tempbx |= SetInSlaveMode;
1461 }
1462 }
1463
1464 }
1465
1466 SiS_Pr->SiS_VBInfo = tempbx;
1467
1468 #ifdef CONFIG_FB_SIS_300
1469 if(SiS_Pr->ChipType == SIS_630) {
1470 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1471 }
1472 #endif
1473
1474 #if 0
1475 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1476 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1477 #endif
1478 }
1479
1480 /*********************************************/
1481 /* DETERMINE YPbPr MODE */
1482 /*********************************************/
1483
1484 void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1485 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1486 {
1487
1488 unsigned char temp;
1489
1490 /* Note: This variable is only used on 30xLV systems.
1491 * CR38 has a different meaning on LVDS/CH7019 systems.
1492 * On 661 and later, these bits moved to CR35.
1493 *
1494 * On 301, 301B, only HiVision 1080i is supported.
1495 * On 30xLV, 301C, only YPbPr 1080i is supported.
1496 */
1497
1498 SiS_Pr->SiS_YPbPr = 0;
1499 if(SiS_Pr->ChipType >= SIS_661) return;
1500
1501 if(SiS_Pr->SiS_VBType) {
1502 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1503 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1504 }
1505 }
1506
1507 if(SiS_Pr->ChipType >= SIS_315H) {
1508 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1509 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1510 if(temp & 0x08) {
1511 switch((temp >> 4)) {
1512 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1513 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1514 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1515 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1516 }
1517 }
1518 }
1519 }
1520
1521 }
1522
1523 /*********************************************/
1524 /* DETERMINE TVMode flag */
1525 /*********************************************/
1526
1527 void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1528 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1529 {
1530 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1531 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1532 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1533
1534 SiS_Pr->SiS_TVMode = 0;
1535
1536 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1537 if(SiS_Pr->UseCustomMode) return;
1538
1539 if(ModeNo > 0x13) {
1540 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1541 }
1542
1543 if(SiS_Pr->ChipType < SIS_661) {
1544
1545 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1546
1547 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1548 temp = 0;
1549 if((SiS_Pr->ChipType == SIS_630) ||
1550 (SiS_Pr->ChipType == SIS_730)) {
1551 temp = 0x35;
1552 romindex = 0xfe;
1553 } else if(SiS_Pr->ChipType >= SIS_315H) {
1554 temp = 0x38;
1555 if(SiS_Pr->ChipType < XGI_20) {
1556 romindex = 0xf3;
1557 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1558 }
1559 }
1560 if(temp) {
1561 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1562 OutputSelect = ROMAddr[romindex];
1563 if(!(OutputSelect & EnablePALMN)) {
1564 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1565 }
1566 }
1567 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1568 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1569 if(temp1 & EnablePALM) { /* 0x40 */
1570 SiS_Pr->SiS_TVMode |= TVSetPALM;
1571 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1572 } else if(temp1 & EnablePALN) { /* 0x80 */
1573 SiS_Pr->SiS_TVMode |= TVSetPALN;
1574 }
1575 } else {
1576 if(temp1 & EnableNTSCJ) { /* 0x40 */
1577 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1578 }
1579 }
1580 }
1581 /* Translate HiVision/YPbPr to our new flags */
1582 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1583 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1584 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1585 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1586 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1587 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1588 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1589 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1590 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1591 SiS_Pr->SiS_TVMode |= TVSetPAL;
1592 }
1593 }
1594 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1595 if(SiS_Pr->SiS_CHOverScan) {
1596 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1597 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1598 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1599 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1600 }
1601 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1602 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1603 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1604 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1605 }
1606 }
1607 if(SiS_Pr->SiS_CHSOverScan) {
1608 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1609 }
1610 }
1611 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1612 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1613 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1614 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1615 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1616 } else {
1617 if(temp & EnableNTSCJ) {
1618 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1619 }
1620 }
1621 }
1622 }
1623
1624 } else { /* 661 and later */
1625
1626 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1627 if(temp1 & 0x01) {
1628 SiS_Pr->SiS_TVMode |= TVSetPAL;
1629 if(temp1 & 0x08) {
1630 SiS_Pr->SiS_TVMode |= TVSetPALN;
1631 } else if(temp1 & 0x04) {
1632 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1633 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1634 }
1635 SiS_Pr->SiS_TVMode |= TVSetPALM;
1636 }
1637 } else {
1638 if(temp1 & 0x02) {
1639 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1640 }
1641 }
1642 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1643 if(SiS_Pr->SiS_CHOverScan) {
1644 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1645 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1646 }
1647 }
1648 }
1649 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1650 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1651 temp1 &= 0xe0;
1652 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1653 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1654 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1655 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1656 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1657 }
1658 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1659 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1660 SiS_Pr->SiS_TVMode |= TVAspect169;
1661 } else {
1662 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1663 if(temp1 & 0x02) {
1664 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1665 SiS_Pr->SiS_TVMode |= TVAspect169;
1666 } else {
1667 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1668 }
1669 } else {
1670 SiS_Pr->SiS_TVMode |= TVAspect43;
1671 }
1672 }
1673 }
1674 }
1675 }
1676
1677 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1678
1679 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1680
1681 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1682 SiS_Pr->SiS_TVMode |= TVSetPAL;
1683 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1684 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1685 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1686 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1687 }
1688 }
1689
1690 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1691 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1692 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1693 }
1694 }
1695
1696 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1697 if(resinfo == SIS_RI_1024x768) {
1698 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1699 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1700 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1701 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1702 }
1703 }
1704 }
1705
1706 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1707 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1708 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1709 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1710 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1711 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1712 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1713 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1714 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1715 }
1716 }
1717
1718 }
1719
1720 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1721 }
1722
1723 /*********************************************/
1724 /* GET LCD INFO */
1725 /*********************************************/
1726
1727 static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1728 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1729 {
1730 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1731 /* Translate my LCDResInfo to BIOS value */
1732 switch(temp) {
1733 case Panel_1280x768_2: temp = Panel_1280x768; break;
1734 case Panel_1280x800_2: temp = Panel_1280x800; break;
1735 case Panel_1280x854: temp = Panel661_1280x854; break;
1736 }
1737 return temp;
1738 }
1739
1740 static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1741 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1742 {
1743 #ifdef CONFIG_FB_SIS_315
1744 unsigned char *ROMAddr;
1745 unsigned short temp;
1746
1747 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1748 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1749 SiS_Pr->SiS_NeedRomModeData = true;
1750 SiS_Pr->PanelHT = temp;
1751 }
1752 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1753 SiS_Pr->SiS_NeedRomModeData = true;
1754 SiS_Pr->PanelVT = temp;
1755 }
1756 SiS_Pr->PanelHRS = SISGETROMW(10);
1757 SiS_Pr->PanelHRE = SISGETROMW(12);
1758 SiS_Pr->PanelVRS = SISGETROMW(14);
1759 SiS_Pr->PanelVRE = SISGETROMW(16);
1760 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1761 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1762 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1763 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1764 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1765 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1766 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1767
1768 }
1769 #endif
1770 }
1771
1772 static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1773 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1774 const unsigned char *nonscalingmodes)
1775 {
1776 int i = 0;
1777 while(nonscalingmodes[i] != 0xff) {
1778 if(nonscalingmodes[i++] == resinfo) {
1779 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1780 (SiS_Pr->UsePanelScaler == -1)) {
1781 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1782 }
1783 break;
1784 }
1785 }
1786 }
1787
1788 void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1789 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1790 {
1791 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1792 bool panelcanscale = false;
1793 #ifdef CONFIG_FB_SIS_300
1794 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1795 static const unsigned char SiS300SeriesLCDRes[] =
1796 { 0, 1, 2, 3, 7, 4, 5, 8,
1797 0, 0, 10, 0, 0, 0, 0, 15 };
1798 #endif
1799 #ifdef CONFIG_FB_SIS_315
1800 unsigned char *myptr = NULL;
1801 #endif
1802
1803 SiS_Pr->SiS_LCDResInfo = 0;
1804 SiS_Pr->SiS_LCDTypeInfo = 0;
1805 SiS_Pr->SiS_LCDInfo = 0;
1806 SiS_Pr->PanelHRS = 999; /* HSync start */
1807 SiS_Pr->PanelHRE = 999; /* HSync end */
1808 SiS_Pr->PanelVRS = 999; /* VSync start */
1809 SiS_Pr->PanelVRE = 999; /* VSync end */
1810 SiS_Pr->SiS_NeedRomModeData = false;
1811
1812 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1813 SiS_Pr->Alternate1600x1200 = false;
1814
1815 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1816
1817 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1818
1819 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1820 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1821 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1822 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1823 }
1824
1825 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1826
1827 /* For broken BIOSes: Assume 1024x768 */
1828 if(temp == 0) temp = 0x02;
1829
1830 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1831 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1832 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1833 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1834 } else {
1835 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1836 }
1837 temp &= 0x0f;
1838 #ifdef CONFIG_FB_SIS_300
1839 if(SiS_Pr->ChipType < SIS_315H) {
1840 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1841 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1842 if(temp < 0x0f) temp &= 0x07;
1843 }
1844 /* Translate 300 series LCDRes to 315 series for unified usage */
1845 temp = SiS300SeriesLCDRes[temp];
1846 }
1847 #endif
1848
1849 /* Translate to our internal types */
1850 #ifdef CONFIG_FB_SIS_315
1851 if(SiS_Pr->ChipType == SIS_550) {
1852 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1853 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1854 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1855 } else if(SiS_Pr->ChipType >= SIS_661) {
1856 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1857 }
1858 #endif
1859
1860 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1861 if(temp == Panel310_1280x768) {
1862 temp = Panel_1280x768_2;
1863 }
1864 if(SiS_Pr->SiS_ROMNew) {
1865 if(temp == Panel661_1280x800) {
1866 temp = Panel_1280x800_2;
1867 }
1868 }
1869 }
1870
1871 SiS_Pr->SiS_LCDResInfo = temp;
1872
1873 #ifdef CONFIG_FB_SIS_300
1874 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1875 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1876 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1877 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1878 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1879 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1880 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1881 }
1882 }
1883 #endif
1884
1885 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1886 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1887 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1888 } else {
1889 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1890 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1891 }
1892
1893 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1894 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1895 /* Need temp below! */
1896
1897 /* These must/can't scale no matter what */
1898 switch(SiS_Pr->SiS_LCDResInfo) {
1899 case Panel_320x240_1:
1900 case Panel_320x240_2:
1901 case Panel_320x240_3:
1902 case Panel_1280x960:
1903 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1904 break;
1905 case Panel_640x480:
1906 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1907 }
1908
1909 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1910
1911 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1912 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1913
1914 /* Dual link, Pass 1:1 BIOS default, etc. */
1915 #ifdef CONFIG_FB_SIS_315
1916 if(SiS_Pr->ChipType >= SIS_661) {
1917 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1918 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1919 }
1920 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1921 if(SiS_Pr->SiS_ROMNew) {
1922 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1923 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1924 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1925 }
1926 }
1927 } else if(SiS_Pr->ChipType >= SIS_315H) {
1928 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1929 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1930 }
1931 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1932 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1933 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1934 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1935 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1936 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1937 }
1938 } else if(!(SiS_Pr->SiS_ROMNew)) {
1939 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1940 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1941 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1942 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1943 }
1944 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1945 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1946 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1947 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1948 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1949 }
1950 }
1951 }
1952 }
1953 #endif
1954
1955 /* Pass 1:1 */
1956 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1957 /* Always center screen on LVDS (if scaling is disabled) */
1958 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1959 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1960 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1961 /* Always center screen on SiS LVDS (if scaling is disabled) */
1962 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1963 } else {
1964 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1965 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1966 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1967 }
1968 }
1969
1970 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1971 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1972
1973 switch(SiS_Pr->SiS_LCDResInfo) {
1974 case Panel_320x240_1:
1975 case Panel_320x240_2:
1976 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1977 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1978 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1979 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1980 break;
1981 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1982 SiS_Pr->PanelVRE = 3;
1983 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1984 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1985 break;
1986 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1987 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1988 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1989 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1990 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1991 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1992 break;
1993 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1994 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1995 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1996 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1997 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1998 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1999 break;
2000 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2001 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2002 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2003 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2004 if(SiS_Pr->ChipType < SIS_315H) {
2005 SiS_Pr->PanelHRS = 23;
2006 SiS_Pr->PanelVRE = 5;
2007 }
2008 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2009 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2010 SiS_GetLCDInfoBIOS(SiS_Pr);
2011 break;
2012 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
2013 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2014 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2015 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2016 if(SiS_Pr->ChipType < SIS_315H) {
2017 SiS_Pr->PanelHRS = 23;
2018 SiS_Pr->PanelVRE = 5;
2019 }
2020 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2021 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2022 break;
2023 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
2024 break;
2025 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
2026 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
2027 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
2028 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
2029 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2030 /* Data above for TMDS (projector); get from BIOS for LVDS */
2031 SiS_GetLCDInfoBIOS(SiS_Pr);
2032 break;
2033 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2034 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2035 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
2036 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2037 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2038 } else {
2039 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
2040 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2041 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2042 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2043 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2044 }
2045 break;
2046 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2047 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
2048 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2049 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2050 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2051 SiS_GetLCDInfoBIOS(SiS_Pr);
2052 break;
2053 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2054 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
2055 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
2056 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2057 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2058 SiS_GetLCDInfoBIOS(SiS_Pr);
2059 break;
2060 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2061 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
2062 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2063 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2064 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2065 SiS_GetLCDInfoBIOS(SiS_Pr);
2066 break;
2067 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
2068 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
2069 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
2070 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2071 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2072 SiS_GetLCDInfoBIOS(SiS_Pr);
2073 break;
2074 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
2075 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
2076 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2077 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2078 if(resinfo == SIS_RI_1280x1024) {
2079 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2080 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2081 }
2082 break;
2083 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2084 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2085 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2086 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2087 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2088 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2089 SiS_GetLCDInfoBIOS(SiS_Pr);
2090 break;
2091 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2092 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2093 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2094 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2095 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2096 SiS_GetLCDInfoBIOS(SiS_Pr);
2097 break;
2098 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2099 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
2100 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
2101 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2102 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2103 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2104 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2105 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
2106 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
2107 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
2108 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2109 SiS_Pr->Alternate1600x1200 = true;
2110 }
2111 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2112 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
2113 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2114 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2115 }
2116 SiS_GetLCDInfoBIOS(SiS_Pr);
2117 break;
2118 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2119 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
2120 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
2121 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2122 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2123 SiS_GetLCDInfoBIOS(SiS_Pr);
2124 break;
2125 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2126 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2127 break;
2128 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
2129 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2130 break;
2131 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
2132 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2133 break;
2134 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2135 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2136 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
2137 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
2138 if(SiS_Pr->CP_PreferredIndex != -1) {
2139 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2140 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2141 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2142 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2143 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2144 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2145 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2146 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2147 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2148 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2149 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2150 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2151 if(SiS_Pr->CP_PrefClock) {
2152 int idx;
2153 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2154 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2155 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2156 else idx = VCLK_CUSTOM_315;
2157 SiS_Pr->SiS_VCLKData[idx].CLOCK =
2158 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2159 SiS_Pr->SiS_VCLKData[idx].SR2B =
2160 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2161 SiS_Pr->SiS_VCLKData[idx].SR2C =
2162 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2163 }
2164 }
2165 break;
2166 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2167 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2168 break;
2169 }
2170
2171 /* Special cases */
2172 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
2173 (SiS_Pr->SiS_IF_DEF_DSTN) ||
2174 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2175 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2176 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2177 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2178 SiS_Pr->PanelHRS = 999;
2179 SiS_Pr->PanelHRE = 999;
2180 }
2181
2182 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2183 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2184 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2185 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2186 SiS_Pr->PanelVRS = 999;
2187 SiS_Pr->PanelVRE = 999;
2188 }
2189
2190 /* DontExpand overrule */
2191 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2192
2193 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2194 /* No scaling for this mode on any panel (LCD=CRT2)*/
2195 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2196 }
2197
2198 switch(SiS_Pr->SiS_LCDResInfo) {
2199
2200 case Panel_Custom:
2201 case Panel_1152x864:
2202 case Panel_1280x768: /* TMDS only */
2203 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2204 break;
2205
2206 case Panel_800x600: {
2207 static const unsigned char nonscalingmodes[] = {
2208 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2209 };
2210 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2211 break;
2212 }
2213 case Panel_1024x768: {
2214 static const unsigned char nonscalingmodes[] = {
2215 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2216 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2217 0xff
2218 };
2219 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2220 break;
2221 }
2222 case Panel_1280x720: {
2223 static const unsigned char nonscalingmodes[] = {
2224 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2225 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2226 0xff
2227 };
2228 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2229 if(SiS_Pr->PanelHT == 1650) {
2230 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2231 }
2232 break;
2233 }
2234 case Panel_1280x768_2: { /* LVDS only */
2235 static const unsigned char nonscalingmodes[] = {
2236 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2237 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2238 SIS_RI_1152x768,0xff
2239 };
2240 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2241 switch(resinfo) {
2242 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2243 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2244 }
2245 break;
2246 }
2247 break;
2248 }
2249 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
2250 static const unsigned char nonscalingmodes[] = {
2251 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2252 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2253 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2254 };
2255 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2256 break;
2257 }
2258 case Panel_1280x800_2: { /* SiS LVDS */
2259 static const unsigned char nonscalingmodes[] = {
2260 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2261 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2262 SIS_RI_1152x768,0xff
2263 };
2264 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2265 switch(resinfo) {
2266 case SIS_RI_1280x720:
2267 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
2268 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2269 }
2270 break;
2271 }
2272 break;
2273 }
2274 case Panel_1280x854: { /* SiS LVDS */
2275 static const unsigned char nonscalingmodes[] = {
2276 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2277 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2278 SIS_RI_1152x768,0xff
2279 };
2280 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2281 switch(resinfo) {
2282 case SIS_RI_1280x720:
2283 case SIS_RI_1280x768:
2284 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2285 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2286 }
2287 break;
2288 }
2289 break;
2290 }
2291 case Panel_1280x960: {
2292 static const unsigned char nonscalingmodes[] = {
2293 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2294 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2295 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2296 SIS_RI_1280x854,0xff
2297 };
2298 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2299 break;
2300 }
2301 case Panel_1280x1024: {
2302 static const unsigned char nonscalingmodes[] = {
2303 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2304 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2305 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2306 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2307 };
2308 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2309 break;
2310 }
2311 case Panel_1400x1050: {
2312 static const unsigned char nonscalingmodes[] = {
2313 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2314 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2315 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2316 SIS_RI_1280x960,0xff
2317 };
2318 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2319 switch(resinfo) {
2320 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2321 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2322 }
2323 break;
2324 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2325 break;
2326 }
2327 break;
2328 }
2329 case Panel_1600x1200: {
2330 static const unsigned char nonscalingmodes[] = {
2331 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2332 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2333 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2334 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2335 };
2336 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2337 break;
2338 }
2339 case Panel_1680x1050: {
2340 static const unsigned char nonscalingmodes[] = {
2341 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2342 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2343 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2344 SIS_RI_1360x1024,0xff
2345 };
2346 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2347 break;
2348 }
2349 }
2350 }
2351
2352 #ifdef CONFIG_FB_SIS_300
2353 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2354 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2355 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2356 }
2357 }
2358
2359 if(SiS_Pr->ChipType < SIS_315H) {
2360 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2361 if(SiS_Pr->SiS_UseROM) {
2362 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2363 if(!(ROMAddr[0x235] & 0x02)) {
2364 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2365 }
2366 }
2367 }
2368 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2369 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2370 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2371 }
2372 }
2373 }
2374 #endif
2375
2376 /* Special cases */
2377
2378 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2379 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2380 }
2381
2382 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2383 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2384 }
2385
2386 switch(SiS_Pr->SiS_LCDResInfo) {
2387 case Panel_640x480:
2388 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2389 break;
2390 case Panel_1280x800:
2391 /* Don't pass 1:1 by default (TMDS special) */
2392 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2393 break;
2394 case Panel_1280x960:
2395 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2396 break;
2397 case Panel_Custom:
2398 if((!SiS_Pr->CP_PrefClock) ||
2399 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2400 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2401 }
2402 break;
2403 }
2404
2405 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2406 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2407 }
2408
2409 /* (In)validate LCDPass11 flag */
2410 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2411 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2412 }
2413
2414 /* LVDS DDA */
2415 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2416
2417 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2418 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2419 if(ModeNo == 0x12) {
2420 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2421 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2422 }
2423 } else if(ModeNo > 0x13) {
2424 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2425 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2426 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2427 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2428 }
2429 }
2430 }
2431 }
2432 }
2433 }
2434
2435 if(modeflag & HalfDCLK) {
2436 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2437 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2438 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2439 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2440 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2441 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2442 } else if(ModeNo > 0x13) {
2443 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2444 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2445 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2446 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2447 }
2448 }
2449 }
2450
2451 }
2452
2453 /* VESA timing */
2454 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2455 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2456 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2457 }
2458 } else {
2459 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2460 }
2461
2462 #if 0
2463 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2464 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2465 #endif
2466 }
2467
2468 /*********************************************/
2469 /* GET VCLK */
2470 /*********************************************/
2471
2472 unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2473 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2474 unsigned short RefreshRateTableIndex)
2475 {
2476 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2477 unsigned short resinfo, tempbx;
2478 const unsigned char *CHTVVCLKPtr = NULL;
2479
2480 if(ModeNo <= 0x13) {
2481 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2482 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2483 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2484 VCLKIndexGENCRT = VCLKIndexGEN;
2485 } else {
2486 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2487 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2488 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2489 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2490 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2491 }
2492
2493 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2494
2495 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2496
2497 CRT2Index >>= 6;
2498 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2499
2500 if(SiS_Pr->ChipType < SIS_315H) {
2501 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2502 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2503 VCLKIndex = VCLKIndexGEN;
2504 }
2505 } else {
2506 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2507 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2508 switch(resinfo) {
2509 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2510 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2511 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2512 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2513 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2514 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2515 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2516 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2517 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2518 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2519 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2520 default: VCLKIndex = VCLKIndexGEN;
2521 }
2522
2523 if(ModeNo <= 0x13) {
2524 if(SiS_Pr->ChipType <= SIS_315PRO) {
2525 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2526 } else {
2527 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2528 }
2529 }
2530 if(SiS_Pr->ChipType <= SIS_315PRO) {
2531 if(VCLKIndex == 0) VCLKIndex = 0x41;
2532 if(VCLKIndex == 1) VCLKIndex = 0x43;
2533 if(VCLKIndex == 4) VCLKIndex = 0x44;
2534 }
2535 }
2536 }
2537
2538 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2539
2540 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2541 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2542 else VCLKIndex = HiTVVCLK;
2543 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2544 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2545 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2546 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2547 else VCLKIndex = TVVCLK;
2548
2549 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2550 else VCLKIndex += TVCLKBASE_315;
2551
2552 } else { /* VGA2 */
2553
2554 VCLKIndex = VCLKIndexGENCRT;
2555 if(SiS_Pr->ChipType < SIS_315H) {
2556 if(ModeNo > 0x13) {
2557 if( (SiS_Pr->ChipType == SIS_630) &&
2558 (SiS_Pr->ChipRevision >= 0x30)) {
2559 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2560 }
2561 /* Better VGA2 clock for 1280x1024@75 */
2562 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2563 }
2564 }
2565 }
2566
2567 } else { /* If not programming CRT2 */
2568
2569 VCLKIndex = VCLKIndexGENCRT;
2570 if(SiS_Pr->ChipType < SIS_315H) {
2571 if(ModeNo > 0x13) {
2572 if( (SiS_Pr->ChipType != SIS_630) &&
2573 (SiS_Pr->ChipType != SIS_300) ) {
2574 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2575 }
2576 }
2577 }
2578 }
2579
2580 } else { /* LVDS */
2581
2582 VCLKIndex = CRT2Index;
2583
2584 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2585
2586 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2587
2588 VCLKIndex &= 0x1f;
2589 tempbx = 0;
2590 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2591 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2592 tempbx += 2;
2593 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2594 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2595 }
2596 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2597 tempbx = 4;
2598 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2599 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2600 tempbx = 6;
2601 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2602 }
2603 }
2604 switch(tempbx) {
2605 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2606 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2607 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2608 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2609 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2610 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2611 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2612 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2613 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2614 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2615 }
2616 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2617
2618 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2619
2620 if(SiS_Pr->ChipType < SIS_315H) {
2621 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2622 } else {
2623 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2624 }
2625
2626 #ifdef CONFIG_FB_SIS_300
2627 /* Special Timing: Barco iQ Pro R series */
2628 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2629
2630 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2631 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2632 if(SiS_Pr->ChipType < SIS_315H) {
2633 VCLKIndex = VCLK34_300;
2634 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2635 } else {
2636 VCLKIndex = VCLK34_315;
2637 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2638 }
2639 }
2640 #endif
2641
2642 } else {
2643
2644 VCLKIndex = VCLKIndexGENCRT;
2645 if(SiS_Pr->ChipType < SIS_315H) {
2646 if(ModeNo > 0x13) {
2647 if( (SiS_Pr->ChipType == SIS_630) &&
2648 (SiS_Pr->ChipRevision >= 0x30) ) {
2649 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2650 }
2651 }
2652 }
2653 }
2654
2655 } else { /* if not programming CRT2 */
2656
2657 VCLKIndex = VCLKIndexGENCRT;
2658 if(SiS_Pr->ChipType < SIS_315H) {
2659 if(ModeNo > 0x13) {
2660 if( (SiS_Pr->ChipType != SIS_630) &&
2661 (SiS_Pr->ChipType != SIS_300) ) {
2662 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2663 }
2664 #if 0
2665 if(SiS_Pr->ChipType == SIS_730) {
2666 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2667 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2668 }
2669 #endif
2670 }
2671 }
2672
2673 }
2674
2675 }
2676
2677 return VCLKIndex;
2678 }
2679
2680 /*********************************************/
2681 /* SET CRT2 MODE TYPE REGISTERS */
2682 /*********************************************/
2683
2684 static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2685 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2686 {
2687 unsigned short i, j, modeflag, tempah=0;
2688 short tempcl;
2689 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2690 unsigned short tempbl;
2691 #endif
2692 #ifdef CONFIG_FB_SIS_315
2693 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2694 unsigned short tempah2, tempbl2;
2695 #endif
2696
2697 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2698
2699 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2700
2701 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2702 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2703
2704 } else {
2705
2706 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2707 if(SiS_Pr->ChipType >= SIS_315H) {
2708 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2709 }
2710
2711 tempcl = SiS_Pr->SiS_ModeType;
2712
2713 if(SiS_Pr->ChipType < SIS_315H) {
2714
2715 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2716
2717 /* For 301BDH: (with LCD via LVDS) */
2718 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2719 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2720 tempbl &= 0xef;
2721 tempbl |= 0x02;
2722 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2723 tempbl |= 0x10;
2724 tempbl &= 0xfd;
2725 }
2726 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2727 }
2728
2729 if(ModeNo > 0x13) {
2730 tempcl -= ModeVGA;
2731 if(tempcl >= 0) {
2732 tempah = ((0x10 >> tempcl) | 0x80);
2733 }
2734 } else tempah = 0x80;
2735
2736 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2737
2738 #endif /* CONFIG_FB_SIS_300 */
2739
2740 } else {
2741
2742 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2743
2744 if(ModeNo > 0x13) {
2745 tempcl -= ModeVGA;
2746 if(tempcl >= 0) {
2747 tempah = (0x08 >> tempcl);
2748 if (tempah == 0) tempah = 1;
2749 tempah |= 0x40;
2750 }
2751 } else tempah = 0x40;
2752
2753 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2754
2755 #endif /* CONFIG_FB_SIS_315 */
2756
2757 }
2758
2759 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2760
2761 if(SiS_Pr->ChipType < SIS_315H) {
2762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2763 } else {
2764 #ifdef CONFIG_FB_SIS_315
2765 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2766 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2767 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2768 if(IS_SIS740) {
2769 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2770 } else {
2771 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2772 }
2773 }
2774 #endif
2775 }
2776
2777 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2778
2779 tempah = 0x01;
2780 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2781 tempah |= 0x02;
2782 }
2783 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2784 tempah ^= 0x05;
2785 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2786 tempah ^= 0x01;
2787 }
2788 }
2789
2790 if(SiS_Pr->ChipType < SIS_315H) {
2791
2792 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2793
2794 tempah = (tempah << 5) & 0xFF;
2795 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2796 tempah = (tempah >> 5) & 0xFF;
2797
2798 } else {
2799
2800 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2801 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2802 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2803 tempah &= ~0x08;
2804
2805 }
2806
2807 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2808 tempah |= 0x10;
2809 }
2810
2811 tempah |= 0x80;
2812 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2813 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2814 }
2815
2816 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2817 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2818 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2819 tempah |= 0x20;
2820 }
2821 }
2822 }
2823
2824 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2825
2826 tempah = 0x80;
2827 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2828 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2829 }
2830
2831 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2832
2833 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2834 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2835 tempah |= 0x40;
2836 }
2837 }
2838
2839 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2840
2841 } else { /* LVDS */
2842
2843 if(SiS_Pr->ChipType >= SIS_315H) {
2844
2845 #ifdef CONFIG_FB_SIS_315
2846 /* LVDS can only be slave in 8bpp modes */
2847 tempah = 0x80;
2848 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2849 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2850 tempah |= 0x02;
2851 }
2852 }
2853
2854 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2855
2856 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2857
2858 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2859
2860 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2861 #endif
2862
2863 } else {
2864
2865 #ifdef CONFIG_FB_SIS_300
2866 tempah = 0;
2867 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2868 tempah |= 0x02;
2869 }
2870 tempah <<= 5;
2871
2872 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2873
2874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2875 #endif
2876
2877 }
2878
2879 }
2880
2881 } /* LCDA */
2882
2883 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2884
2885 if(SiS_Pr->ChipType >= SIS_315H) {
2886
2887 #ifdef CONFIG_FB_SIS_315
2888 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2889
2890 /* The following is nearly unpreditable and varies from machine
2891 * to machine. Especially the 301DH seems to be a real trouble
2892 * maker. Some BIOSes simply set the registers (like in the
2893 * NoLCD-if-statements here), some set them according to the
2894 * LCDA stuff. It is very likely that some machines are not
2895 * treated correctly in the following, very case-orientated
2896 * code. What do I do then...?
2897 */
2898
2899 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2900
2901 if(!(IS_SIS740)) {
2902 tempah = 0x04; /* For all bridges */
2903 tempbl = 0xfb;
2904 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2905 tempah = 0x00;
2906 if(SiS_IsDualEdge(SiS_Pr)) {
2907 tempbl = 0xff;
2908 }
2909 }
2910 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2911 }
2912
2913 /* The following two are responsible for eventually wrong colors
2914 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2915 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2916 * in a 650 box (Jake). What is the criteria?
2917 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2918 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2919 * chipset than the bridge revision.
2920 */
2921
2922 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2923 tempah = 0x30;
2924 tempbl = 0xc0;
2925 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2926 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2927 tempah = 0x00;
2928 tempbl = 0x00;
2929 }
2930 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2931 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2932 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2933 /* Fixes "TV-blue-bug" on 315+301 */
2934 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2935 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2936 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2937 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2938 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2939 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2940 tempah = 0x30; tempah2 = 0xc0;
2941 tempbl = 0xcf; tempbl2 = 0x3f;
2942 if(SiS_Pr->SiS_TVBlue == 0) {
2943 tempah = tempah2 = 0x00;
2944 } else if(SiS_Pr->SiS_TVBlue == -1) {
2945 /* Set on 651/M650, clear on 315/650 */
2946 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2947 tempah = tempah2 = 0x00;
2948 }
2949 }
2950 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2951 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2952 } else {
2953 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2954 tempbl = 0xcf; tempbl2 = 0x3f;
2955 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2956 tempah = tempah2 = 0x00;
2957 if(SiS_IsDualEdge(SiS_Pr)) {
2958 tempbl = tempbl2 = 0xff;
2959 }
2960 }
2961 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2962 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2963 }
2964
2965 if(IS_SIS740) {
2966 tempah = 0x80;
2967 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2968 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2969 } else {
2970 tempah = 0x00;
2971 tempbl = 0x7f;
2972 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2973 tempbl = 0xff;
2974 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2975 }
2976 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2977 }
2978
2979 #endif /* CONFIG_FB_SIS_315 */
2980
2981 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2982
2983 #ifdef CONFIG_FB_SIS_300
2984 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2985
2986 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2987 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2988 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2989 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2990 } else {
2991 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2992 }
2993 #endif
2994
2995 }
2996
2997 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2998 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2999 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3000 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3001 }
3002 }
3003
3004 } else { /* LVDS */
3005
3006 #ifdef CONFIG_FB_SIS_315
3007 if(SiS_Pr->ChipType >= SIS_315H) {
3008
3009 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3010
3011 tempah = 0x04;
3012 tempbl = 0xfb;
3013 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3014 tempah = 0x00;
3015 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3016 }
3017 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3018
3019 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3020 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3021 }
3022
3023 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3024
3025 } else if(SiS_Pr->ChipType == SIS_550) {
3026
3027 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3028 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3029
3030 }
3031
3032 }
3033 #endif
3034
3035 }
3036
3037 }
3038
3039 /*********************************************/
3040 /* GET RESOLUTION DATA */
3041 /*********************************************/
3042
3043 unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3044 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3045 {
3046 if(ModeNo <= 0x13)
3047 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3048 else
3049 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3050 }
3051
3052 static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3053 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3054 {
3055 unsigned short xres, yres, modeflag=0, resindex;
3056
3057 if(SiS_Pr->UseCustomMode) {
3058 xres = SiS_Pr->CHDisplay;
3059 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3060 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3061 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3062 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3063 return;
3064 }
3065
3066 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3067
3068 if(ModeNo <= 0x13) {
3069 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3070 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3071 } else {
3072 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3073 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3074 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3075 }
3076
3077 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3078
3079 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3080 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3081 if(yres == 350) yres = 400;
3082 }
3083 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3084 if(ModeNo == 0x12) yres = 400;
3085 }
3086 }
3087
3088 if(modeflag & HalfDCLK) xres <<= 1;
3089 if(modeflag & DoubleScanMode) yres <<= 1;
3090
3091 }
3092
3093 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3094
3095 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3096 switch(SiS_Pr->SiS_LCDResInfo) {
3097 case Panel_1024x768:
3098 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3099 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3100 if(yres == 350) yres = 357;
3101 if(yres == 400) yres = 420;
3102 if(yres == 480) yres = 525;
3103 }
3104 }
3105 break;
3106 case Panel_1280x1024:
3107 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3108 /* BIOS bug - does this regardless of scaling */
3109 if(yres == 400) yres = 405;
3110 }
3111 if(yres == 350) yres = 360;
3112 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3113 if(yres == 360) yres = 375;
3114 }
3115 break;
3116 case Panel_1600x1200:
3117 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3118 if(yres == 1024) yres = 1056;
3119 }
3120 break;
3121 }
3122 }
3123
3124 } else {
3125
3126 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3127 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3128 if(xres == 720) xres = 640;
3129 }
3130 } else if(xres == 720) xres = 640;
3131
3132 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3133 yres = 400;
3134 if(SiS_Pr->ChipType >= SIS_315H) {
3135 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3136 } else {
3137 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3138 }
3139 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3140 }
3141
3142 }
3143 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3144 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3145 }
3146
3147 /*********************************************/
3148 /* GET CRT2 TIMING DATA */
3149 /*********************************************/
3150
3151 static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)3152 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3153 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3154 unsigned short *ResIndex)
3155 {
3156 unsigned short tempbx=0, tempal=0, resinfo=0;
3157
3158 if(ModeNo <= 0x13) {
3159 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3160 } else {
3161 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3162 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3163 }
3164
3165 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3166
3167 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
3168
3169 tempbx = SiS_Pr->SiS_LCDResInfo;
3170 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3171
3172 /* patch index */
3173 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3174 if (resinfo == SIS_RI_1280x800) tempal = 9;
3175 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3176 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3177 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3178 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3179 if (resinfo == SIS_RI_1280x768) tempal = 9;
3180 }
3181
3182 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3183 /* Pass 1:1 only (center-screen handled outside) */
3184 /* This is never called for the panel's native resolution */
3185 /* since Pass1:1 will not be set in this case */
3186 tempbx = 100;
3187 if(ModeNo >= 0x13) {
3188 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3189 }
3190 }
3191
3192 #ifdef CONFIG_FB_SIS_315
3193 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3194 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3195 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3196 tempbx = 200;
3197 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3198 }
3199 }
3200 }
3201 #endif
3202
3203 } else { /* TV */
3204
3205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3206 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3207 tempbx = 2;
3208 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3209 tempbx = 13;
3210 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3211 }
3212 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3213 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3214 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3215 else tempbx = 5;
3216 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3217 } else {
3218 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3219 else tempbx = 4;
3220 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3221 }
3222
3223 }
3224
3225 tempal &= 0x3F;
3226
3227 if(ModeNo > 0x13) {
3228 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3229 switch(resinfo) {
3230 case SIS_RI_720x480:
3231 tempal = 6;
3232 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
3233 break;
3234 case SIS_RI_720x576:
3235 case SIS_RI_768x576:
3236 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3237 tempal = 6;
3238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3239 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
3240 }
3241 break;
3242 case SIS_RI_800x480:
3243 tempal = 4;
3244 break;
3245 case SIS_RI_512x384:
3246 case SIS_RI_1024x768:
3247 tempal = 7;
3248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3249 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
3250 }
3251 break;
3252 case SIS_RI_1280x720:
3253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3254 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3255 }
3256 break;
3257 }
3258 }
3259 }
3260
3261 *CRT2Index = tempbx;
3262 *ResIndex = tempal;
3263
3264 } else { /* LVDS, 301B-DH (if running on LCD) */
3265
3266 tempbx = 0;
3267 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3268
3269 tempbx = 90;
3270 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3271 tempbx = 92;
3272 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3273 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3274 }
3275 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3276 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3277 }
3278 if(tempbx != 99) {
3279 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3280 }
3281
3282 } else {
3283
3284 switch(SiS_Pr->SiS_LCDResInfo) {
3285 case Panel_640x480: tempbx = 12; break;
3286 case Panel_320x240_1: tempbx = 10; break;
3287 case Panel_320x240_2:
3288 case Panel_320x240_3: tempbx = 14; break;
3289 case Panel_800x600: tempbx = 16; break;
3290 case Panel_1024x600: tempbx = 18; break;
3291 case Panel_1152x768:
3292 case Panel_1024x768: tempbx = 20; break;
3293 case Panel_1280x768: tempbx = 22; break;
3294 case Panel_1280x1024: tempbx = 24; break;
3295 case Panel_1400x1050: tempbx = 26; break;
3296 case Panel_1600x1200: tempbx = 28; break;
3297 #ifdef CONFIG_FB_SIS_300
3298 case Panel_Barco1366: tempbx = 80; break;
3299 #endif
3300 }
3301
3302 switch(SiS_Pr->SiS_LCDResInfo) {
3303 case Panel_320x240_1:
3304 case Panel_320x240_2:
3305 case Panel_320x240_3:
3306 case Panel_640x480:
3307 break;
3308 default:
3309 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3310 }
3311
3312 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3313
3314 #ifdef CONFIG_FB_SIS_300
3315 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3316 tempbx = 82;
3317 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3318 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3319 tempbx = 84;
3320 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3321 }
3322 #endif
3323
3324 }
3325
3326 (*CRT2Index) = tempbx;
3327 (*ResIndex) = tempal & 0x1F;
3328 }
3329 }
3330
3331 static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3332 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3333 unsigned short RefreshRateTableIndex)
3334 {
3335 unsigned short tempax=0, tempbx=0, index, dotclock;
3336 unsigned short temp1=0, modeflag=0, tempcx=0;
3337
3338 SiS_Pr->SiS_RVBHCMAX = 1;
3339 SiS_Pr->SiS_RVBHCFACT = 1;
3340
3341 if(ModeNo <= 0x13) {
3342
3343 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3344 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3345
3346 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3347 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3348 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3349
3350 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3351
3352 } else {
3353
3354 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3355 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3356
3357 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3358 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3359 tempax &= 0x03FF;
3360 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3361 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3362 tempcx &= 0x0100;
3363 tempcx <<= 2;
3364 tempbx |= tempcx;
3365 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3366
3367 dotclock = 8;
3368
3369 }
3370
3371 if(temp1 & 0x01) tempbx |= 0x0100;
3372 if(temp1 & 0x20) tempbx |= 0x0200;
3373
3374 tempax += 5;
3375 tempax *= dotclock;
3376 if(modeflag & HalfDCLK) tempax <<= 1;
3377
3378 tempbx++;
3379
3380 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3381 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3382 }
3383
3384 static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3385 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3386 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3387 {
3388 unsigned short ResIndex;
3389
3390 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3391 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3392 if(SiS_Pr->UseCustomMode) {
3393 ResIndex = SiS_Pr->CHTotal;
3394 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3395 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3396 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3397 } else {
3398 if(ModeNo < 0x13) {
3399 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3400 } else {
3401 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3402 }
3403 if(ResIndex == 0x09) {
3404 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3405 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3406 }
3407 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3408 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3409 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3410 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3411 }
3412 } else {
3413 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3414 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3415 }
3416 } else {
3417 /* This handles custom modes and custom panels */
3418 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3419 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3420 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3421 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3422 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3423 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3424 }
3425 }
3426
3427 static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3428 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3429 unsigned short RefreshRateTableIndex)
3430 {
3431 unsigned short CRT2Index, ResIndex, backup;
3432 const struct SiS_LVDSData *LVDSData = NULL;
3433
3434 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3435
3436 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3437 SiS_Pr->SiS_RVBHCMAX = 1;
3438 SiS_Pr->SiS_RVBHCFACT = 1;
3439 SiS_Pr->SiS_NewFlickerMode = 0;
3440 SiS_Pr->SiS_RVBHRS = 50;
3441 SiS_Pr->SiS_RY1COE = 0;
3442 SiS_Pr->SiS_RY2COE = 0;
3443 SiS_Pr->SiS_RY3COE = 0;
3444 SiS_Pr->SiS_RY4COE = 0;
3445 SiS_Pr->SiS_RVBHRS2 = 0;
3446 }
3447
3448 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3449
3450 #ifdef CONFIG_FB_SIS_315
3451 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3452 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3453 #endif
3454
3455 } else {
3456
3457 /* 301BDH needs LVDS Data */
3458 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3459 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3460 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3461 }
3462
3463 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3464 &CRT2Index, &ResIndex);
3465
3466 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3467
3468 switch(CRT2Index) {
3469 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3470 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3471 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3472 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3473 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3474 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3475 #ifdef CONFIG_FB_SIS_300
3476 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3477 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3478 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3479 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3480 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3481 #endif
3482 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3483 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3484 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3485 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3486 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3487 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3488 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3489 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3490 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3491 }
3492
3493 if(LVDSData) {
3494 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3495 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3496 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3497 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3498 } else {
3499 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3500 }
3501
3502 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3503 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3504 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3505 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3506 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3507 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3508 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3509 #ifdef CONFIG_FB_SIS_300
3510 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3511 if(ResIndex < 0x08) {
3512 SiS_Pr->SiS_HDE = 1280;
3513 SiS_Pr->SiS_VDE = 1024;
3514 }
3515 }
3516 #endif
3517 }
3518 }
3519 }
3520 }
3521
3522 static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3523 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3524 unsigned short RefreshRateTableIndex)
3525 {
3526 unsigned char *ROMAddr = NULL;
3527 unsigned short tempax, tempbx, modeflag, romptr=0;
3528 unsigned short resinfo, CRT2Index, ResIndex;
3529 const struct SiS_LCDData *LCDPtr = NULL;
3530 const struct SiS_TVData *TVPtr = NULL;
3531 #ifdef CONFIG_FB_SIS_315
3532 short resinfo661;
3533 #endif
3534
3535 if(ModeNo <= 0x13) {
3536 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3537 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3538 } else if(SiS_Pr->UseCustomMode) {
3539 modeflag = SiS_Pr->CModeFlag;
3540 resinfo = 0;
3541 } else {
3542 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3543 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3544 #ifdef CONFIG_FB_SIS_315
3545 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3546 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3547 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3548 (resinfo661 >= 0) &&
3549 (SiS_Pr->SiS_NeedRomModeData) ) {
3550 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3551 if((romptr = (SISGETROMW(21)))) {
3552 romptr += (resinfo661 * 10);
3553 ROMAddr = SiS_Pr->VirtualRomBase;
3554 }
3555 }
3556 }
3557 #endif
3558 }
3559
3560 SiS_Pr->SiS_NewFlickerMode = 0;
3561 SiS_Pr->SiS_RVBHRS = 50;
3562 SiS_Pr->SiS_RY1COE = 0;
3563 SiS_Pr->SiS_RY2COE = 0;
3564 SiS_Pr->SiS_RY3COE = 0;
3565 SiS_Pr->SiS_RY4COE = 0;
3566 SiS_Pr->SiS_RVBHRS2 = 0;
3567
3568 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3569
3570 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3571
3572 if(SiS_Pr->UseCustomMode) {
3573
3574 SiS_Pr->SiS_RVBHCMAX = 1;
3575 SiS_Pr->SiS_RVBHCFACT = 1;
3576 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3577 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3578
3579 tempax = SiS_Pr->CHTotal;
3580 if(modeflag & HalfDCLK) tempax <<= 1;
3581 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3582 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3583
3584 } else {
3585
3586 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3587
3588 }
3589
3590 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3591
3592 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3593 &CRT2Index,&ResIndex);
3594
3595 switch(CRT2Index) {
3596 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3597 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3598 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3599 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3600 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3601 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3602 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3603 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3604 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3605 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3606 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3607 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3608 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3609 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3610 }
3611
3612 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3613 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3614 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3615 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3616 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3617 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3618 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3619 if(modeflag & HalfDCLK) {
3620 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3621 if(SiS_Pr->SiS_RVBHRS2) {
3622 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3623 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3624 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3625 else SiS_Pr->SiS_RVBHRS2 += tempax;
3626 }
3627 } else {
3628 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3629 }
3630 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3631
3632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3633
3634 if((resinfo == SIS_RI_960x600) ||
3635 (resinfo == SIS_RI_1024x768) ||
3636 (resinfo == SIS_RI_1280x1024) ||
3637 (resinfo == SIS_RI_1280x720)) {
3638 SiS_Pr->SiS_NewFlickerMode = 0x40;
3639 }
3640
3641 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3642
3643 SiS_Pr->SiS_HT = ExtHiTVHT;
3644 SiS_Pr->SiS_VT = ExtHiTVVT;
3645 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3646 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3647 SiS_Pr->SiS_HT = StHiTVHT;
3648 SiS_Pr->SiS_VT = StHiTVVT;
3649 }
3650 }
3651
3652 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3653
3654 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3655 SiS_Pr->SiS_HT = 1650;
3656 SiS_Pr->SiS_VT = 750;
3657 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3658 SiS_Pr->SiS_HT = NTSCHT;
3659 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3660 SiS_Pr->SiS_VT = NTSCVT;
3661 } else {
3662 SiS_Pr->SiS_HT = NTSCHT;
3663 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3664 SiS_Pr->SiS_VT = NTSCVT;
3665 }
3666
3667 } else {
3668
3669 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3670 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3671 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3672 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3673
3674 if(modeflag & HalfDCLK) {
3675 SiS_Pr->SiS_RY1COE = 0x00;
3676 SiS_Pr->SiS_RY2COE = 0xf4;
3677 SiS_Pr->SiS_RY3COE = 0x10;
3678 SiS_Pr->SiS_RY4COE = 0x38;
3679 }
3680
3681 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3682 SiS_Pr->SiS_HT = NTSCHT;
3683 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3684 SiS_Pr->SiS_VT = NTSCVT;
3685 } else {
3686 SiS_Pr->SiS_HT = PALHT;
3687 SiS_Pr->SiS_VT = PALVT;
3688 }
3689
3690 }
3691
3692 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3693
3694 SiS_Pr->SiS_RVBHCMAX = 1;
3695 SiS_Pr->SiS_RVBHCFACT = 1;
3696
3697 if(SiS_Pr->UseCustomMode) {
3698
3699 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3700 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3701
3702 tempax = SiS_Pr->CHTotal;
3703 if(modeflag & HalfDCLK) tempax <<= 1;
3704 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3705 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3706
3707 } else {
3708
3709 bool gotit = false;
3710
3711 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3712
3713 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3714 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3715 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3716 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3717 gotit = true;
3718
3719 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3720
3721 #ifdef CONFIG_FB_SIS_315
3722 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3723 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3724 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3725 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3726 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3727 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3728 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3729 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3730 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3731 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3732 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3733 else SiS_Pr->SiS_RVBHRS2 += tempax;
3734 }
3735 if(SiS_Pr->SiS_VGAHT) gotit = true;
3736 else {
3737 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3738 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3739 SiS_Pr->SiS_RVBHCMAX = 1;
3740 SiS_Pr->SiS_RVBHCFACT = 1;
3741 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3742 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3743 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3744 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3745 SiS_Pr->SiS_RVBHRS2 = 0;
3746 gotit = true;
3747 }
3748 #endif
3749
3750 }
3751
3752 if(!gotit) {
3753
3754 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3755 &CRT2Index,&ResIndex);
3756
3757 switch(CRT2Index) {
3758 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3759 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3760 case Panel_1280x720 :
3761 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3762 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3763 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3764 case Panel_1280x800 :
3765 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3766 case Panel_1280x800_2 :
3767 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3768 case Panel_1280x854 :
3769 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3770 case Panel_1280x960 :
3771 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3772 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3773 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3774 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3775 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3776 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3777 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3778 case Panel_1680x1050 :
3779 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3780 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3781 #ifdef CONFIG_FB_SIS_315
3782 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3783 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3784 #endif
3785 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3786 }
3787
3788 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3789 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3790 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3791 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3792 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3793 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3794
3795 }
3796
3797 tempax = SiS_Pr->PanelXRes;
3798 tempbx = SiS_Pr->PanelYRes;
3799
3800 switch(SiS_Pr->SiS_LCDResInfo) {
3801 case Panel_1024x768:
3802 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3803 if(SiS_Pr->ChipType < SIS_315H) {
3804 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3805 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3806 }
3807 } else {
3808 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3809 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3810 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3811 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3812 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3813 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3814 }
3815 break;
3816 case Panel_1280x960:
3817 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3818 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3819 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3820 break;
3821 case Panel_1280x1024:
3822 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3823 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3824 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3825 break;
3826 case Panel_1600x1200:
3827 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3828 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3829 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3830 }
3831 break;
3832 }
3833
3834 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3835 tempax = SiS_Pr->SiS_VGAHDE;
3836 tempbx = SiS_Pr->SiS_VGAVDE;
3837 }
3838
3839 SiS_Pr->SiS_HDE = tempax;
3840 SiS_Pr->SiS_VDE = tempbx;
3841 }
3842 }
3843 }
3844
3845 static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3846 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3847 unsigned short RefreshRateTableIndex)
3848 {
3849
3850 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3851
3852 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3853 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3854 } else {
3855 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3856 /* Need LVDS Data for LCD on 301B-DH */
3857 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3858 } else {
3859 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3860 }
3861 }
3862
3863 } else {
3864
3865 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3866
3867 }
3868 }
3869
3870 /*********************************************/
3871 /* GET LVDS DES (SKEW) DATA */
3872 /*********************************************/
3873
3874 static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3875 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3876 {
3877 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3878
3879 #ifdef CONFIG_FB_SIS_300
3880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3881
3882 if(SiS_Pr->ChipType < SIS_315H) {
3883 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3884 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3885 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3886 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3887 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3888 }
3889 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3890 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3891 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3892 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3893 }
3894 }
3895 }
3896 }
3897 }
3898 #endif
3899 return PanelDesPtr;
3900 }
3901
3902 static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3903 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3904 unsigned short RefreshRateTableIndex)
3905 {
3906 unsigned short modeflag, ResIndex;
3907 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3908
3909 SiS_Pr->SiS_LCDHDES = 0;
3910 SiS_Pr->SiS_LCDVDES = 0;
3911
3912 /* Some special cases */
3913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3914
3915 /* Trumpion */
3916 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3917 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3918 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3919 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3920 }
3921 }
3922 return;
3923 }
3924
3925 /* 640x480 on LVDS */
3926 if(SiS_Pr->ChipType < SIS_315H) {
3927 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3928 SiS_Pr->SiS_LCDHDES = 8;
3929 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3930 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3931 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3932 return;
3933 }
3934 }
3935
3936 } /* LCD */
3937
3938 if( (SiS_Pr->UseCustomMode) ||
3939 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3940 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3941 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3942 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3943 return;
3944 }
3945
3946 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3947 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3948
3949 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3950
3951 #ifdef CONFIG_FB_SIS_315
3952 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3953 /* non-pass 1:1 only, see above */
3954 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3955 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3956 }
3957 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3958 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3959 }
3960 }
3961 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3962 switch(SiS_Pr->SiS_CustomT) {
3963 case CUT_UNIWILL1024:
3964 case CUT_UNIWILL10242:
3965 case CUT_CLEVO1400:
3966 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3967 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3968 }
3969 break;
3970 }
3971 switch(SiS_Pr->SiS_LCDResInfo) {
3972 case Panel_1280x1024:
3973 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3974 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3975 }
3976 break;
3977 case Panel_1280x800: /* Verified for Averatec 6240 */
3978 case Panel_1280x800_2: /* Verified for Asus A4L */
3979 case Panel_1280x854: /* Not verified yet FIXME */
3980 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3981 break;
3982 }
3983 }
3984 #endif
3985
3986 } else {
3987
3988 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3989
3990 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3991 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3992 }
3993
3994 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3995
3996 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3997 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3998
3999 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4000
4001 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4002 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4003 }
4004 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4005 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4006 } else {
4007 if(SiS_Pr->ChipType < SIS_315H) {
4008 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4009 } else {
4010 switch(SiS_Pr->SiS_LCDResInfo) {
4011 case Panel_800x600:
4012 case Panel_1024x768:
4013 case Panel_1280x1024:
4014 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4015 break;
4016 case Panel_1400x1050:
4017 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4018 break;
4019 }
4020 }
4021 }
4022
4023 } else {
4024
4025 if(SiS_Pr->ChipType < SIS_315H) {
4026 #ifdef CONFIG_FB_SIS_300
4027 switch(SiS_Pr->SiS_LCDResInfo) {
4028 case Panel_800x600:
4029 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4030 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4031 } else {
4032 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4033 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4034 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4035 else SiS_Pr->SiS_LCDVDES -= 4;
4036 }
4037 break;
4038 case Panel_1024x768:
4039 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4040 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4041 } else {
4042 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4043 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4044 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4045 }
4046 break;
4047 case Panel_1024x600:
4048 default:
4049 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4050 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4051 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4052 } else {
4053 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4054 }
4055 break;
4056 }
4057
4058 switch(SiS_Pr->SiS_LCDTypeInfo) {
4059 case 1:
4060 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4061 break;
4062 case 3: /* 640x480 only? */
4063 SiS_Pr->SiS_LCDHDES = 8;
4064 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4065 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4066 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4067 break;
4068 }
4069 #endif
4070 } else {
4071 #ifdef CONFIG_FB_SIS_315
4072 switch(SiS_Pr->SiS_LCDResInfo) {
4073 case Panel_1024x768:
4074 case Panel_1280x1024:
4075 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4076 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4077 }
4078 break;
4079 case Panel_320x240_1:
4080 case Panel_320x240_2:
4081 case Panel_320x240_3:
4082 SiS_Pr->SiS_LCDVDES = 524;
4083 break;
4084 }
4085 #endif
4086 }
4087 }
4088
4089 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4090 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4091 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4092 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4093 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4094 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4095 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4096 if(SiS_Pr->ChipType < SIS_315H) {
4097 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4098 } else {
4099 #ifdef CONFIG_FB_SIS_315
4100 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
4101 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4102 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4103 if(!(modeflag & HalfDCLK)) {
4104 SiS_Pr->SiS_LCDHDES = 320;
4105 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4106 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4107 }
4108 #endif
4109 }
4110 }
4111 }
4112 }
4113 }
4114 }
4115 }
4116
4117 /*********************************************/
4118 /* DISABLE VIDEO BRIDGE */
4119 /*********************************************/
4120
4121 #ifdef CONFIG_FB_SIS_315
4122 static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)4123 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4124 {
4125 int ret = 0;
4126 #ifdef SET_PWD
4127 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4128 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4129 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4130 unsigned short temp;
4131
4132 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4133 (romptr) &&
4134 (SiS_Pr->SiS_PWDOffset) ) {
4135 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4136 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4137 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4140 temp = 0x00;
4141 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4142 temp = 0x80;
4143 ret = 1;
4144 }
4145 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4146 }
4147 #endif
4148 return ret;
4149 }
4150 #endif
4151
4152 /* NEVER use any variables (VBInfo), this will be called
4153 * from outside the context of modeswitch!
4154 * MUST call getVBType before calling this
4155 */
4156 void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)4157 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4158 {
4159 #ifdef CONFIG_FB_SIS_315
4160 unsigned short tempah, pushax=0, modenum;
4161 #endif
4162 unsigned short temp=0;
4163
4164 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4165
4166 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
4167
4168 if(SiS_Pr->ChipType < SIS_315H) {
4169
4170 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4171
4172 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4173 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4174 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4175 } else {
4176 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4177 }
4178 SiS_PanelDelay(SiS_Pr, 3);
4179 }
4180 if(SiS_Is301B(SiS_Pr)) {
4181 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4182 SiS_ShortDelay(SiS_Pr,1);
4183 }
4184 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4185 SiS_DisplayOff(SiS_Pr);
4186 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4187 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4188 SiS_UnLockCRT2(SiS_Pr);
4189 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4190 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4191 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4192 }
4193 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4194 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4195 SiS_PanelDelay(SiS_Pr, 2);
4196 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4197 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4198 } else {
4199 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4200 }
4201 }
4202
4203 #endif /* CONFIG_FB_SIS_300 */
4204
4205 } else {
4206
4207 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4208
4209 int didpwd = 0;
4210 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4211 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4212
4213 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4214
4215 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4216
4217 #ifdef SET_EMI
4218 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4219 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4220 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4221 }
4222 }
4223 #endif
4224
4225 didpwd = SiS_HandlePWD(SiS_Pr);
4226
4227 if( (modenum <= 0x13) ||
4228 (SiS_IsVAMode(SiS_Pr)) ||
4229 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4230 if(!didpwd) {
4231 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4232 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4233 } else {
4234 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4235 }
4236 }
4237
4238 if(!custom1) {
4239 SiS_DDC2Delay(SiS_Pr,0xff00);
4240 SiS_DDC2Delay(SiS_Pr,0xe000);
4241 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4242 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4243 if(IS_SIS740) {
4244 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4245 }
4246 SiS_PanelDelay(SiS_Pr, 3);
4247 }
4248
4249 }
4250
4251 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4252 /* if(SiS_Pr->ChipType < SIS_340) {*/
4253 tempah = 0xef;
4254 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4255 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4256 /*}*/
4257 }
4258
4259 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4260 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4261 }
4262
4263 tempah = 0x3f;
4264 if(SiS_IsDualEdge(SiS_Pr)) {
4265 tempah = 0x7f;
4266 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4267 }
4268 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4269
4270 if((SiS_IsVAMode(SiS_Pr)) ||
4271 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4272
4273 SiS_DisplayOff(SiS_Pr);
4274 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4275 SiS_PanelDelay(SiS_Pr, 2);
4276 }
4277 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4278 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4279
4280 }
4281
4282 if((!(SiS_IsVAMode(SiS_Pr))) ||
4283 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4284
4285 if(!(SiS_IsDualEdge(SiS_Pr))) {
4286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4287 SiS_DisplayOff(SiS_Pr);
4288 }
4289 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4290
4291 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4292 SiS_PanelDelay(SiS_Pr, 2);
4293 }
4294
4295 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4296 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4297 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4298 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4299 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4300
4301 }
4302
4303 if(SiS_IsNotM650orLater(SiS_Pr)) {
4304 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4305 }
4306
4307 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4308
4309 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4310 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4311 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4312
4313 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4314 if(!didpwd) {
4315 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4316 }
4317 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4318 }
4319
4320 if(!custom1) {
4321 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4322 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4323 if(SiS_IsVAorLCD(SiS_Pr)) {
4324 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4325 }
4326 }
4327 }
4328
4329 }
4330
4331 #endif /* CONFIG_FB_SIS_315 */
4332
4333 }
4334
4335 } else { /* ============ For 301 ================ */
4336
4337 if(SiS_Pr->ChipType < SIS_315H) {
4338 #ifdef CONFIG_FB_SIS_300
4339 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4340 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4341 SiS_PanelDelay(SiS_Pr, 3);
4342 }
4343 #endif
4344 }
4345
4346 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4347 SiS_DisplayOff(SiS_Pr);
4348
4349 if(SiS_Pr->ChipType >= SIS_315H) {
4350 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4351 }
4352
4353 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4354
4355 if(SiS_Pr->ChipType >= SIS_315H) {
4356 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4357 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4358 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4359 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4360 } else {
4361 #ifdef CONFIG_FB_SIS_300
4362 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4363 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4364 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4365 SiS_PanelDelay(SiS_Pr, 2);
4366 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4367 }
4368 #endif
4369 }
4370
4371 }
4372
4373 } else { /* ============ For LVDS =============*/
4374
4375 if(SiS_Pr->ChipType < SIS_315H) {
4376
4377 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4378
4379 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4380 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4381 }
4382
4383 if(SiS_Pr->ChipType == SIS_730) {
4384 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4385 SiS_WaitVBRetrace(SiS_Pr);
4386 }
4387 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4388 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4389 SiS_PanelDelay(SiS_Pr, 3);
4390 }
4391 } else {
4392 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4393 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4394 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4395 SiS_WaitVBRetrace(SiS_Pr);
4396 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4397 SiS_DisplayOff(SiS_Pr);
4398 }
4399 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4400 SiS_PanelDelay(SiS_Pr, 3);
4401 }
4402 }
4403 }
4404 }
4405
4406 SiS_DisplayOff(SiS_Pr);
4407
4408 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4409
4410 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4411 SiS_UnLockCRT2(SiS_Pr);
4412 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4413 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4414
4415 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4416 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4417 SiS_PanelDelay(SiS_Pr, 2);
4418 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4419 }
4420
4421 #endif /* CONFIG_FB_SIS_300 */
4422
4423 } else {
4424
4425 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4426
4427 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4428 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4429 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4430 /* } */
4431 }
4432
4433 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4434
4435 if(SiS_Pr->ChipType == SIS_740) {
4436 temp = SiS_GetCH701x(SiS_Pr,0x61);
4437 if(temp < 1) {
4438 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4439 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4440 }
4441
4442 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4443 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4444 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4445 }
4446 }
4447
4448 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4449 (SiS_IsVAMode(SiS_Pr)) ) {
4450 SiS_Chrontel701xBLOff(SiS_Pr);
4451 SiS_Chrontel701xOff(SiS_Pr);
4452 }
4453
4454 if(SiS_Pr->ChipType != SIS_740) {
4455 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4456 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4457 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4458 }
4459 }
4460
4461 }
4462
4463 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4464 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4465 SiS_PanelDelay(SiS_Pr, 3);
4466 }
4467
4468 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4469 (!(SiS_IsDualEdge(SiS_Pr))) ||
4470 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4471 SiS_DisplayOff(SiS_Pr);
4472 }
4473
4474 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4475 (!(SiS_IsDualEdge(SiS_Pr))) ||
4476 (!(SiS_IsVAMode(SiS_Pr))) ) {
4477 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4478 }
4479
4480 if(SiS_Pr->ChipType == SIS_740) {
4481 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4482 }
4483
4484 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4485
4486 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4487 (!(SiS_IsDualEdge(SiS_Pr))) ||
4488 (!(SiS_IsVAMode(SiS_Pr))) ) {
4489 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4490 }
4491
4492 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4493 if(SiS_CRT2IsLCD(SiS_Pr)) {
4494 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4495 if(SiS_Pr->ChipType == SIS_550) {
4496 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4498 }
4499 }
4500 } else {
4501 if(SiS_Pr->ChipType == SIS_740) {
4502 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4503 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4504 }
4505 } else if(SiS_IsVAMode(SiS_Pr)) {
4506 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4507 }
4508 }
4509
4510 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4511 if(SiS_IsDualEdge(SiS_Pr)) {
4512 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4513 } else {
4514 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4515 }
4516 }
4517
4518 SiS_UnLockCRT2(SiS_Pr);
4519
4520 if(SiS_Pr->ChipType == SIS_550) {
4521 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4522 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4523 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4524 (!(SiS_IsDualEdge(SiS_Pr))) ||
4525 (!(SiS_IsVAMode(SiS_Pr))) ) {
4526 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4527 }
4528
4529 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4530 if(SiS_CRT2IsLCD(SiS_Pr)) {
4531 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4532 SiS_PanelDelay(SiS_Pr, 2);
4533 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4534 }
4535 }
4536 }
4537
4538 #endif /* CONFIG_FB_SIS_315 */
4539
4540 } /* 315 series */
4541
4542 } /* LVDS */
4543
4544 }
4545
4546 /*********************************************/
4547 /* ENABLE VIDEO BRIDGE */
4548 /*********************************************/
4549
4550 /* NEVER use any variables (VBInfo), this will be called
4551 * from outside the context of a mode switch!
4552 * MUST call getVBType before calling this
4553 */
4554 static
4555 void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4556 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4557 {
4558 unsigned short temp=0, tempah;
4559 #ifdef CONFIG_FB_SIS_315
4560 unsigned short temp1, pushax=0;
4561 bool delaylong = false;
4562 #endif
4563
4564 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4565
4566 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4567
4568 if(SiS_Pr->ChipType < SIS_315H) {
4569
4570 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4571
4572 if(SiS_CRT2IsLCD(SiS_Pr)) {
4573 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4574 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4575 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4576 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4577 }
4578 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4579 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4580 SiS_PanelDelay(SiS_Pr, 0);
4581 }
4582 }
4583 }
4584
4585 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4586 (SiS_CRT2IsLCD(SiS_Pr))) {
4587
4588 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4589 SiS_DisplayOn(SiS_Pr);
4590 SiS_UnLockCRT2(SiS_Pr);
4591 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4592 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4593 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4594 } else {
4595 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4596 }
4597 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4598 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4599 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4600 SiS_PanelDelay(SiS_Pr, 1);
4601 }
4602 SiS_WaitVBRetrace(SiS_Pr);
4603 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4604 }
4605 }
4606
4607 } else {
4608
4609 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4610 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4611 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4612 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4613 }
4614 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4615 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4616 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4617 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4618 SiS_DisplayOn(SiS_Pr);
4619 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4620 if(SiS_CRT2IsLCD(SiS_Pr)) {
4621 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4622 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4623 SiS_PanelDelay(SiS_Pr, 1);
4624 }
4625 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4626 }
4627 }
4628 }
4629
4630 }
4631
4632
4633 #endif /* CONFIG_FB_SIS_300 */
4634
4635 } else {
4636
4637 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4638
4639 #ifdef SET_EMI
4640 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4641 int didpwd = 0;
4642 /* unsigned short emidelay=0; */
4643 #endif
4644
4645 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4646 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4647 #ifdef SET_EMI
4648 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4650 }
4651 #endif
4652 }
4653
4654 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4655 /*if(SiS_Pr->ChipType < SIS_340) { */
4656 tempah = 0x10;
4657 if(SiS_LCDAEnabled(SiS_Pr)) {
4658 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4659 else tempah = 0x08;
4660 }
4661 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4662 /*}*/
4663 }
4664
4665 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4666
4667 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4668 SiS_DisplayOff(SiS_Pr);
4669 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4670 if(IS_SIS740) {
4671 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4672 }
4673
4674 didpwd = SiS_HandlePWD(SiS_Pr);
4675
4676 if(SiS_IsVAorLCD(SiS_Pr)) {
4677 if(!didpwd) {
4678 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4679 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4680 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4681 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4682 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4683 SiS_GenericDelay(SiS_Pr, 17664);
4684 }
4685 }
4686 } else {
4687 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4688 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4689 SiS_GenericDelay(SiS_Pr, 17664);
4690 }
4691 }
4692 }
4693
4694 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4695 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4696 delaylong = true;
4697 }
4698
4699 }
4700
4701 if(!(SiS_IsVAMode(SiS_Pr))) {
4702
4703 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4704 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4705 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4706 if(!(tempah & SetCRT2ToRAMDAC)) {
4707 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4708 }
4709 }
4710 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4711
4712 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4713
4714 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4715 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4716
4717 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4718 SiS_PanelDelay(SiS_Pr, 2);
4719 }
4720
4721 } else {
4722
4723 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4724
4725 }
4726
4727 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4728 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4729
4730 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4731 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4732 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4733 /* Enable "LVDS PLL power on" (even on 301C) */
4734 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4735 /* Enable "LVDS Driver Power on" (even on 301C) */
4736 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4737 }
4738 }
4739
4740 tempah = 0xc0;
4741 if(SiS_IsDualEdge(SiS_Pr)) {
4742 tempah = 0x80;
4743 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4744 }
4745 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4746
4747 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4748
4749 SiS_PanelDelay(SiS_Pr, 2);
4750
4751 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4752 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4753
4754 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4755 #ifdef SET_EMI
4756 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4757 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4758 SiS_GenericDelay(SiS_Pr, 2048);
4759 }
4760 #endif
4761 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4762
4763 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4764 #ifdef SET_EMI
4765 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4766
4767 if(SiS_Pr->SiS_ROMNew) {
4768 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4769 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4770 if(romptr) {
4771 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4772 SiS_Pr->EMI_30 = 0;
4773 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4774 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4775 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4776 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4777 /* emidelay = SISGETROMW((romptr + 0x22)); */
4778 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4779 }
4780 }
4781
4782 /* (P4_30|0x40) */
4783 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4784 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4785 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4786 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4787 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4788 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4789 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4790 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4791 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4792
4793 if(SiS_Pr->HaveEMI) {
4794 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4795 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4796 } else {
4797 r30 = 0;
4798 }
4799
4800 /* EMI_30 is read at driver start; however, the BIOS sets this
4801 * (if it is used) only if the LCD is in use. In case we caught
4802 * the machine while on TV output, this bit is not set and we
4803 * don't know if it should be set - hence our detection is wrong.
4804 * Work-around this here:
4805 */
4806
4807 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4808 switch((cr36 & 0x0f)) {
4809 case 2:
4810 r30 |= 0x40;
4811 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4812 if(!SiS_Pr->HaveEMI) {
4813 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4814 if((cr36 & 0xf0) == 0x30) {
4815 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4816 }
4817 }
4818 break;
4819 case 3: /* 1280x1024 */
4820 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4821 if(!SiS_Pr->HaveEMI) {
4822 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4823 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4824 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4825 }
4826 }
4827 break;
4828 case 9: /* 1400x1050 */
4829 r30 |= 0x40;
4830 if(!SiS_Pr->HaveEMI) {
4831 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4832 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4833 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4834 }
4835 }
4836 break;
4837 case 11: /* 1600x1200 - unknown */
4838 r30 |= 0x40;
4839 if(!SiS_Pr->HaveEMI) {
4840 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4841 }
4842 }
4843 }
4844
4845 /* BIOS values don't work so well sometimes */
4846 if(!SiS_Pr->OverruleEMI) {
4847 #ifdef COMPAL_HACK
4848 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4849 if((cr36 & 0x0f) == 0x09) {
4850 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4851 }
4852 }
4853 #endif
4854 #ifdef COMPAQ_HACK
4855 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4856 if((cr36 & 0x0f) == 0x03) {
4857 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4858 }
4859 }
4860 #endif
4861 #ifdef ASUS_HACK
4862 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4863 if((cr36 & 0x0f) == 0x02) {
4864 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4865 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4866 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4867 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4868 }
4869 }
4870 #endif
4871 }
4872
4873 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4874 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4875 SiS_GenericDelay(SiS_Pr, 2048);
4876 }
4877 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4878 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4879 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4880 #endif /* SET_EMI */
4881
4882 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4883
4884 #ifdef SET_EMI
4885 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4886 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4887 if(r30 & 0x40) {
4888 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4889 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4890 if(delaylong) {
4891 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4892 delaylong = false;
4893 }
4894 SiS_WaitVBRetrace(SiS_Pr);
4895 SiS_WaitVBRetrace(SiS_Pr);
4896 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4897 SiS_GenericDelay(SiS_Pr, 1280);
4898 }
4899 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4900 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4901 }
4902 }
4903 #endif
4904 }
4905 }
4906
4907 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4908 if(SiS_IsVAorLCD(SiS_Pr)) {
4909 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4910 if(delaylong) {
4911 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4912 }
4913 SiS_WaitVBRetrace(SiS_Pr);
4914 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4915 SiS_GenericDelay(SiS_Pr, 2048);
4916 SiS_WaitVBRetrace(SiS_Pr);
4917 }
4918 if(!didpwd) {
4919 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4920 } else {
4921 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4922 }
4923 }
4924 }
4925
4926 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4927 SiS_DisplayOn(SiS_Pr);
4928 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4929
4930 }
4931
4932 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4933 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4934 }
4935
4936 #endif /* CONFIG_FB_SIS_315 */
4937
4938 }
4939
4940 } else { /* ============ For 301 ================ */
4941
4942 if(SiS_Pr->ChipType < SIS_315H) {
4943 if(SiS_CRT2IsLCD(SiS_Pr)) {
4944 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4945 SiS_PanelDelay(SiS_Pr, 0);
4946 }
4947 }
4948
4949 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4950 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4951 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4952 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4953 }
4954 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4955
4956 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4957
4958 if(SiS_Pr->ChipType >= SIS_315H) {
4959 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4960 if(!(temp & 0x80)) {
4961 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4962 }
4963 }
4964
4965 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4966
4967 SiS_VBLongWait(SiS_Pr);
4968 SiS_DisplayOn(SiS_Pr);
4969 if(SiS_Pr->ChipType >= SIS_315H) {
4970 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4971 }
4972 SiS_VBLongWait(SiS_Pr);
4973
4974 if(SiS_Pr->ChipType < SIS_315H) {
4975 if(SiS_CRT2IsLCD(SiS_Pr)) {
4976 SiS_PanelDelay(SiS_Pr, 1);
4977 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4978 }
4979 }
4980
4981 }
4982
4983 } else { /* =================== For LVDS ================== */
4984
4985 if(SiS_Pr->ChipType < SIS_315H) {
4986
4987 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4988
4989 if(SiS_CRT2IsLCD(SiS_Pr)) {
4990 if(SiS_Pr->ChipType == SIS_730) {
4991 SiS_PanelDelay(SiS_Pr, 1);
4992 SiS_PanelDelay(SiS_Pr, 1);
4993 SiS_PanelDelay(SiS_Pr, 1);
4994 }
4995 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4996 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4997 SiS_PanelDelay(SiS_Pr, 0);
4998 }
4999 }
5000
5001 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5002 SiS_DisplayOn(SiS_Pr);
5003 SiS_UnLockCRT2(SiS_Pr);
5004 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5005 if(SiS_BridgeInSlavemode(SiS_Pr)) {
5006 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5007 } else {
5008 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5009 }
5010
5011 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5012 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5013 SiS_WaitVBRetrace(SiS_Pr);
5014 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5015 }
5016 }
5017
5018 if(SiS_CRT2IsLCD(SiS_Pr)) {
5019 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5020 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5021 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5022 SiS_PanelDelay(SiS_Pr, 1);
5023 SiS_PanelDelay(SiS_Pr, 1);
5024 }
5025 SiS_WaitVBRetrace(SiS_Pr);
5026 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5027 }
5028 }
5029 }
5030
5031 #endif /* CONFIG_FB_SIS_300 */
5032
5033 } else {
5034
5035 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5036
5037 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5038 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
5039 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5040 /*}*/
5041 }
5042
5043 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5044 if(SiS_CRT2IsLCD(SiS_Pr)) {
5045 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5046 SiS_PanelDelay(SiS_Pr, 0);
5047 }
5048 }
5049
5050 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5051 SiS_UnLockCRT2(SiS_Pr);
5052
5053 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5054
5055 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5056 temp = SiS_GetCH701x(SiS_Pr,0x66);
5057 temp &= 0x20;
5058 SiS_Chrontel701xBLOff(SiS_Pr);
5059 }
5060
5061 if(SiS_Pr->ChipType != SIS_550) {
5062 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5063 }
5064
5065 if(SiS_Pr->ChipType == SIS_740) {
5066 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5067 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5068 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5069 }
5070 }
5071 }
5072
5073 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5074 if(!(temp1 & 0x80)) {
5075 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5076 }
5077
5078 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5079 if(temp) {
5080 SiS_Chrontel701xBLOn(SiS_Pr);
5081 }
5082 }
5083
5084 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5085 if(SiS_CRT2IsLCD(SiS_Pr)) {
5086 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5087 if(SiS_Pr->ChipType == SIS_550) {
5088 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5090 }
5091 }
5092 } else if(SiS_IsVAMode(SiS_Pr)) {
5093 if(SiS_Pr->ChipType != SIS_740) {
5094 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5095 }
5096 }
5097
5098 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5099 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5100 }
5101
5102 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5103 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5104 SiS_Chrontel701xOn(SiS_Pr);
5105 }
5106 if( (SiS_IsVAMode(SiS_Pr)) ||
5107 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5108 SiS_ChrontelDoSomething1(SiS_Pr);
5109 }
5110 }
5111
5112 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5113 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5114 if( (SiS_IsVAMode(SiS_Pr)) ||
5115 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5116 SiS_Chrontel701xBLOn(SiS_Pr);
5117 SiS_ChrontelInitTVVSync(SiS_Pr);
5118 }
5119 }
5120 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5121 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5122 if(SiS_CRT2IsLCD(SiS_Pr)) {
5123 SiS_PanelDelay(SiS_Pr, 1);
5124 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5125 }
5126 }
5127 }
5128
5129 #endif /* CONFIG_FB_SIS_315 */
5130
5131 } /* 310 series */
5132
5133 } /* LVDS */
5134
5135 }
5136
5137 /*********************************************/
5138 /* SET PART 1 REGISTER GROUP */
5139 /*********************************************/
5140
5141 /* Set CRT2 OFFSET / PITCH */
5142 static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)5143 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5144 unsigned short RRTI)
5145 {
5146 unsigned short offset;
5147 unsigned char temp;
5148
5149 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5150
5151 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5152
5153 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5155
5156 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5157 if(offset & 0x07) temp++;
5158 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5159 }
5160
5161 /* Set CRT2 sync and PanelLink mode */
5162 static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)5163 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5164 {
5165 unsigned short tempah=0, tempbl, infoflag;
5166
5167 tempbl = 0xC0;
5168
5169 if(SiS_Pr->UseCustomMode) {
5170 infoflag = SiS_Pr->CInfoFlag;
5171 } else {
5172 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5173 }
5174
5175 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
5176
5177 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5178 tempah = 0;
5179 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5180 tempah = SiS_Pr->SiS_LCDInfo;
5181 } else tempah = infoflag >> 8;
5182 tempah &= 0xC0;
5183 tempah |= 0x20;
5184 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5185 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5186 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5187 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5188 tempah |= 0xf0;
5189 }
5190 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5191 (SiS_Pr->SiS_IF_DEF_DSTN) ||
5192 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5193 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5194 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5195 tempah |= 0x30;
5196 }
5197 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5198 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5199 tempah &= ~0xc0;
5200 }
5201 }
5202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5203 if(SiS_Pr->ChipType >= SIS_315H) {
5204 tempah >>= 3;
5205 tempah &= 0x18;
5206 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5207 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5208 } else {
5209 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5210 }
5211 } else {
5212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5213 }
5214
5215 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5216
5217 if(SiS_Pr->ChipType < SIS_315H) {
5218
5219 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
5220
5221 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
5222
5223 tempah = infoflag >> 8;
5224 tempbl = 0;
5225 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5226 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5227 tempah = SiS_Pr->SiS_LCDInfo;
5228 tempbl = (tempah >> 6) & 0x03;
5229 }
5230 }
5231 tempah &= 0xC0;
5232 tempah |= 0x20;
5233 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5234 tempah |= 0xc0;
5235 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5236 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5237 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5238 }
5239
5240 } else { /* 630 - 301 */
5241
5242 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5243 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5245
5246 }
5247
5248 #endif /* CONFIG_FB_SIS_300 */
5249
5250 } else {
5251
5252 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
5253
5254 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5255
5256 tempbl = 0;
5257 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5258 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5259 tempah = infoflag >> 8;
5260 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5261 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5262 }
5263 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5264 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5265 tempah = infoflag >> 8;
5266 tempbl = 0x03;
5267 } else {
5268 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5269 tempbl = (tempah >> 6) & 0x03;
5270 tempbl |= 0x08;
5271 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5272 }
5273 tempah &= 0xC0;
5274 tempah |= 0x20;
5275 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5277 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5278 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5280 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5281 }
5282 }
5283
5284 } else { /* 315 - TMDS */
5285
5286 tempah = tempbl = infoflag >> 8;
5287 if(!SiS_Pr->UseCustomMode) {
5288 tempbl = 0;
5289 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5290 if(ModeNo <= 0x13) {
5291 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5292 }
5293 }
5294 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5295 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5296 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5297 tempah = SiS_Pr->SiS_LCDInfo;
5298 tempbl = (tempah >> 6) & 0x03;
5299 }
5300 }
5301 }
5302 }
5303 tempah &= 0xC0;
5304 tempah |= 0x20;
5305 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5306 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5307 /* Imitate BIOS bug */
5308 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5309 }
5310 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5311 tempah >>= 3;
5312 tempah &= 0x18;
5313 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5314 } else {
5315 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5316 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5317 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5318 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5319 }
5320 }
5321 }
5322
5323 }
5324 #endif /* CONFIG_FB_SIS_315 */
5325 }
5326 }
5327 }
5328
5329 /* Set CRT2 FIFO on 300/540/630/730 */
5330 #ifdef CONFIG_FB_SIS_300
5331 static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5332 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5333 {
5334 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5335 unsigned short temp, index, modeidindex, refreshratetableindex;
5336 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5337 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5338 unsigned int data, pci50, pciA0;
5339 static const unsigned char colortharray[] = {
5340 1, 1, 2, 2, 3, 4
5341 };
5342
5343 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5344
5345 if(!SiS_Pr->CRT1UsesCustomMode) {
5346
5347 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5348 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5349 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5350 SiS_Pr->SiS_SelectCRT2Rate = 0;
5351 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5352
5353 if(CRT1ModeNo >= 0x13) {
5354 /* Get VCLK */
5355 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5356 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5357
5358 /* Get colordepth */
5359 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5360 if(!colorth) colorth++;
5361 }
5362
5363 } else {
5364
5365 CRT1ModeNo = 0xfe;
5366
5367 /* Get VCLK */
5368 VCLK = SiS_Pr->CSRClock_CRT1;
5369
5370 /* Get color depth */
5371 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5372
5373 }
5374
5375 if(CRT1ModeNo >= 0x13) {
5376 /* Get MCLK */
5377 if(SiS_Pr->ChipType == SIS_300) {
5378 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5379 } else {
5380 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5381 }
5382 index &= 0x07;
5383 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5384
5385 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5386 if(!temp) temp++;
5387 temp <<= 2;
5388
5389 data2 = temp - ((colorth * VCLK) / MCLK);
5390
5391 temp = (28 * 16) % data2;
5392 data2 = (28 * 16) / data2;
5393 if(temp) data2++;
5394
5395 if(SiS_Pr->ChipType == SIS_300) {
5396
5397 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5398 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5399
5400 } else {
5401
5402 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5403 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5404
5405 if(SiS_Pr->ChipType == SIS_730) {
5406
5407 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5408 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5409
5410 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5411 index = 0; /* -- do it like the BIOS anyway... */
5412
5413 } else {
5414
5415 pci50 >>= 24;
5416 pciA0 >>= 24;
5417
5418 index = (pci50 >> 1) & 0x07;
5419
5420 if(pci50 & 0x01) index += 6;
5421 if(!(pciA0 & 0x01)) index += 24;
5422
5423 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5424
5425 }
5426
5427 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5428 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5429
5430 }
5431
5432 data += data2; /* CRT1 Request Period */
5433
5434 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5435 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5436
5437 if(!SiS_Pr->UseCustomMode) {
5438
5439 CRT2ModeNo = ModeNo;
5440 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5441
5442 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5443
5444 /* Get VCLK */
5445 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5446 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5447
5448 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5449 if(SiS_Pr->SiS_UseROM) {
5450 if(ROMAddr[0x220] & 0x01) {
5451 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5452 }
5453 }
5454 }
5455
5456 } else {
5457
5458 /* Get VCLK */
5459 CRT2ModeNo = 0xfe;
5460 VCLK = SiS_Pr->CSRClock;
5461
5462 }
5463
5464 /* Get colordepth */
5465 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5466 if(!colorth) colorth++;
5467
5468 data = data * VCLK * colorth;
5469 temp = data % (MCLK << 4);
5470 data = data / (MCLK << 4);
5471 if(temp) data++;
5472
5473 if(data < 6) data = 6;
5474 else if(data > 0x14) data = 0x14;
5475
5476 if(SiS_Pr->ChipType == SIS_300) {
5477 temp = 0x16;
5478 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5479 temp = 0x13;
5480 } else {
5481 temp = 0x16;
5482 if(( (SiS_Pr->ChipType == SIS_630) ||
5483 (SiS_Pr->ChipType == SIS_730) ) &&
5484 (SiS_Pr->ChipRevision >= 0x30))
5485 temp = 0x1b;
5486 }
5487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5488
5489 if((SiS_Pr->ChipType == SIS_630) &&
5490 (SiS_Pr->ChipRevision >= 0x30)) {
5491 if(data > 0x13) data = 0x13;
5492 }
5493 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5494
5495 } else { /* If mode <= 0x13, we just restore everything */
5496
5497 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5498 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5499
5500 }
5501 }
5502 #endif
5503
5504 /* Set CRT2 FIFO on 315/330 series */
5505 #ifdef CONFIG_FB_SIS_315
5506 static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5507 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5508 {
5509 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5510 if( (SiS_Pr->ChipType == SIS_760) &&
5511 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5512 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5513 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5514 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5515 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5521 } else {
5522 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5523 }
5524
5525 }
5526 #endif
5527
5528 static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5529 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5530 {
5531 unsigned int tempax,tempbx;
5532
5533 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5534 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5535 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5536 return (unsigned short)tempax;
5537 }
5538
5539 /* Set Part 1 / SiS bridge slave mode */
5540 static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5541 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5542 unsigned short RefreshRateTableIndex)
5543 {
5544 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5545 static const unsigned short CRTranslation[] = {
5546 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5547 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5548 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5549 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5550 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5551 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5552 };
5553
5554 if(ModeNo <= 0x13) {
5555 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5556 } else if(SiS_Pr->UseCustomMode) {
5557 modeflag = SiS_Pr->CModeFlag;
5558 xres = SiS_Pr->CHDisplay;
5559 } else {
5560 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5561 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5562 }
5563
5564 /* The following is only done if bridge is in slave mode: */
5565
5566 if(SiS_Pr->ChipType >= SIS_315H) {
5567 if(xres >= 1600) { /* BIOS: == 1600 */
5568 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5569 }
5570 }
5571
5572 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5573
5574 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5575 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5576
5577 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5578 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5579 SiS_Pr->CHBlankStart += 16;
5580 }
5581
5582 SiS_Pr->CHBlankEnd = 32;
5583 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5584 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5585 }
5586
5587 temp = SiS_Pr->SiS_VGAHT - 96;
5588 if(!(modeflag & HalfDCLK)) temp -= 32;
5589 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5590 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5591 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5592 temp -= 3;
5593 temp <<= 3;
5594 } else {
5595 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5596 }
5597 SiS_Pr->CHSyncStart = temp;
5598
5599 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5600
5601 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5602
5603 VGAVDE = SiS_Pr->SiS_VGAVDE;
5604 if (VGAVDE == 357) VGAVDE = 350;
5605 else if(VGAVDE == 360) VGAVDE = 350;
5606 else if(VGAVDE == 375) VGAVDE = 350;
5607 else if(VGAVDE == 405) VGAVDE = 400;
5608 else if(VGAVDE == 420) VGAVDE = 400;
5609 else if(VGAVDE == 525) VGAVDE = 480;
5610 else if(VGAVDE == 1056) VGAVDE = 1024;
5611 SiS_Pr->CVDisplay = VGAVDE;
5612
5613 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5614
5615 SiS_Pr->CVBlankEnd = 1;
5616 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5617
5618 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5619 SiS_Pr->CVSyncStart = VGAVDE + temp;
5620
5621 temp >>= 3;
5622 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5623
5624 SiS_CalcCRRegisters(SiS_Pr, 0);
5625 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5626
5627 for(i = 0; i <= 7; i++) {
5628 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5629 }
5630 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5631 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5632 }
5633 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5634 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5635 }
5636 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5637 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5638 }
5639
5640 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5641 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5642
5643 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5644 if(modeflag & DoubleScanMode) temp |= 0x80;
5645 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5646
5647 temp = 0;
5648 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5649 if(modeflag & HalfDCLK) temp |= 0x08;
5650 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5651
5652 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5654
5655 temp = 0;
5656 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5657 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5658 }
5659 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5660
5661 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5663 }
5664
5665 /* Setup panel link
5666 * This is used for LVDS, LCDA and Chrontel TV output
5667 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5668 */
5669 static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5670 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5671 unsigned short RefreshRateTableIndex)
5672 {
5673 unsigned short modeflag, resinfo = 0;
5674 unsigned short push2, tempax, tempbx, tempcx, temp;
5675 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5676 bool islvds = false, issis = false, chkdclkfirst = false;
5677 #ifdef CONFIG_FB_SIS_300
5678 unsigned short crt2crtc = 0;
5679 #endif
5680 #ifdef CONFIG_FB_SIS_315
5681 unsigned short pushcx;
5682 #endif
5683
5684 if(ModeNo <= 0x13) {
5685 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5686 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5687 #ifdef CONFIG_FB_SIS_300
5688 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5689 #endif
5690 } else if(SiS_Pr->UseCustomMode) {
5691 modeflag = SiS_Pr->CModeFlag;
5692 } else {
5693 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5694 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5695 #ifdef CONFIG_FB_SIS_300
5696 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5697 #endif
5698 }
5699
5700 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5701 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5702 islvds = true;
5703 }
5704
5705 /* is really sis if sis bridge, but not 301B-DH */
5706 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5707 issis = true;
5708 }
5709
5710 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5711 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5712 chkdclkfirst = true;
5713 }
5714 }
5715
5716 #ifdef CONFIG_FB_SIS_315
5717 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5718 if(IS_SIS330) {
5719 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5720 } else if(IS_SIS740) {
5721 if(islvds) {
5722 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5723 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5724 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5725 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5726 }
5727 } else {
5728 if(islvds) {
5729 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5730 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5731 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5732 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5733 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5734 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5735 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5736 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5737 }
5738 }
5739 }
5740 }
5741 }
5742 #endif
5743
5744 /* Horizontal */
5745
5746 tempax = SiS_Pr->SiS_LCDHDES;
5747 if(islvds) {
5748 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5749 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5750 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5751 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5752 tempax -= 8;
5753 }
5754 }
5755 }
5756 }
5757
5758 temp = (tempax & 0x0007);
5759 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5760 temp = (tempax >> 3) & 0x00FF;
5761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5762
5763 tempbx = SiS_Pr->SiS_HDE;
5764 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5765 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5766 tempbx = SiS_Pr->PanelXRes;
5767 }
5768 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5769 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5770 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5771 tempbx >>= 1;
5772 }
5773 }
5774
5775 tempax += tempbx;
5776 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5777
5778 temp = tempax;
5779 if(temp & 0x07) temp += 8;
5780 temp >>= 3;
5781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5782
5783 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5784
5785 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5786 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5787 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5788 }
5789 }
5790
5791 tempcx += tempax;
5792 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5793
5794 temp = (tempcx >> 3) & 0x00FF;
5795 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5796 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5797 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5798 switch(ModeNo) {
5799 case 0x04:
5800 case 0x05:
5801 case 0x0d: temp = 0x56; break;
5802 case 0x10: temp = 0x60; break;
5803 case 0x13: temp = 0x5f; break;
5804 case 0x40:
5805 case 0x41:
5806 case 0x4f:
5807 case 0x43:
5808 case 0x44:
5809 case 0x62:
5810 case 0x56:
5811 case 0x53:
5812 case 0x5d:
5813 case 0x5e: temp = 0x54; break;
5814 }
5815 }
5816 }
5817 }
5818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5819
5820 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5821 temp += 2;
5822 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5823 temp += 8;
5824 if(SiS_Pr->PanelHRE != 999) {
5825 temp = tempcx + SiS_Pr->PanelHRE;
5826 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5827 temp >>= 3;
5828 }
5829 }
5830 } else {
5831 temp += 10;
5832 }
5833
5834 temp &= 0x1F;
5835 temp |= ((tempcx & 0x07) << 5);
5836 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5837
5838 /* Vertical */
5839
5840 tempax = SiS_Pr->SiS_VGAVDE;
5841 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5842 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5843 tempax = SiS_Pr->PanelYRes;
5844 }
5845 }
5846
5847 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5848 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5849
5850 push2 = tempbx;
5851
5852 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5853 if(SiS_Pr->ChipType < SIS_315H) {
5854 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5855 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5856 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5857 }
5858 }
5859 }
5860 if(islvds) tempcx >>= 1;
5861 else tempcx >>= 2;
5862
5863 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5864 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5865 (SiS_Pr->PanelVRS != 999) ) {
5866 tempcx = SiS_Pr->PanelVRS;
5867 tempbx += tempcx;
5868 if(issis) tempbx++;
5869 } else {
5870 tempbx += tempcx;
5871 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5872 else if(issis) tempbx++;
5873 }
5874
5875 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5876
5877 temp = tempbx & 0x00FF;
5878 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5879 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5880 if(ModeNo == 0x10) temp = 0xa9;
5881 }
5882 }
5883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5884
5885 tempcx >>= 3;
5886 tempcx++;
5887
5888 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5889 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5890 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5891 }
5892 }
5893
5894 tempcx += tempbx;
5895 temp = tempcx & 0x000F;
5896 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5897
5898 temp = ((tempbx >> 8) & 0x07) << 3;
5899 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5900 if(SiS_Pr->SiS_HDE != 640) {
5901 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5902 }
5903 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5904 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5905 tempbx = 0x87;
5906 if((SiS_Pr->ChipType >= SIS_315H) ||
5907 (SiS_Pr->ChipRevision >= 0x30)) {
5908 tempbx = 0x07;
5909 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5910 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5911 }
5912 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5913 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5915 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5916 } else {
5917 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5918 }
5919 }
5920 }
5921 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5922
5923 tempbx = push2; /* BPLVDEE */
5924
5925 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5926
5927 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5928 switch(SiS_Pr->SiS_LCDResInfo) {
5929 case Panel_640x480:
5930 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5931 tempcx = SiS_Pr->SiS_VGAVDE;
5932 break;
5933 case Panel_800x600:
5934 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5935 if(resinfo == SIS_RI_800x600) tempcx++;
5936 }
5937 break;
5938 case Panel_1024x600:
5939 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5940 if(resinfo == SIS_RI_1024x600) tempcx++;
5941 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5942 if(resinfo == SIS_RI_800x600) tempcx++;
5943 }
5944 }
5945 break;
5946 case Panel_1024x768:
5947 if(SiS_Pr->ChipType < SIS_315H) {
5948 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5949 if(resinfo == SIS_RI_1024x768) tempcx++;
5950 }
5951 }
5952 break;
5953 }
5954 }
5955
5956 temp = ((tempbx >> 8) & 0x07) << 3;
5957 temp |= ((tempcx >> 8) & 0x07);
5958 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5961
5962 /* Vertical scaling */
5963
5964 if(SiS_Pr->ChipType < SIS_315H) {
5965
5966 #ifdef CONFIG_FB_SIS_300 /* 300 series */
5967 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5968 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5969 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5970 if(temp) tempeax++;
5971
5972 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5973
5974 temp = (unsigned short)(tempeax & 0x00FF);
5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5976 tempvcfact = temp;
5977 #endif /* CONFIG_FB_SIS_300 */
5978
5979 } else {
5980
5981 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5982 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5983 tempebx = SiS_Pr->SiS_VDE;
5984 temp = (tempeax % tempebx);
5985 tempeax = tempeax / tempebx;
5986 if(temp) tempeax++;
5987 tempvcfact = tempeax;
5988
5989 temp = (unsigned short)(tempeax & 0x00FF);
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5991 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5993 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5994 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5996
5997 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5998 temp = (unsigned short)(tempeax & 0x00FF);
5999 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6000 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6001 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6002 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6003 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6004 temp = 0;
6005 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6006 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6007 }
6008 #endif
6009
6010 }
6011
6012 /* Horizontal scaling */
6013
6014 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6015 if(chkdclkfirst) {
6016 if(modeflag & HalfDCLK) tempeax >>= 1;
6017 }
6018 tempebx = tempeax << 16;
6019 if(SiS_Pr->SiS_HDE == tempeax) {
6020 tempecx = 0xFFFF;
6021 } else {
6022 tempecx = tempebx / SiS_Pr->SiS_HDE;
6023 if(SiS_Pr->ChipType >= SIS_315H) {
6024 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6025 }
6026 }
6027
6028 if(SiS_Pr->ChipType >= SIS_315H) {
6029 tempeax = (tempebx / tempecx) - 1;
6030 } else {
6031 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6032 }
6033 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6034 temp = (unsigned short)(tempecx & 0x00FF);
6035 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6036
6037 if(SiS_Pr->ChipType >= SIS_315H) {
6038 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6039 tempbx = (unsigned short)(tempeax & 0xFFFF);
6040 } else {
6041 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6042 tempbx = tempvcfact & 0x3f;
6043 if(tempbx == 0) tempbx = 64;
6044 tempeax /= tempbx;
6045 tempbx = (unsigned short)(tempeax & 0xFFFF);
6046 }
6047 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6048 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6049 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6050 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6051 }
6052
6053 temp = ((tempbx >> 8) & 0x07) << 3;
6054 temp = temp | ((tempecx >> 8) & 0x07);
6055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6057
6058 tempecx >>= 16; /* BPLHCFACT */
6059 if(!chkdclkfirst) {
6060 if(modeflag & HalfDCLK) tempecx >>= 1;
6061 }
6062 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6063 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6064 temp = (unsigned short)(tempecx & 0x00FF);
6065 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6066
6067 #ifdef CONFIG_FB_SIS_315
6068 if(SiS_Pr->ChipType >= SIS_315H) {
6069 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6070 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6071 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6072 }
6073 } else {
6074 if(islvds) {
6075 if(SiS_Pr->ChipType == SIS_740) {
6076 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6077 } else {
6078 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6079 }
6080 }
6081 }
6082 }
6083 #endif
6084
6085 #ifdef CONFIG_FB_SIS_300
6086 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6087 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6088 unsigned char *trumpdata;
6089 int i, j = crt2crtc;
6090 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6091 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6092 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6093
6094 if(SiS_Pr->SiS_UseROM) {
6095 trumpdata = &ROMAddr[0x8001 + (j * 80)];
6096 } else {
6097 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6098 trumpdata = &SiS300_TrumpionData[j][0];
6099 }
6100
6101 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6102 for(i=0; i<5; i++) {
6103 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6104 }
6105 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6106 if(ModeNo == 0x13) {
6107 for(i=0; i<4; i++) {
6108 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6109 }
6110 } else if(ModeNo == 0x10) {
6111 for(i=0; i<4; i++) {
6112 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6113 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6114 }
6115 }
6116 }
6117 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6118 }
6119 #endif
6120
6121 #ifdef CONFIG_FB_SIS_315
6122 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6123 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6125 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6129 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6130 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6131 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6132 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6133 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6134 tempax += 64;
6135 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6136 temp = (tempax >> 8) << 3;
6137 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6138 tempax += 32; /* Blpe = lBlps+32 */
6139 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6140 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
6141 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6142
6143 tempax = SiS_Pr->SiS_VDE;
6144 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6145 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6146 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6147 tempax >>= 1;
6148 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6149 temp = (tempax >> 8) << 3;
6150 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6151
6152 tempeax = SiS_Pr->SiS_HDE;
6153 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6154 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6155 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6156 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6157 temp = tempeax & 0x7f;
6158 tempeax >>= 7;
6159 if(temp) tempeax++;
6160 temp = tempeax & 0x3f;
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6165 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6166
6167 tempax = SiS_Pr->SiS_HDE;
6168 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6169 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6170 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6171 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6172 pushcx = tempax;
6173 temp = tempax & 0x00FF;
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6175 temp = ((tempax & 0xFF00) >> 8) << 3;
6176 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6177
6178 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6179 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6180 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6181 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6182 tempeax = tempax * pushcx;
6183 temp = tempeax & 0xFF;
6184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6185 temp = (tempeax & 0xFF00) >> 8;
6186 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6187 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6188 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6189 temp = ((tempeax & 0x01000000) >> 24) << 7;
6190 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6191
6192 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6197
6198 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6199 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6200 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6219 }
6220 }
6221 #endif /* CONFIG_FB_SIS_315 */
6222 }
6223
6224 /* Set Part 1 */
6225 static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6226 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6227 unsigned short RefreshRateTableIndex)
6228 {
6229 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6230 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6231 #endif
6232 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6233 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6234 #ifdef CONFIG_FB_SIS_315
6235 unsigned short tempbl=0;
6236 #endif
6237
6238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6239 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6240 return;
6241 }
6242
6243 if(ModeNo <= 0x13) {
6244 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6245 } else if(SiS_Pr->UseCustomMode) {
6246 modeflag = SiS_Pr->CModeFlag;
6247 } else {
6248 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6249 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6250 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6251 }
6252
6253 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6254
6255 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6256 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6257 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6258
6259 if(SiS_Pr->ChipType < SIS_315H ) {
6260 #ifdef CONFIG_FB_SIS_300
6261 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6262 #endif
6263 } else {
6264 #ifdef CONFIG_FB_SIS_315
6265 SiS_SetCRT2FIFO_310(SiS_Pr);
6266 #endif
6267 }
6268
6269 /* 1. Horizontal setup */
6270
6271 if(SiS_Pr->ChipType < SIS_315H ) {
6272
6273 #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
6274
6275 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6276 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6277
6278 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6279 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6280
6281 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6283
6284 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6285 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6286 tempbx = pushbx + tempcx;
6287 tempcx <<= 1;
6288 tempcx += tempbx;
6289
6290 bridgeadd = 12;
6291
6292 #endif /* CONFIG_FB_SIS_300 */
6293
6294 } else {
6295
6296 #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
6297
6298 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6299 if(modeflag & HalfDCLK) {
6300 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6301 tempcx >>= 1;
6302 } else {
6303 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6304 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6305 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6306 tempcx = SiS_Pr->SiS_HT - tempax;
6307 }
6308 }
6309 }
6310 tempcx--;
6311 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6312 temp = (tempcx >> 4) & 0xF0;
6313 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6314
6315 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6316 tempbx = SiS_Pr->SiS_VGAHDE;
6317 tempcx -= tempbx;
6318 tempcx >>= 2;
6319 if(modeflag & HalfDCLK) {
6320 tempbx >>= 1;
6321 tempcx >>= 1;
6322 }
6323 tempbx += 16;
6324
6325 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6326
6327 pushbx = tempbx;
6328 tempcx >>= 1;
6329 tempbx += tempcx;
6330 tempcx += tempbx;
6331
6332 bridgeadd = 16;
6333
6334 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6335 if(SiS_Pr->ChipType >= SIS_661) {
6336 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6337 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6338 if(resinfo == SIS_RI_1280x1024) {
6339 tempcx = (tempcx & 0xff00) | 0x30;
6340 } else if(resinfo == SIS_RI_1600x1200) {
6341 tempcx = (tempcx & 0xff00) | 0xff;
6342 }
6343 }
6344 }
6345 }
6346
6347 #endif /* CONFIG_FB_SIS_315 */
6348
6349 } /* 315/330 series */
6350
6351 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6352
6353 if(SiS_Pr->UseCustomMode) {
6354 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6355 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6356 tempax = SiS_Pr->SiS_VGAHT;
6357 if(modeflag & HalfDCLK) tempax >>= 1;
6358 tempax--;
6359 if(tempcx > tempax) tempcx = tempax;
6360 }
6361
6362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6363 unsigned char cr4, cr14, cr5, cr15;
6364 if(SiS_Pr->UseCustomMode) {
6365 cr4 = SiS_Pr->CCRT1CRTC[4];
6366 cr14 = SiS_Pr->CCRT1CRTC[14];
6367 cr5 = SiS_Pr->CCRT1CRTC[5];
6368 cr15 = SiS_Pr->CCRT1CRTC[15];
6369 } else {
6370 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6371 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6372 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6373 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6374 }
6375 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6376 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6377 tempcx &= 0x00FF;
6378 tempcx |= (tempbx & 0xFF00);
6379 tempbx += bridgeadd;
6380 tempcx += bridgeadd;
6381 tempax = SiS_Pr->SiS_VGAHT;
6382 if(modeflag & HalfDCLK) tempax >>= 1;
6383 tempax--;
6384 if(tempcx > tempax) tempcx = tempax;
6385 }
6386
6387 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6388 tempbx = 1040;
6389 tempcx = 1044; /* HWCursor bug! */
6390 }
6391
6392 }
6393
6394 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6395
6396 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6397
6398 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6399 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6400
6401 /* 2. Vertical setup */
6402
6403 tempcx = SiS_Pr->SiS_VGAVT - 1;
6404 temp = tempcx & 0x00FF;
6405
6406 if(SiS_Pr->ChipType < SIS_661) {
6407 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6408 if(SiS_Pr->ChipType < SIS_315H) {
6409 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6410 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6411 temp--;
6412 }
6413 }
6414 } else {
6415 temp--;
6416 }
6417 } else if(SiS_Pr->ChipType >= SIS_315H) {
6418 temp--;
6419 }
6420 }
6421 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6422
6423 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6424 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6425
6426 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6427 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6428
6429 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6430 tempbx++;
6431 tempax = tempbx;
6432 tempcx++;
6433 tempcx -= tempax;
6434 tempcx >>= 2;
6435 tempbx += tempcx;
6436 if(tempcx < 4) tempcx = 4;
6437 tempcx >>= 2;
6438 tempcx += tempbx;
6439 tempcx++;
6440 } else {
6441 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6442 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6443 }
6444
6445 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6446 if(SiS_Pr->UseCustomMode) {
6447 tempbx = SiS_Pr->CVSyncStart;
6448 tempcx = SiS_Pr->CVSyncEnd;
6449 }
6450 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6451 unsigned char cr8, cr7, cr13;
6452 if(SiS_Pr->UseCustomMode) {
6453 cr8 = SiS_Pr->CCRT1CRTC[8];
6454 cr7 = SiS_Pr->CCRT1CRTC[7];
6455 cr13 = SiS_Pr->CCRT1CRTC[13];
6456 tempcx = SiS_Pr->CCRT1CRTC[9];
6457 } else {
6458 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6459 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6460 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6461 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6462 }
6463 tempbx = cr8;
6464 if(cr7 & 0x04) tempbx |= 0x0100;
6465 if(cr7 & 0x80) tempbx |= 0x0200;
6466 if(cr13 & 0x08) tempbx |= 0x0400;
6467 }
6468 }
6469 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6470
6471 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6472 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6473
6474 /* 3. Panel delay compensation */
6475
6476 if(SiS_Pr->ChipType < SIS_315H) {
6477
6478 #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6479
6480 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6481 temp = 0x20;
6482 if(SiS_Pr->ChipType == SIS_300) {
6483 temp = 0x10;
6484 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6485 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6486 }
6487 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6488 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6489 }
6490 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6491 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6494 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6495 else temp = 0x20;
6496 }
6497 if(SiS_Pr->SiS_UseROM) {
6498 if(ROMAddr[0x220] & 0x80) {
6499 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6500 temp = ROMAddr[0x221];
6501 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6502 temp = ROMAddr[0x222];
6503 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6504 temp = ROMAddr[0x223];
6505 else
6506 temp = ROMAddr[0x224];
6507 }
6508 }
6509 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6510 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6511 }
6512
6513 } else {
6514 temp = 0x20;
6515 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6516 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6517 }
6518 if(SiS_Pr->SiS_UseROM) {
6519 if(ROMAddr[0x220] & 0x80) {
6520 temp = ROMAddr[0x220];
6521 }
6522 }
6523 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6524 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6525 }
6526 }
6527
6528 temp &= 0x3c;
6529
6530 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6531
6532 #endif /* CONFIG_FB_SIS_300 */
6533
6534 } else {
6535
6536 #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6537
6538 if(SiS_Pr->ChipType < SIS_661) {
6539
6540 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6541
6542 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6543 else temp = 0x00;
6544
6545 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6546 tempbl = 0xF0;
6547 if(SiS_Pr->ChipType == SIS_650) {
6548 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6549 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6550 }
6551 }
6552
6553 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6554 temp = 0x08;
6555 tempbl = 0;
6556 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6557 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6558 }
6559 }
6560
6561 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6562 }
6563
6564 } /* < 661 */
6565
6566 tempax = 0;
6567 if(modeflag & DoubleScanMode) tempax |= 0x80;
6568 if(modeflag & HalfDCLK) tempax |= 0x40;
6569 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6570
6571 #endif /* CONFIG_FB_SIS_315 */
6572
6573 }
6574
6575 } /* Slavemode */
6576
6577 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6578 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6579 /* For 301BDH with LCD, we set up the Panel Link */
6580 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6581 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6582 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6583 }
6584 } else {
6585 if(SiS_Pr->ChipType < SIS_315H) {
6586 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6587 } else {
6588 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6589 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6590 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6591 }
6592 } else {
6593 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6594 }
6595 }
6596 }
6597 }
6598
6599 /*********************************************/
6600 /* SET PART 2 REGISTER GROUP */
6601 /*********************************************/
6602
6603 #ifdef CONFIG_FB_SIS_315
6604 static unsigned char *
SiS_GetGroup2CLVXPtr(struct SiS_Private * SiS_Pr,int tabletype)6605 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6606 {
6607 const unsigned char *tableptr = NULL;
6608 unsigned short a, b, p = 0;
6609
6610 a = SiS_Pr->SiS_VGAHDE;
6611 b = SiS_Pr->SiS_HDE;
6612 if(tabletype) {
6613 a = SiS_Pr->SiS_VGAVDE;
6614 b = SiS_Pr->SiS_VDE;
6615 }
6616
6617 if(a < b) {
6618 tableptr = SiS_Part2CLVX_1;
6619 } else if(a == b) {
6620 tableptr = SiS_Part2CLVX_2;
6621 } else {
6622 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6623 tableptr = SiS_Part2CLVX_4;
6624 } else {
6625 tableptr = SiS_Part2CLVX_3;
6626 }
6627 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6628 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6629 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6630 else tableptr = SiS_Part2CLVX_5;
6631 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6632 tableptr = SiS_Part2CLVX_6;
6633 }
6634 do {
6635 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6636 p += 0x42;
6637 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6638 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6639 }
6640 p += 2;
6641 return ((unsigned char *)&tableptr[p]);
6642 }
6643
6644 static void
SiS_SetGroup2_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6645 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6646 unsigned short RefreshRateTableIndex)
6647 {
6648 unsigned char *tableptr;
6649 unsigned char temp;
6650 int i, j;
6651
6652 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6653
6654 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6655 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6656 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6657 }
6658 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6659 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6660 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6661 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6662 }
6663 }
6664 temp = 0x10;
6665 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6666 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6667 }
6668
6669 static bool
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6670 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6671 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6672 unsigned short *ResIndex)
6673 {
6674
6675 if(SiS_Pr->ChipType < SIS_315H) return false;
6676
6677 if(ModeNo <= 0x13)
6678 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6679 else
6680 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6681
6682 (*ResIndex) &= 0x3f;
6683 (*CRT2Index) = 0;
6684
6685 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6686 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6687 (*CRT2Index) = 200;
6688 }
6689 }
6690
6691 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6692 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6693 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6694 }
6695 }
6696 return (((*CRT2Index) != 0));
6697 }
6698 #endif
6699
6700 #ifdef CONFIG_FB_SIS_300
6701 static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6702 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6703 {
6704 unsigned short tempcx;
6705 static const unsigned char atable[] = {
6706 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6707 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6708 };
6709
6710 if(!SiS_Pr->UseCustomMode) {
6711 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6712 (SiS_Pr->ChipType == SIS_730) ) &&
6713 (SiS_Pr->ChipRevision > 2) ) &&
6714 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6715 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6716 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6717 if(ModeNo == 0x13) {
6718 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6721 } else if((crt2crtc & 0x3F) == 4) {
6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6727 }
6728 }
6729
6730 if(SiS_Pr->ChipType < SIS_315H) {
6731 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6732 crt2crtc &= 0x1f;
6733 tempcx = 0;
6734 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6735 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6736 tempcx += 7;
6737 }
6738 }
6739 tempcx += crt2crtc;
6740 if(crt2crtc >= 4) {
6741 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6742 }
6743
6744 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6745 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6746 if(crt2crtc == 4) {
6747 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6748 }
6749 }
6750 }
6751 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6752 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6753 }
6754 }
6755 }
6756 }
6757
6758 /* For ECS A907. Highly preliminary. */
6759 static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6760 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6761 unsigned short ModeNo)
6762 {
6763 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6764 unsigned short crt2crtc, resindex;
6765 int i, j;
6766
6767 if(SiS_Pr->ChipType != SIS_300) return;
6768 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6769 if(SiS_Pr->UseCustomMode) return;
6770
6771 if(ModeNo <= 0x13) {
6772 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6773 } else {
6774 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6775 }
6776
6777 resindex = crt2crtc & 0x3F;
6778 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6779 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6780
6781 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6782 if(ModeNo > 0x13) {
6783 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6784 resindex = 4;
6785 }
6786
6787 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6788 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6789 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6790 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6791 }
6792 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6793 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6794 }
6795 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6796 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6797 }
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6799 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6800 }
6801 #endif
6802
6803 static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6804 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6805 {
6806 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6807 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6808 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6809
6810 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6811 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6812 static const unsigned char specialtv[] = {
6813 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6814 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6815 0x58,0xe4,0x73,0xda,0x13
6816 };
6817 int i, j;
6818 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6819 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6820 }
6821 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6822 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6823 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6824 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6826 } else {
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6829 }
6830 }
6831 }
6832 } else {
6833 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6834 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6835 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6837 } else {
6838 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6840 }
6841 }
6842 }
6843
6844 static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6845 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6846 {
6847 unsigned short temp;
6848
6849 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6850 if(SiS_Pr->SiS_VGAVDE == 525) {
6851 temp = 0xc3;
6852 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6853 temp++;
6854 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6855 }
6856 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6858 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6859 temp = 0x4d;
6860 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6861 temp++;
6862 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6863 }
6864 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6865 }
6866 }
6867
6868 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6869 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6870 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6871 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6872 /* Not always for LV, see SetGrp2 */
6873 }
6874 temp = 1;
6875 if(ModeNo <= 0x13) temp = 3;
6876 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6877 }
6878 #if 0
6879 /* 651+301C, for 1280x768 - do I really need that? */
6880 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6881 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6882 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6883 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6884 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6885 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6886 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6887 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6888 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6889 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6890 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6891 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6892 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6893 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6894 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6895 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6896 }
6897 }
6898 }
6899 #endif
6900 }
6901 }
6902
6903 static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6904 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6905 unsigned short RefreshRateTableIndex)
6906 {
6907 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6908 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6909 unsigned int longtemp, PhaseIndex;
6910 bool newtvphase;
6911 const unsigned char *TimingPoint;
6912 #ifdef CONFIG_FB_SIS_315
6913 unsigned short resindex, CRT2Index;
6914 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6915
6916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6917 #endif
6918
6919 if(ModeNo <= 0x13) {
6920 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6921 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6922 } else if(SiS_Pr->UseCustomMode) {
6923 modeflag = SiS_Pr->CModeFlag;
6924 crt2crtc = 0;
6925 } else {
6926 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6927 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6928 }
6929
6930 temp = 0;
6931 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6932 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6933 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6935
6936 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6937
6938 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6939
6940 PhaseIndex = 0x01; /* SiS_PALPhase */
6941 TimingPoint = SiS_Pr->SiS_PALTiming;
6942
6943 newtvphase = false;
6944 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6945 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6946 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6947 newtvphase = true;
6948 }
6949
6950 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6951
6952 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6953 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6954 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6955 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6956 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6957 }
6958 }
6959
6960 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6961
6962 i = 0;
6963 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6964 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6965
6966 TimingPoint = &SiS_YPbPrTable[i][0];
6967
6968 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6969
6970 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6971
6972 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6973
6974 } else {
6975
6976 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6977 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6978 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6979
6980 }
6981
6982 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6983 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6984 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6985 }
6986
6987 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6988 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6989 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6990 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6991 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6992 } else {
6993 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6994 }
6995 }
6996
6997 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6998 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6999 }
7000
7001 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7002 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7003 }
7004 for(i = 0x39; i <= 0x45; i++, j++) {
7005 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7006 }
7007
7008 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7009 if(SiS_Pr->SiS_ModeType != ModeText) {
7010 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7011 }
7012 }
7013
7014 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7015
7016 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7018 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7020
7021 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7022 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
7023 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7024 else tempax = 440; /* NTSC, YPbPr 525 */
7025
7026 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7027 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7028 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7029
7030 tempax -= SiS_Pr->SiS_VDE;
7031 tempax >>= 1;
7032 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7033 tempax >>= 1;
7034 }
7035 tempax &= 0x00ff;
7036
7037 temp = tempax + (unsigned short)TimingPoint[0];
7038 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7039
7040 temp = tempax + (unsigned short)TimingPoint[1];
7041 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7042
7043 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7044 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7045 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7047 } else {
7048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7050 }
7051 }
7052
7053 }
7054
7055 tempcx = SiS_Pr->SiS_HT;
7056 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7057 tempcx--;
7058 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7059 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7060 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7061
7062 tempcx = SiS_Pr->SiS_HT >> 1;
7063 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7064 tempcx += 7;
7065 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7066 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7067
7068 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7069 tempbx += tempcx;
7070 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7071 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7072
7073 tempbx += 8;
7074 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7075 tempbx -= 4;
7076 tempcx = tempbx;
7077 }
7078 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7079
7080 j += 2;
7081 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7082 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7083 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7084
7085 tempcx += 8;
7086 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7087 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7088
7089 tempcx = SiS_Pr->SiS_HT >> 1;
7090 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7091 j += 2;
7092 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7093 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7094
7095 tempcx -= 11;
7096 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7097 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7098 }
7099 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7100
7101 tempbx = SiS_Pr->SiS_VDE;
7102 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7103 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7104 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7105 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7106 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7107 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7108 tempbx >>= 1;
7109 if(SiS_Pr->ChipType >= SIS_315H) {
7110 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7111 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7112 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7113 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7114 if(crt2crtc == 4) tempbx++;
7115 }
7116 }
7117 }
7118 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7119 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7120 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7121 }
7122 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7123 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7124 }
7125 }
7126 }
7127 tempbx -= 2;
7128 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7129
7130 temp = (tempcx >> 8) & 0x0F;
7131 temp |= ((tempbx >> 2) & 0xC0);
7132 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7133 temp |= 0x10;
7134 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7135 }
7136 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7137
7138 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7139 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7140 }
7141
7142 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7143 tempbx = SiS_Pr->SiS_VDE;
7144 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7145 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7146 tempbx >>= 1;
7147 }
7148 tempbx -= 3;
7149 temp = ((tempbx >> 3) & 0x60) | 0x18;
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7152
7153 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7154 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7155 }
7156 }
7157
7158 tempbx = 0;
7159 if(!(modeflag & HalfDCLK)) {
7160 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7161 tempax = 0;
7162 tempbx |= 0x20;
7163 }
7164 }
7165
7166 tempch = tempcl = 0x01;
7167 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7168 if(SiS_Pr->SiS_VGAHDE >= 960) {
7169 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7170 tempcl = 0x20;
7171 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7172 tempch = 20;
7173 tempbx &= ~0x20;
7174 } else {
7175 tempch = 25; /* OK */
7176 }
7177 }
7178 }
7179 }
7180
7181 if(!(tempbx & 0x20)) {
7182 if(modeflag & HalfDCLK) tempcl <<= 1;
7183 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7184 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7185 tempax = longtemp / SiS_Pr->SiS_HDE;
7186 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7187 tempbx |= ((tempax >> 8) & 0x1F);
7188 tempcx = tempax >> 13;
7189 }
7190
7191 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7192 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7193
7194 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7195
7196 tempcx &= 0x07;
7197 if(tempbx & 0x20) tempcx = 0;
7198 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7199
7200 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7201 tempbx = 0x0382;
7202 tempcx = 0x007e;
7203 } else {
7204 tempbx = 0x0369;
7205 tempcx = 0x0061;
7206 }
7207 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7208 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7209 temp = (tempcx & 0x0300) >> 6;
7210 temp |= ((tempbx >> 8) & 0x03);
7211 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7212 temp |= 0x10;
7213 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7214 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7215 }
7216 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7217
7218 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7219 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7220
7221 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7222
7223 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7224 temp = 0;
7225 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7226 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7227 }
7228
7229 }
7230
7231 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7232 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7233 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7234 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7235 }
7236 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7237 }
7238
7239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7240 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7241 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7242 }
7243 }
7244
7245 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7246
7247 /* From here: Part2 LCD setup */
7248
7249 tempbx = SiS_Pr->SiS_HDE;
7250 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7251 tempbx--; /* RHACTE = HDE - 1 */
7252 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7253 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7254
7255 temp = 0x01;
7256 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7257 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7258 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7259 temp = 0x02;
7260 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7261 temp = 0x01;
7262 }
7263 }
7264 }
7265 }
7266 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7267
7268 tempbx = SiS_Pr->SiS_VDE - 1;
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7270 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7271
7272 tempcx = SiS_Pr->SiS_VT - 1;
7273 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7274 temp = (tempcx >> 3) & 0xE0;
7275 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7276 /* Enable dithering; only do this for 32bpp mode */
7277 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7278 temp |= 0x10;
7279 }
7280 }
7281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7282
7283 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7285
7286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7288
7289 #ifdef CONFIG_FB_SIS_315
7290 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7291 &CRT2Index, &resindex)) {
7292 switch(CRT2Index) {
7293 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7294 default:
7295 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7296 }
7297
7298 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7300 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7301 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7302 }
7303 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7304 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305 }
7306 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308 }
7309 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7310 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7311
7312 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7313
7314 } else {
7315 #endif
7316
7317 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7318 /* Clevo dual-link 1024x768 */
7319 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7320 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7321
7322 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7323 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7324 tempbx = SiS_Pr->SiS_VDE - 1;
7325 tempcx = SiS_Pr->SiS_VT - 1;
7326 } else {
7327 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7328 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329 }
7330 } else {
7331 tempbx = SiS_Pr->PanelYRes;
7332 tempcx = SiS_Pr->SiS_VT;
7333 tempax = 1;
7334 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7335 tempax = SiS_Pr->PanelYRes;
7336 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7337 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7338 tempax = tempcx = 0;
7339 } else {
7340 tempax -= SiS_Pr->SiS_VDE;
7341 }
7342 tempax >>= 1;
7343 }
7344 tempcx -= tempax; /* lcdvdes */
7345 tempbx -= tempax; /* lcdvdee */
7346 }
7347
7348 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7349
7350 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7351 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7352
7353 temp = (tempbx >> 5) & 0x38;
7354 temp |= ((tempcx >> 8) & 0x07);
7355 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7356
7357 tempax = SiS_Pr->SiS_VDE;
7358 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7359 tempax = SiS_Pr->PanelYRes;
7360 }
7361 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7362 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7363 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7364 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7365 }
7366 }
7367
7368 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7369 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7370 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7371 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7372 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7373 if(tempax % 4) { tempax >>= 2; tempax++; }
7374 else { tempax >>= 2; }
7375 tempbx -= (tempax - 1);
7376 } else {
7377 tempbx -= 10;
7378 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7379 }
7380 }
7381 }
7382 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7383 tempbx++;
7384 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7385 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7386 tempbx = 770;
7387 tempcx = 3;
7388 }
7389 }
7390 }
7391
7392 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7393
7394 if(SiS_Pr->UseCustomMode) {
7395 tempbx = SiS_Pr->CVSyncStart;
7396 }
7397
7398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7399
7400 temp = (tempbx >> 4) & 0xF0;
7401 tempbx += (tempcx + 1);
7402 temp |= (tempbx & 0x0F);
7403
7404 if(SiS_Pr->UseCustomMode) {
7405 temp &= 0xf0;
7406 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7407 }
7408
7409 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7410
7411 #ifdef CONFIG_FB_SIS_300
7412 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7413 #endif
7414
7415 bridgeoffset = 7;
7416 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7417 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7418 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7419 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7420 /* Higher bridgeoffset shifts to the LEFT */
7421
7422 temp = 0;
7423 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7424 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7425 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7426 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7427 }
7428 }
7429 temp += bridgeoffset;
7430 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7431 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7432
7433 tempcx = SiS_Pr->SiS_HT;
7434 tempax = tempbx = SiS_Pr->SiS_HDE;
7435 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7436 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7437 tempax = SiS_Pr->PanelXRes;
7438 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7439 }
7440 }
7441 if(SiS_IsDualLink(SiS_Pr)) {
7442 tempcx >>= 1;
7443 tempbx >>= 1;
7444 tempax >>= 1;
7445 }
7446
7447 tempbx += bridgeoffset;
7448
7449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7450 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7451
7452 tempcx = (tempcx - tempax) >> 2;
7453
7454 tempbx += tempcx;
7455 push2 = tempbx;
7456
7457 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7458 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7459 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7460 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7461 }
7462 }
7463 }
7464
7465 if(SiS_Pr->UseCustomMode) {
7466 tempbx = SiS_Pr->CHSyncStart;
7467 if(modeflag & HalfDCLK) tempbx <<= 1;
7468 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7469 tempbx += bridgeoffset;
7470 }
7471
7472 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7473 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7474
7475 tempbx = push2;
7476
7477 tempcx <<= 1;
7478 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7479 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7480 }
7481 tempbx += tempcx;
7482
7483 if(SiS_Pr->UseCustomMode) {
7484 tempbx = SiS_Pr->CHSyncEnd;
7485 if(modeflag & HalfDCLK) tempbx <<= 1;
7486 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7487 tempbx += bridgeoffset;
7488 }
7489
7490 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7491
7492 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7493
7494 #ifdef CONFIG_FB_SIS_300
7495 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7496 #endif
7497 #ifdef CONFIG_FB_SIS_315
7498 } /* CRT2-LCD from table */
7499 #endif
7500 }
7501
7502 /*********************************************/
7503 /* SET PART 3 REGISTER GROUP */
7504 /*********************************************/
7505
7506 static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7507 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7508 {
7509 unsigned short i;
7510 const unsigned char *tempdi;
7511
7512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7513
7514 #ifndef SIS_CP
7515 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7516 #else
7517 SIS_CP_INIT301_CP
7518 #endif
7519
7520 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7521 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7522 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7523 } else {
7524 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7526 }
7527
7528 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7529 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7530 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7531 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7532 }
7533
7534 tempdi = NULL;
7535 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7536 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7537 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7538 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7539 }
7540 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7541 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7542 tempdi = SiS_HiTVGroup3_1;
7543 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7544 }
7545 }
7546 if(tempdi) {
7547 for(i=0; i<=0x3E; i++) {
7548 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7549 }
7550 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7551 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7552 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7553 }
7554 }
7555 }
7556
7557 #ifdef SIS_CP
7558 SIS_CP_INIT301_CP2
7559 #endif
7560 }
7561
7562 /*********************************************/
7563 /* SET PART 4 REGISTER GROUP */
7564 /*********************************************/
7565
7566 #ifdef CONFIG_FB_SIS_315
7567 #if 0
7568 static void
7569 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7570 {
7571 unsigned short temp, temp1, temp2;
7572
7573 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7574 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7575 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7576 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7577 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7578 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7579 temp = (unsigned short)((int)(temp) + shift);
7580 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7581 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7582 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7583 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7584 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7585 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7586 }
7587 #endif
7588
7589 static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7590 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7591 {
7592 unsigned short temp, temp1;
7593 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7594
7595 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7596 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7597
7598 if(SiS_Pr->ChipType >= XGI_20) return;
7599
7600 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7601 if(!(ROMAddr[0x61] & 0x04)) return;
7602 }
7603
7604 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7605 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7606 if(!(temp & 0x01)) {
7607 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7608 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7609 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7610 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7611 }
7612 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7613 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7614 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7615 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7616 else temp = 0x0402;
7617 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7618 temp1 = 0;
7619 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7620 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7621 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7622 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7624 if(ModeNo > 0x13) {
7625 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7626 }
7627 } else {
7628 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7629 if(temp1 == 0x01) temp |= 0x01;
7630 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7631 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7632 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7633 if(ModeNo > 0x13) {
7634 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7635 }
7636 }
7637
7638 #if 0
7639 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7640 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7641 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7642 if(resinfo == SIS_RI_1024x768) {
7643 SiS_ShiftXPos(SiS_Pr, 97);
7644 } else {
7645 SiS_ShiftXPos(SiS_Pr, 111);
7646 }
7647 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7648 SiS_ShiftXPos(SiS_Pr, 136);
7649 }
7650 }
7651 }
7652 #endif
7653
7654 }
7655
7656 }
7657 #endif
7658
7659 static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7660 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7661 unsigned short RefreshRateTableIndex)
7662 {
7663 unsigned short vclkindex, temp, reg1, reg2;
7664
7665 if(SiS_Pr->UseCustomMode) {
7666 reg1 = SiS_Pr->CSR2B;
7667 reg2 = SiS_Pr->CSR2C;
7668 } else {
7669 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7670 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7671 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7672 }
7673
7674 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7675 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7676 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7679 } else {
7680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7682 }
7683 } else {
7684 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7686 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7687 }
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7689 temp = 0x08;
7690 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7691 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7692 }
7693
7694 static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7695 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7696 {
7697 if(SiS_Pr->ChipType >= SIS_315H) {
7698 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7699 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7700 (SiS_IsVAMode(SiS_Pr))) {
7701 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7702 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7703 } else {
7704 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7705 }
7706 }
7707 }
7708 }
7709 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7710 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7711 #ifdef SET_EMI
7712 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7713 #endif
7714 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7715 }
7716 }
7717
7718 static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7719 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7720 unsigned short RefreshRateTableIndex)
7721 {
7722 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7723 unsigned int tempebx, tempeax, templong;
7724
7725 if(ModeNo <= 0x13) {
7726 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7727 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7728 } else if(SiS_Pr->UseCustomMode) {
7729 modeflag = SiS_Pr->CModeFlag;
7730 resinfo = 0;
7731 } else {
7732 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7733 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7734 }
7735
7736 if(SiS_Pr->ChipType >= SIS_315H) {
7737 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7738 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7739 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7740 }
7741 }
7742 }
7743
7744 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7745 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7746 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7747 }
7748 }
7749
7750 if(SiS_Pr->ChipType >= SIS_315H) {
7751 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7752 SiS_SetDualLinkEtc(SiS_Pr);
7753 return;
7754 }
7755 }
7756
7757 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7758
7759 tempbx = SiS_Pr->SiS_RVBHCMAX;
7760 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7761
7762 temp = (tempbx >> 1) & 0x80;
7763
7764 tempcx = SiS_Pr->SiS_VGAHT - 1;
7765 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7766
7767 temp |= ((tempcx >> 5) & 0x78);
7768
7769 tempcx = SiS_Pr->SiS_VGAVT - 1;
7770 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7771 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7772
7773 temp |= ((tempcx >> 8) & 0x07);
7774 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7775
7776 tempbx = SiS_Pr->SiS_VGAHDE;
7777 if(modeflag & HalfDCLK) tempbx >>= 1;
7778 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7779
7780 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7781 temp = 0;
7782 if(tempbx > 800) temp = 0x60;
7783 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7784 temp = 0;
7785 if(tempbx > 1024) temp = 0xC0;
7786 else if(tempbx >= 960) temp = 0xA0;
7787 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7788 temp = 0;
7789 if(tempbx >= 1280) temp = 0x40;
7790 else if(tempbx >= 1024) temp = 0x20;
7791 } else {
7792 temp = 0x80;
7793 if(tempbx >= 1024) temp = 0xA0;
7794 }
7795
7796 temp |= SiS_Pr->Init_P4_0E;
7797
7798 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7799 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7800 temp &= 0xf0;
7801 temp |= 0x0A;
7802 }
7803 }
7804
7805 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7806
7807 tempeax = SiS_Pr->SiS_VGAVDE;
7808 tempebx = SiS_Pr->SiS_VDE;
7809 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7810 if(!(temp & 0xE0)) tempebx >>=1;
7811 }
7812
7813 tempcx = SiS_Pr->SiS_RVBHRS;
7814 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7815 tempcx >>= 8;
7816 tempcx |= 0x40;
7817
7818 if(tempeax <= tempebx) {
7819 tempcx ^= 0x40;
7820 } else {
7821 tempeax -= tempebx;
7822 }
7823
7824 tempeax *= (256 * 1024);
7825 templong = tempeax % tempebx;
7826 tempeax /= tempebx;
7827 if(templong) tempeax++;
7828
7829 temp = (unsigned short)(tempeax & 0x000000FF);
7830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7831 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7833 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7834 temp |= (tempcx & 0x4F);
7835 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7836
7837 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7838
7839 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7840
7841 /* Calc Linebuffer max address and set/clear decimode */
7842 tempbx = 0;
7843 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7844 tempax = SiS_Pr->SiS_VGAHDE;
7845 if(modeflag & HalfDCLK) tempax >>= 1;
7846 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7847 if(tempax > 800) {
7848 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7849 tempax -= 800;
7850 } else {
7851 tempbx = 0x08;
7852 if(tempax == 960) tempax *= 25; /* Correct */
7853 else if(tempax == 1024) tempax *= 25;
7854 else tempax *= 20;
7855 temp = tempax % 32;
7856 tempax /= 32;
7857 if(temp) tempax++;
7858 tempax++;
7859 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7860 if(resinfo == SIS_RI_1024x768 ||
7861 resinfo == SIS_RI_1024x576 ||
7862 resinfo == SIS_RI_1280x1024 ||
7863 resinfo == SIS_RI_1280x720) {
7864 /* Otherwise white line or garbage at right edge */
7865 tempax = (tempax & 0xff00) | 0x20;
7866 }
7867 }
7868 }
7869 }
7870 tempax--;
7871 temp = ((tempax >> 4) & 0x30) | tempbx;
7872 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7873 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7874
7875 temp = 0x0036; tempbx = 0xD0;
7876 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7877 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7878 }
7879 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7880 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7881 temp |= 0x01;
7882 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7883 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7884 temp &= ~0x01;
7885 }
7886 }
7887 }
7888 }
7889 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7890
7891 tempbx = SiS_Pr->SiS_HT >> 1;
7892 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7893 tempbx -= 2;
7894 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7895 temp = (tempbx >> 5) & 0x38;
7896 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7897
7898 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7899 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7900 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7901 /* LCD-too-dark-error-source, see FinalizeLCD() */
7902 }
7903 }
7904
7905 SiS_SetDualLinkEtc(SiS_Pr);
7906
7907 } /* 301B */
7908
7909 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7910 }
7911
7912 /*********************************************/
7913 /* SET PART 5 REGISTER GROUP */
7914 /*********************************************/
7915
7916 static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7917 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7918 {
7919
7920 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7921
7922 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7923 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7924 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7925 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7926 }
7927 }
7928 }
7929
7930 /*********************************************/
7931 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7932 /*********************************************/
7933
7934 static bool
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7935 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7936 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7937 unsigned short *DisplayType)
7938 {
7939 unsigned short modeflag = 0;
7940 bool checkhd = true;
7941
7942 /* Pass 1:1 not supported here */
7943
7944 if(ModeNo <= 0x13) {
7945 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7946 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7947 } else {
7948 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7949 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7950 }
7951
7952 (*ResIndex) &= 0x3F;
7953
7954 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7955
7956 (*DisplayType) = 80;
7957 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7958 (*DisplayType) = 82;
7959 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7960 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7961 }
7962 }
7963 if((*DisplayType) != 84) {
7964 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7965 }
7966
7967 } else {
7968
7969 (*DisplayType = 0);
7970 switch(SiS_Pr->SiS_LCDResInfo) {
7971 case Panel_320x240_1: (*DisplayType) = 50;
7972 checkhd = false;
7973 break;
7974 case Panel_320x240_2: (*DisplayType) = 14;
7975 break;
7976 case Panel_320x240_3: (*DisplayType) = 18;
7977 break;
7978 case Panel_640x480: (*DisplayType) = 10;
7979 break;
7980 case Panel_1024x600: (*DisplayType) = 26;
7981 break;
7982 default: return true;
7983 }
7984
7985 if(checkhd) {
7986 if(modeflag & HalfDCLK) (*DisplayType)++;
7987 }
7988
7989 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7990 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7991 }
7992
7993 }
7994
7995 return true;
7996 }
7997
7998 static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7999 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8000 unsigned short RefreshRateTableIndex)
8001 {
8002 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8003 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8004 static const unsigned short CRIdx[] = {
8005 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8006 0x07, 0x10, 0x11, 0x15, 0x16
8007 };
8008
8009 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8010 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8011 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
8012 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8013 return;
8014
8015 if(SiS_Pr->SiS_IF_DEF_LVDS) {
8016 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8017 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8018 }
8019 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8020 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8021 } else return;
8022
8023 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8024
8025 if(SiS_Pr->ChipType < SIS_315H) {
8026 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8027 }
8028
8029 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8030 &ResIndex, &DisplayType))) {
8031 return;
8032 }
8033
8034 switch(DisplayType) {
8035 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
8036 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
8037 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
8038 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
8039 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
8040 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8041 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8042 #if 0 /* Works better with calculated numbers */
8043 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
8044 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
8045 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
8046 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
8047 #endif
8048 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
8049 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
8050 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
8051 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
8052 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8053 }
8054
8055 if(LVDSCRT1Ptr) {
8056
8057 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8058
8059 for(i = 0; i <= 10; i++) {
8060 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8061 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8062 }
8063
8064 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8065 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8066 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8067 }
8068
8069 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8070 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8071
8072 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8073 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8074
8075 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8076 if(modeflag & DoubleScanMode) tempah |= 0x80;
8077 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8078
8079 } else {
8080
8081 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8082
8083 }
8084 }
8085
8086 /*********************************************/
8087 /* SET CRT2 ECLK */
8088 /*********************************************/
8089
8090 static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8091 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8092 unsigned short RefreshRateTableIndex)
8093 {
8094 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8095 unsigned short clkbase, vclkindex = 0;
8096 unsigned char sr2b, sr2c;
8097
8098 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8099 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8100 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8101 RefreshRateTableIndex--;
8102 }
8103 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8104 RefreshRateTableIndex);
8105 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8106 } else {
8107 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8108 RefreshRateTableIndex);
8109 }
8110
8111 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8112 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8113
8114 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8115 if(SiS_Pr->SiS_UseROM) {
8116 if(ROMAddr[0x220] & 0x01) {
8117 sr2b = ROMAddr[0x227];
8118 sr2c = ROMAddr[0x228];
8119 }
8120 }
8121 }
8122
8123 clkbase = 0x02B;
8124 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8125 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8126 clkbase += 3;
8127 }
8128 }
8129
8130 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8131 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8132 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8133 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8134 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8135 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8136 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8137 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8139 }
8140
8141 /*********************************************/
8142 /* SET UP CHRONTEL CHIPS */
8143 /*********************************************/
8144
8145 static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8146 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8147 unsigned short RefreshRateTableIndex)
8148 {
8149 unsigned short TVType, resindex;
8150 const struct SiS_CHTVRegData *CHTVRegData = NULL;
8151
8152 if(ModeNo <= 0x13)
8153 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8154 else
8155 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8156
8157 resindex &= 0x3F;
8158
8159 TVType = 0;
8160 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8161 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8162 TVType += 2;
8163 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8164 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8165 }
8166 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8167 TVType = 4;
8168 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8169 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8170 TVType = 6;
8171 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8172 }
8173 }
8174
8175 switch(TVType) {
8176 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8177 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8178 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8179 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8180 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8181 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8182 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8183 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8184 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8185 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8186 }
8187
8188
8189 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8190
8191 #ifdef CONFIG_FB_SIS_300
8192
8193 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8194
8195 /* We don't support modes >800x600 */
8196 if (resindex > 5) return;
8197
8198 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8199 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8200 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8201 } else {
8202 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8203 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8204 }
8205
8206 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8207 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8208 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8209 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8210 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8211
8212 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8213 minimum text enhancement (S3-2=10),
8214 maximum flicker filter for Chroma channel (S5-4=10)
8215 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8216 */
8217 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8218
8219 /* Set video bandwidth
8220 High bandwidth Luma composite video filter(S0=1)
8221 low bandwidth Luma S-video filter (S2-1=00)
8222 disable peak filter in S-video channel (S3=0)
8223 high bandwidth Chroma Filter (S5-4=11)
8224 =00110001=0x31
8225 */
8226 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8227
8228 /* Register 0x3D does not exist in non-macrovision register map
8229 (Maybe this is a macrovision register?)
8230 */
8231 #ifndef SIS_CP
8232 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8233 #endif
8234
8235 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8236 all other bits a read-only. Macrovision?
8237 */
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8239
8240 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8241 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8242 */
8243 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8244
8245 /* Clear DSEN
8246 */
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8248
8249 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8250 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8251 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8254 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8261 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8264 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8265 }
8266 } else {
8267 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8268 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8270 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8271 #if 0
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8273 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8274 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8275 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8276 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8280 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8281 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8282 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8283 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8284 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8285 }
8286 }
8287 } else { /* ---- PAL ---- */
8288 /* We don't play around with FSCI in PAL mode */
8289 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */
8290 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */
8291 }
8292
8293 #endif /* 300 */
8294
8295 } else {
8296
8297 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8298
8299 #ifdef CONFIG_FB_SIS_315
8300
8301 unsigned short temp;
8302
8303 /* We don't support modes >1024x768 */
8304 if (resindex > 6) return;
8305
8306 temp = CHTVRegData[resindex].Reg[0];
8307 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8308 SiS_SetCH701x(SiS_Pr,0x00,temp);
8309
8310 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8311 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8312 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8313 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8314 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8315 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8316
8317 temp = CHTVRegData[resindex].Reg[7];
8318 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8319 SiS_SetCH701x(SiS_Pr,0x07,temp);
8320
8321 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8322 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8323 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8324 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8325 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8326 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8327 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8328 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8329
8330 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8331 /* D1 should be set for PAL, PAL-N and NTSC-J,
8332 but I won't do that for PAL unless somebody
8333 tells me to do so. Since the BIOS uses
8334 non-default CIV values and blacklevels,
8335 this might be compensated anyway.
8336 */
8337 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8338 SiS_SetCH701x(SiS_Pr,0x21,temp);
8339
8340 #endif /* 315 */
8341
8342 }
8343
8344 #ifdef SIS_CP
8345 SIS_CP_INIT301_CP3
8346 #endif
8347
8348 }
8349
8350 #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8351
8352 void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8353 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8354 {
8355 unsigned short temp;
8356
8357 /* Enable Chrontel 7019 LCD panel backlight */
8358 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8359 if(SiS_Pr->ChipType == SIS_740) {
8360 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8361 } else {
8362 temp = SiS_GetCH701x(SiS_Pr,0x66);
8363 temp |= 0x20;
8364 SiS_SetCH701x(SiS_Pr,0x66,temp);
8365 }
8366 }
8367 }
8368
8369 void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8370 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8371 {
8372 unsigned short temp;
8373
8374 /* Disable Chrontel 7019 LCD panel backlight */
8375 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8376 temp = SiS_GetCH701x(SiS_Pr,0x66);
8377 temp &= 0xDF;
8378 SiS_SetCH701x(SiS_Pr,0x66,temp);
8379 }
8380 }
8381
8382 static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8383 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8384 {
8385 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8386 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8387 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8388 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8389 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8391 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392 const unsigned char *tableptr = NULL;
8393 int i;
8394
8395 /* Set up Power up/down timing */
8396
8397 if(SiS_Pr->ChipType == SIS_740) {
8398 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8399 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8400 else tableptr = table1024_740;
8401 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8402 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8403 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8404 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8405 else tableptr = table1400_740;
8406 } else return;
8407 } else {
8408 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8409 tableptr = table1024_650;
8410 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8411 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8412 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8413 tableptr = table1400_650;
8414 } else return;
8415 }
8416
8417 for(i=0; i<5; i++) {
8418 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8419 }
8420 }
8421
8422 static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8423 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8424 {
8425 const unsigned char *tableptr = NULL;
8426 unsigned short tempbh;
8427 int i;
8428 static const unsigned char regtable[] = {
8429 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8430 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8431 };
8432 static const unsigned char table1024_740[] = {
8433 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8434 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8435 };
8436 static const unsigned char table1280_740[] = {
8437 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8438 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8439 };
8440 static const unsigned char table1400_740[] = {
8441 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8442 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8443 };
8444 static const unsigned char table1600_740[] = {
8445 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8446 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8447 };
8448 static const unsigned char table1024_650[] = {
8449 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8450 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8451 };
8452 static const unsigned char table1280_650[] = {
8453 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8454 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8455 };
8456 static const unsigned char table1400_650[] = {
8457 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8458 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8459 };
8460 static const unsigned char table1600_650[] = {
8461 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8462 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8463 };
8464
8465 if(SiS_Pr->ChipType == SIS_740) {
8466 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8467 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8468 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8470 else return;
8471 } else {
8472 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8473 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8474 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8475 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8476 else return;
8477 }
8478
8479 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8480 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8481 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8482 if(tempbh == 0xc8) {
8483 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8484 } else if(tempbh == 0xdb) {
8485 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8487 } else if(tempbh == 0xde) {
8488 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8489 }
8490 }
8491
8492 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8493 else tempbh = 0x0c;
8494
8495 for(i = 0; i < tempbh; i++) {
8496 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8497 }
8498 SiS_ChrontelPowerSequencing(SiS_Pr);
8499 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8500 tempbh |= 0xc0;
8501 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8502
8503 if(SiS_Pr->ChipType == SIS_740) {
8504 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8505 tempbh &= 0xfb;
8506 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8507 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8508 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8509 tempbh |= 0x40;
8510 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8511 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8512 tempbh &= 0x3f;
8513 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8514 }
8515 }
8516
8517 static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8518 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8519 {
8520 unsigned char temp, temp1;
8521
8522 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8523 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8524 temp = SiS_GetCH701x(SiS_Pr,0x47);
8525 temp &= 0x7f; /* Use external VSYNC */
8526 SiS_SetCH701x(SiS_Pr,0x47,temp);
8527 SiS_LongDelay(SiS_Pr, 3);
8528 temp = SiS_GetCH701x(SiS_Pr,0x47);
8529 temp |= 0x80; /* Use internal VSYNC */
8530 SiS_SetCH701x(SiS_Pr,0x47,temp);
8531 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8532 }
8533
8534 static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8535 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8536 {
8537 unsigned short temp;
8538
8539 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8540 if(SiS_Pr->ChipType == SIS_740) {
8541 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8542 temp |= 0x04; /* Invert XCLK phase */
8543 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8544 }
8545 if(SiS_IsYPbPr(SiS_Pr)) {
8546 temp = SiS_GetCH701x(SiS_Pr,0x01);
8547 temp &= 0x3f;
8548 temp |= 0x80; /* Enable YPrPb (HDTV) */
8549 SiS_SetCH701x(SiS_Pr,0x01,temp);
8550 }
8551 if(SiS_IsChScart(SiS_Pr)) {
8552 temp = SiS_GetCH701x(SiS_Pr,0x01);
8553 temp &= 0x3f;
8554 temp |= 0xc0; /* Enable SCART + CVBS */
8555 SiS_SetCH701x(SiS_Pr,0x01,temp);
8556 }
8557 if(SiS_Pr->ChipType == SIS_740) {
8558 SiS_ChrontelResetVSync(SiS_Pr);
8559 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8560 } else {
8561 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8562 temp = SiS_GetCH701x(SiS_Pr,0x49);
8563 if(SiS_IsYPbPr(SiS_Pr)) {
8564 temp = SiS_GetCH701x(SiS_Pr,0x73);
8565 temp |= 0x60;
8566 SiS_SetCH701x(SiS_Pr,0x73,temp);
8567 }
8568 temp = SiS_GetCH701x(SiS_Pr,0x47);
8569 temp &= 0x7f;
8570 SiS_SetCH701x(SiS_Pr,0x47,temp);
8571 SiS_LongDelay(SiS_Pr, 2);
8572 temp = SiS_GetCH701x(SiS_Pr,0x47);
8573 temp |= 0x80;
8574 SiS_SetCH701x(SiS_Pr,0x47,temp);
8575 }
8576 }
8577 }
8578
8579 static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8580 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8581 {
8582 unsigned short temp;
8583
8584 /* Complete power down of LVDS */
8585 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8586 if(SiS_Pr->ChipType == SIS_740) {
8587 SiS_LongDelay(SiS_Pr, 1);
8588 SiS_GenericDelay(SiS_Pr, 5887);
8589 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8590 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8591 } else {
8592 SiS_LongDelay(SiS_Pr, 2);
8593 temp = SiS_GetCH701x(SiS_Pr,0x76);
8594 temp &= 0xfc;
8595 SiS_SetCH701x(SiS_Pr,0x76,temp);
8596 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8597 }
8598 }
8599 }
8600
8601 static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8602 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8603 {
8604 unsigned short temp;
8605
8606 if(SiS_Pr->ChipType == SIS_740) {
8607
8608 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8609 temp &= 0x01;
8610 if(!temp) {
8611
8612 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8613 temp = SiS_GetCH701x(SiS_Pr,0x49);
8614 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8615 }
8616
8617 /* Reset Chrontel 7019 datapath */
8618 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8619 SiS_LongDelay(SiS_Pr, 1);
8620 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8621
8622 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8623 SiS_ChrontelResetVSync(SiS_Pr);
8624 SiS_SetCH701x(SiS_Pr,0x49,temp);
8625 }
8626
8627 } else {
8628
8629 /* Clear/set/clear GPIO */
8630 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8631 temp &= 0xef;
8632 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8633 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8634 temp |= 0x10;
8635 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8636 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8637 temp &= 0xef;
8638 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8639 temp = SiS_GetCH701x(SiS_Pr,0x61);
8640 if(!temp) {
8641 SiS_SetCH701xForLCD(SiS_Pr);
8642 }
8643 }
8644
8645 } else { /* 650 */
8646 /* Reset Chrontel 7019 datapath */
8647 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8648 SiS_LongDelay(SiS_Pr, 1);
8649 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8650 }
8651 }
8652
8653 static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8654 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8655 {
8656 unsigned short temp;
8657
8658 if(SiS_Pr->ChipType == SIS_740) {
8659
8660 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8661 SiS_ChrontelResetVSync(SiS_Pr);
8662 }
8663
8664 } else {
8665
8666 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8667 temp = SiS_GetCH701x(SiS_Pr,0x49);
8668 temp &= 1;
8669 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8670 temp = SiS_GetCH701x(SiS_Pr,0x47);
8671 temp &= 0x70;
8672 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8673 SiS_LongDelay(SiS_Pr, 3);
8674 temp = SiS_GetCH701x(SiS_Pr,0x47);
8675 temp |= 0x80;
8676 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8677 }
8678
8679 }
8680 }
8681
8682 static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8683 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8684 {
8685 unsigned short temp,temp1;
8686
8687 if(SiS_Pr->ChipType == SIS_740) {
8688
8689 temp = SiS_GetCH701x(SiS_Pr,0x61);
8690 if(temp < 1) {
8691 temp++;
8692 SiS_SetCH701x(SiS_Pr,0x61,temp);
8693 }
8694 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8695 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8696 SiS_LongDelay(SiS_Pr, 1);
8697 SiS_GenericDelay(SiS_Pr, 5887);
8698
8699 } else { /* 650 */
8700
8701 temp1 = 0;
8702 temp = SiS_GetCH701x(SiS_Pr,0x61);
8703 if(temp < 2) {
8704 temp++;
8705 SiS_SetCH701x(SiS_Pr,0x61,temp);
8706 temp1 = 1;
8707 }
8708 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8709 temp = SiS_GetCH701x(SiS_Pr,0x66);
8710 temp |= 0x5f;
8711 SiS_SetCH701x(SiS_Pr,0x66,temp);
8712 if(ModeNo > 0x13) {
8713 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8714 SiS_GenericDelay(SiS_Pr, 1023);
8715 } else {
8716 SiS_GenericDelay(SiS_Pr, 767);
8717 }
8718 } else {
8719 if(!temp1)
8720 SiS_GenericDelay(SiS_Pr, 767);
8721 }
8722 temp = SiS_GetCH701x(SiS_Pr,0x76);
8723 temp |= 0x03;
8724 SiS_SetCH701x(SiS_Pr,0x76,temp);
8725 temp = SiS_GetCH701x(SiS_Pr,0x66);
8726 temp &= 0x7f;
8727 SiS_SetCH701x(SiS_Pr,0x66,temp);
8728 SiS_LongDelay(SiS_Pr, 1);
8729
8730 }
8731 }
8732
8733 static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8734 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8735 {
8736 unsigned short temp;
8737
8738 SiS_LongDelay(SiS_Pr, 1);
8739
8740 do {
8741 temp = SiS_GetCH701x(SiS_Pr,0x66);
8742 temp &= 0x04; /* PLL stable? -> bail out */
8743 if(temp == 0x04) break;
8744
8745 if(SiS_Pr->ChipType == SIS_740) {
8746 /* Power down LVDS output, PLL normal operation */
8747 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8748 }
8749
8750 SiS_SetCH701xForLCD(SiS_Pr);
8751
8752 temp = SiS_GetCH701x(SiS_Pr,0x76);
8753 temp &= 0xfb; /* Reset PLL */
8754 SiS_SetCH701x(SiS_Pr,0x76,temp);
8755 SiS_LongDelay(SiS_Pr, 2);
8756 temp = SiS_GetCH701x(SiS_Pr,0x76);
8757 temp |= 0x04; /* PLL normal operation */
8758 SiS_SetCH701x(SiS_Pr,0x76,temp);
8759 if(SiS_Pr->ChipType == SIS_740) {
8760 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8761 } else {
8762 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8763 }
8764 SiS_LongDelay(SiS_Pr, 2);
8765 } while(0);
8766
8767 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8768 }
8769
8770 static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8771 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8772 {
8773 unsigned short temp;
8774
8775 temp = SiS_GetCH701x(SiS_Pr,0x03);
8776 temp |= 0x80; /* Set datapath 1 to TV */
8777 temp &= 0xbf; /* Set datapath 2 to LVDS */
8778 SiS_SetCH701x(SiS_Pr,0x03,temp);
8779
8780 if(SiS_Pr->ChipType == SIS_740) {
8781
8782 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8783 temp &= 0xfb; /* Normal XCLK phase */
8784 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8785
8786 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8787
8788 temp = SiS_GetCH701x(SiS_Pr,0x64);
8789 temp |= 0x40; /* ? Bit not defined */
8790 SiS_SetCH701x(SiS_Pr,0x64,temp);
8791
8792 temp = SiS_GetCH701x(SiS_Pr,0x03);
8793 temp &= 0x3f; /* D1 input to both LVDS and TV */
8794 SiS_SetCH701x(SiS_Pr,0x03,temp);
8795
8796 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8797 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8798 SiS_LongDelay(SiS_Pr, 1);
8799 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8800 SiS_ChrontelResetDB(SiS_Pr);
8801 SiS_ChrontelDoSomething2(SiS_Pr);
8802 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8803 } else {
8804 temp = SiS_GetCH701x(SiS_Pr,0x66);
8805 if(temp != 0x45) {
8806 SiS_ChrontelResetDB(SiS_Pr);
8807 SiS_ChrontelDoSomething2(SiS_Pr);
8808 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8809 }
8810 }
8811
8812 } else { /* 650 */
8813
8814 SiS_ChrontelResetDB(SiS_Pr);
8815 SiS_ChrontelDoSomething2(SiS_Pr);
8816 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8817 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8818 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8819
8820 }
8821
8822 }
8823 #endif /* 315 series */
8824
8825 /*********************************************/
8826 /* MAIN: SET CRT2 REGISTER GROUP */
8827 /*********************************************/
8828
8829 bool
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8830 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8831 {
8832 #ifdef CONFIG_FB_SIS_300
8833 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8834 #endif
8835 unsigned short ModeIdIndex, RefreshRateTableIndex;
8836
8837 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8838
8839 if(!SiS_Pr->UseCustomMode) {
8840 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8841 } else {
8842 ModeIdIndex = 0;
8843 }
8844
8845 /* Used for shifting CR33 */
8846 SiS_Pr->SiS_SelectCRT2Rate = 4;
8847
8848 SiS_UnLockCRT2(SiS_Pr);
8849
8850 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8851
8852 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8853
8854 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8855 SiS_DisableBridge(SiS_Pr);
8856 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8858 }
8859 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8860 }
8861
8862 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8863 SiS_LockCRT2(SiS_Pr);
8864 SiS_DisplayOn(SiS_Pr);
8865 return true;
8866 }
8867
8868 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8869
8870 /* Set up Panel Link for LVDS and LCDA */
8871 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8872 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8873 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8874 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8875 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8876 }
8877
8878 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8879 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8880 }
8881
8882 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8883
8884 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8885
8886 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8887 #ifdef CONFIG_FB_SIS_315
8888 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8889 #endif
8890 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8891 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8892 #ifdef CONFIG_FB_SIS_315
8893 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8894 #endif
8895 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8896
8897 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8898
8899 /* For 301BDH (Panel link initialization): */
8900 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8901
8902 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8903 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8904 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8905 }
8906 }
8907 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8908 }
8909 }
8910
8911 } else {
8912
8913 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8914
8915 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8916
8917 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8918
8919 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8920 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8921 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8922 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8923 #ifdef CONFIG_FB_SIS_315
8924 SiS_SetCH701xForLCD(SiS_Pr);
8925 #endif
8926 }
8927 }
8928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8929 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8930 }
8931 }
8932 }
8933
8934 }
8935
8936 #ifdef CONFIG_FB_SIS_300
8937 if(SiS_Pr->ChipType < SIS_315H) {
8938 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8939 if(SiS_Pr->SiS_UseOEM) {
8940 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8941 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8942 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8943 }
8944 } else {
8945 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8946 }
8947 }
8948 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8949 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8950 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8951 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8952 }
8953 SiS_DisplayOn(SiS_Pr);
8954 }
8955 }
8956 }
8957 #endif
8958
8959 #ifdef CONFIG_FB_SIS_315
8960 if(SiS_Pr->ChipType >= SIS_315H) {
8961 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8962 if(SiS_Pr->ChipType < SIS_661) {
8963 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8964 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8965 } else {
8966 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8967 }
8968 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8969 }
8970 }
8971 #endif
8972
8973 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8974 SiS_EnableBridge(SiS_Pr);
8975 }
8976
8977 SiS_DisplayOn(SiS_Pr);
8978
8979 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8980 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8981 /* Disable LCD panel when using TV */
8982 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8983 } else {
8984 /* Disable TV when using LCD */
8985 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8986 }
8987 }
8988
8989 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8990 SiS_LockCRT2(SiS_Pr);
8991 }
8992
8993 return true;
8994 }
8995
8996
8997 /*********************************************/
8998 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8999 /*********************************************/
9000
9001 void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)9002 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9003 {
9004 /* Switch on LCD backlight on SiS30xLV */
9005 SiS_DDC2Delay(SiS_Pr,0xff00);
9006 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9007 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9008 SiS_WaitVBRetrace(SiS_Pr);
9009 }
9010 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9011 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9012 }
9013 }
9014
9015 void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)9016 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9017 {
9018 /* Switch off LCD backlight on SiS30xLV */
9019 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9020 SiS_DDC2Delay(SiS_Pr,0xff00);
9021 }
9022
9023 /*********************************************/
9024 /* DDC RELATED FUNCTIONS */
9025 /*********************************************/
9026
9027 static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)9028 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9029 {
9030 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9031 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9032 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9033 SiS_Pr->SiS_DDC_NData &= 0x0f;
9034 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9035 }
9036 }
9037
9038 #ifdef CONFIG_FB_SIS_300
9039 static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9040 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9041 {
9042 int i, j, num;
9043 unsigned short tempah,temp;
9044 unsigned char *mydataptr;
9045
9046 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9047 mydataptr = dataptr;
9048 num = *mydataptr++;
9049 if(!num) return mydataptr;
9050 if(i) {
9051 SiS_SetStop(SiS_Pr);
9052 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9053 }
9054 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9055 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9056 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9057 if(temp) continue; /* (ERROR: no ack) */
9058 tempah = *mydataptr++;
9059 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9060 if(temp) continue; /* (ERROR: no ack) */
9061 for(j=0; j<num; j++) {
9062 tempah = *mydataptr++;
9063 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9064 if(temp) break;
9065 }
9066 if(temp) continue;
9067 if(SiS_SetStop(SiS_Pr)) continue;
9068 return mydataptr;
9069 }
9070 return NULL;
9071 }
9072
9073 static bool
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9074 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9075 {
9076 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9077 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9078 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9079 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9080 SiS_SetupDDCN(SiS_Pr);
9081
9082 SiS_SetSwitchDDC2(SiS_Pr);
9083
9084 while(*dataptr) {
9085 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9086 if(!dataptr) return false;
9087 }
9088 return true;
9089 }
9090 #endif
9091
9092 /* The Chrontel 700x is connected to the 630/730 via
9093 * the 630/730's DDC/I2C port.
9094 *
9095 * On 630(S)T chipset, the index changed from 0x11 to
9096 * 0x0a, possibly for working around the DDC problems
9097 */
9098
9099 static bool
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)9100 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9101 {
9102 unsigned short temp, i;
9103
9104 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9105 if(i) {
9106 SiS_SetStop(SiS_Pr);
9107 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9108 }
9109 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9110 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9111 if(temp) continue; /* (ERROR: no ack) */
9112 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
9113 if(temp) continue; /* (ERROR: no ack) */
9114 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
9115 if(temp) continue; /* (ERROR: no ack) */
9116 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9117 SiS_Pr->SiS_ChrontelInit = 1;
9118 return true;
9119 }
9120 return false;
9121 }
9122
9123 /* Write to Chrontel 700x */
9124 void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9125 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9126 {
9127 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9128
9129 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9130
9131 if(!(SiS_Pr->SiS_ChrontelInit)) {
9132 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9133 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9134 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9135 SiS_SetupDDCN(SiS_Pr);
9136 }
9137
9138 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9139 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9140 SiS_Pr->SiS_DDC_Index = 0x0a;
9141 SiS_Pr->SiS_DDC_Data = 0x80;
9142 SiS_Pr->SiS_DDC_Clk = 0x40;
9143 SiS_SetupDDCN(SiS_Pr);
9144
9145 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9146 }
9147 }
9148
9149 /* Write to Chrontel 701x */
9150 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9151 void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9152 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9153 {
9154 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9155 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9156 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9157 SiS_SetupDDCN(SiS_Pr);
9158 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9159 SiS_SetChReg(SiS_Pr, reg, val, 0);
9160 }
9161
9162 static
9163 void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9164 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9165 {
9166 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9167 SiS_SetCH700x(SiS_Pr, reg, val);
9168 else
9169 SiS_SetCH701x(SiS_Pr, reg, val);
9170 }
9171
9172 static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)9173 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9174 {
9175 unsigned short tempah, temp, i;
9176
9177 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9178 if(i) {
9179 SiS_SetStop(SiS_Pr);
9180 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9181 }
9182 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9183 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9184 if(temp) continue; /* (ERROR: no ack) */
9185 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9186 if(temp) continue; /* (ERROR: no ack) */
9187 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9188 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9189 if(temp) continue; /* (ERROR: no ack) */
9190 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9191 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9192 SiS_Pr->SiS_ChrontelInit = 1;
9193 return tempah;
9194 }
9195 return 0xFFFF;
9196 }
9197
9198 /* Read from Chrontel 700x */
9199 /* Parameter is [Register no (S7-S0)] */
9200 unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9201 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9202 {
9203 unsigned short result;
9204
9205 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9206
9207 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9208
9209 if(!(SiS_Pr->SiS_ChrontelInit)) {
9210 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9211 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9212 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9213 SiS_SetupDDCN(SiS_Pr);
9214 }
9215
9216 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9217
9218 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9219 (!SiS_Pr->SiS_ChrontelInit) ) {
9220
9221 SiS_Pr->SiS_DDC_Index = 0x0a;
9222 SiS_Pr->SiS_DDC_Data = 0x80;
9223 SiS_Pr->SiS_DDC_Clk = 0x40;
9224 SiS_SetupDDCN(SiS_Pr);
9225
9226 result = SiS_GetChReg(SiS_Pr,0x80);
9227 }
9228 return result;
9229 }
9230
9231 /* Read from Chrontel 701x */
9232 /* Parameter is [Register no (S7-S0)] */
9233 unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9234 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9235 {
9236 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9237 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9238 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9239 SiS_SetupDDCN(SiS_Pr);
9240 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9241
9242 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9243
9244 return SiS_GetChReg(SiS_Pr,0);
9245 }
9246
9247 /* Read from Chrontel 70xx */
9248 /* Parameter is [Register no (S7-S0)] */
9249 static
9250 unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)9251 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9252 {
9253 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9254 return SiS_GetCH700x(SiS_Pr, tempbx);
9255 else
9256 return SiS_GetCH701x(SiS_Pr, tempbx);
9257 }
9258
9259 void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)9260 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9261 unsigned char myor, unsigned short myand)
9262 {
9263 unsigned short tempbl;
9264
9265 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9266 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9267 }
9268
9269 /* Our own DDC functions */
9270 static
9271 unsigned short
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,bool checkcr32,unsigned int VBFlags2)9272 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9273 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9274 unsigned int VBFlags2)
9275 {
9276 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9277 unsigned char flag, cr32;
9278 unsigned short temp = 0, myadaptnum = adaptnum;
9279
9280 if(adaptnum != 0) {
9281 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9282 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9283 }
9284
9285 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9286
9287 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9288
9289 SiS_Pr->SiS_DDC_SecAddr = 0;
9290 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9291 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9292 SiS_Pr->SiS_DDC_Index = 0x11;
9293 flag = 0xff;
9294
9295 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9296
9297 #if 0
9298 if(VBFlags2 & VB2_SISBRIDGE) {
9299 if(myadaptnum == 0) {
9300 if(!(cr32 & 0x20)) {
9301 myadaptnum = 2;
9302 if(!(cr32 & 0x10)) {
9303 myadaptnum = 1;
9304 if(!(cr32 & 0x08)) {
9305 myadaptnum = 0;
9306 }
9307 }
9308 }
9309 }
9310 }
9311 #endif
9312
9313 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9314
9315 if(myadaptnum != 0) {
9316 flag = 0;
9317 if(VBFlags2 & VB2_SISBRIDGE) {
9318 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9319 SiS_Pr->SiS_DDC_Index = 0x0f;
9320 }
9321 }
9322
9323 if(!(VBFlags2 & VB2_301)) {
9324 if((cr32 & 0x80) && (checkcr32)) {
9325 if(myadaptnum >= 1) {
9326 if(!(cr32 & 0x08)) {
9327 myadaptnum = 1;
9328 if(!(cr32 & 0x10)) return 0xFFFF;
9329 }
9330 }
9331 }
9332 }
9333
9334 temp = 4 - (myadaptnum * 2);
9335 if(flag) temp = 0;
9336
9337 } else { /* 315/330 series */
9338
9339 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9340
9341 if(VBFlags2 & VB2_SISBRIDGE) {
9342 if(myadaptnum == 2) {
9343 myadaptnum = 1;
9344 }
9345 }
9346
9347 if(myadaptnum == 1) {
9348 flag = 0;
9349 if(VBFlags2 & VB2_SISBRIDGE) {
9350 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9351 SiS_Pr->SiS_DDC_Index = 0x0f;
9352 }
9353 }
9354
9355 if((cr32 & 0x80) && (checkcr32)) {
9356 if(myadaptnum >= 1) {
9357 if(!(cr32 & 0x08)) {
9358 myadaptnum = 1;
9359 if(!(cr32 & 0x10)) return 0xFFFF;
9360 }
9361 }
9362 }
9363
9364 temp = myadaptnum;
9365 if(myadaptnum == 1) {
9366 temp = 0;
9367 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9368 }
9369
9370 if(flag) temp = 0;
9371 }
9372
9373 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9374 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9375
9376 SiS_SetupDDCN(SiS_Pr);
9377
9378 return 0;
9379 }
9380
9381 static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9382 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9383 {
9384 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9385 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9386 return 0xFFFF;
9387 }
9388 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9389 return 0xFFFF;
9390 }
9391 return 0;
9392 }
9393
9394 static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9395 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9396 {
9397 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9398 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9399 return 0xFFFF;
9400 }
9401 return 0;
9402 }
9403
9404 static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9405 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9406 {
9407 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9408 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9409 return 0;
9410 }
9411
9412 static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9413 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9414 {
9415 SiS_SetSCLKLow(SiS_Pr);
9416 if(yesno) {
9417 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418 SiS_Pr->SiS_DDC_Index,
9419 SiS_Pr->SiS_DDC_NData,
9420 SiS_Pr->SiS_DDC_Data);
9421 } else {
9422 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9423 SiS_Pr->SiS_DDC_Index,
9424 SiS_Pr->SiS_DDC_NData,
9425 0);
9426 }
9427 SiS_SetSCLKHigh(SiS_Pr);
9428 }
9429
9430 static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9431 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9432 {
9433 unsigned char mask, value;
9434 unsigned short temp, ret=0;
9435 bool failed = false;
9436
9437 SiS_SetSwitchDDC2(SiS_Pr);
9438 if(SiS_PrepareDDC(SiS_Pr)) {
9439 SiS_SetStop(SiS_Pr);
9440 return 0xFFFF;
9441 }
9442 mask = 0xf0;
9443 value = 0x20;
9444 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9445 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9446 SiS_SendACK(SiS_Pr, 0);
9447 if(temp == 0) {
9448 mask = 0xff;
9449 value = 0xff;
9450 } else {
9451 failed = true;
9452 ret = 0xFFFF;
9453 }
9454 }
9455 if(!failed) {
9456 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9457 SiS_SendACK(SiS_Pr, 1);
9458 temp &= mask;
9459 if(temp == value) ret = 0;
9460 else {
9461 ret = 0xFFFF;
9462 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9463 if(temp == 0x30) ret = 0;
9464 }
9465 }
9466 }
9467 SiS_SetStop(SiS_Pr);
9468 return ret;
9469 }
9470
9471 static
9472 unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9473 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9474 {
9475 unsigned short flag;
9476
9477 flag = 0x180;
9478 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9479 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9480 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9481 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9482 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9483 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9484 if(!(flag & 0x1a)) flag = 0;
9485 return flag;
9486 }
9487
9488 static
9489 unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9490 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9491 {
9492 unsigned short flag, length, i;
9493 unsigned char chksum,gotcha;
9494
9495 if(DDCdatatype > 4) return 0xFFFF;
9496
9497 flag = 0;
9498 SiS_SetSwitchDDC2(SiS_Pr);
9499 if(!(SiS_PrepareDDC(SiS_Pr))) {
9500 length = 127;
9501 if(DDCdatatype != 1) length = 255;
9502 chksum = 0;
9503 gotcha = 0;
9504 for(i=0; i<length; i++) {
9505 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9506 chksum += buffer[i];
9507 gotcha |= buffer[i];
9508 SiS_SendACK(SiS_Pr, 0);
9509 }
9510 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9511 chksum += buffer[i];
9512 SiS_SendACK(SiS_Pr, 1);
9513 if(gotcha) flag = (unsigned short)chksum;
9514 else flag = 0xFFFF;
9515 } else {
9516 flag = 0xFFFF;
9517 }
9518 SiS_SetStop(SiS_Pr);
9519 return flag;
9520 }
9521
9522 /* Our private DDC functions
9523
9524 It complies somewhat with the corresponding VESA function
9525 in arguments and return values.
9526
9527 Since this is probably called before the mode is changed,
9528 we use our pre-detected pSiS-values instead of SiS_Pr as
9529 regards chipset and video bridge type.
9530
9531 Arguments:
9532 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9533 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9534 LCDA is CRT1, but DDC is read from CRT2 port.
9535 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9536 buffer: ptr to 256 data bytes which will be filled with read data.
9537
9538 Returns 0xFFFF if error, otherwise
9539 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9540 if DDCdatatype = 0: Returns supported DDC modes
9541
9542 */
9543 unsigned short
SiS_HandleDDC(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,unsigned char * buffer,unsigned int VBFlags2)9544 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9545 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9546 unsigned int VBFlags2)
9547 {
9548 unsigned char sr1f, cr17=1;
9549 unsigned short result;
9550
9551 if(adaptnum > 2)
9552 return 0xFFFF;
9553
9554 if(DDCdatatype > 4)
9555 return 0xFFFF;
9556
9557 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9558 return 0xFFFF;
9559
9560 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9561 return 0xFFFF;
9562
9563 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9564 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9565 if(VGAEngine == SIS_300_VGA) {
9566 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9567 if(!cr17) {
9568 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9569 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9570 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9571 }
9572 }
9573 if((sr1f) || (!cr17)) {
9574 SiS_WaitRetrace1(SiS_Pr);
9575 SiS_WaitRetrace1(SiS_Pr);
9576 SiS_WaitRetrace1(SiS_Pr);
9577 SiS_WaitRetrace1(SiS_Pr);
9578 }
9579
9580 if(DDCdatatype == 0) {
9581 result = SiS_ProbeDDC(SiS_Pr);
9582 } else {
9583 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9584 if((!result) && (DDCdatatype == 1)) {
9585 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9586 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9587 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9588 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9589 (buffer[0x12] == 1)) {
9590 if(!SiS_Pr->DDCPortMixup) {
9591 if(adaptnum == 1) {
9592 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9593 } else {
9594 if(buffer[0x14] & 0x80) result = 0xFFFE;
9595 }
9596 }
9597 }
9598 }
9599 }
9600 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9601 if(VGAEngine == SIS_300_VGA) {
9602 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9603 }
9604 return result;
9605 }
9606
9607 /* Generic I2C functions for Chrontel & DDC --------- */
9608
9609 static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9610 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9611 {
9612 SiS_SetSCLKHigh(SiS_Pr);
9613 SiS_WaitRetrace1(SiS_Pr);
9614
9615 SiS_SetSCLKLow(SiS_Pr);
9616 SiS_WaitRetrace1(SiS_Pr);
9617 }
9618
9619 unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9620 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9621 {
9622 SiS_WaitRetrace1(SiS_Pr);
9623 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9624 }
9625
9626 /* Set I2C start condition */
9627 /* This is done by a SD high-to-low transition while SC is high */
9628 static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9629 SiS_SetStart(struct SiS_Private *SiS_Pr)
9630 {
9631 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9632 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9633 SiS_Pr->SiS_DDC_Index,
9634 SiS_Pr->SiS_DDC_NData,
9635 SiS_Pr->SiS_DDC_Data); /* SD->high */
9636 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9637 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9638 SiS_Pr->SiS_DDC_Index,
9639 SiS_Pr->SiS_DDC_NData,
9640 0x00); /* SD->low = start condition */
9641 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9642 return 0;
9643 }
9644
9645 /* Set I2C stop condition */
9646 /* This is done by a SD low-to-high transition while SC is high */
9647 static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9648 SiS_SetStop(struct SiS_Private *SiS_Pr)
9649 {
9650 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9651 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9652 SiS_Pr->SiS_DDC_Index,
9653 SiS_Pr->SiS_DDC_NData,
9654 0x00); /* SD->low */
9655 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9656 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9657 SiS_Pr->SiS_DDC_Index,
9658 SiS_Pr->SiS_DDC_NData,
9659 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9660 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9661 return 0;
9662 }
9663
9664 /* Write 8 bits of data */
9665 static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9666 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9667 {
9668 unsigned short i,flag,temp;
9669
9670 flag = 0x80;
9671 for(i = 0; i < 8; i++) {
9672 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9673 if(tempax & flag) {
9674 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9675 SiS_Pr->SiS_DDC_Index,
9676 SiS_Pr->SiS_DDC_NData,
9677 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9678 } else {
9679 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9680 SiS_Pr->SiS_DDC_Index,
9681 SiS_Pr->SiS_DDC_NData,
9682 0x00); /* Write bit (0) to SD */
9683 }
9684 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9685 flag >>= 1;
9686 }
9687 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9688 return temp;
9689 }
9690
9691 static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9692 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9693 {
9694 unsigned short i, temp, getdata;
9695
9696 getdata = 0;
9697 for(i = 0; i < 8; i++) {
9698 getdata <<= 1;
9699 SiS_SetSCLKLow(SiS_Pr);
9700 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9701 SiS_Pr->SiS_DDC_Index,
9702 SiS_Pr->SiS_DDC_NData,
9703 SiS_Pr->SiS_DDC_Data);
9704 SiS_SetSCLKHigh(SiS_Pr);
9705 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9706 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9707 }
9708 return getdata;
9709 }
9710
9711 static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9712 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9713 {
9714 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9715 SiS_Pr->SiS_DDC_Index,
9716 SiS_Pr->SiS_DDC_NClk,
9717 0x00); /* SetSCLKLow() */
9718 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9719 return 0;
9720 }
9721
9722 static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9723 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9724 {
9725 unsigned short temp, watchdog=1000;
9726
9727 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9728 SiS_Pr->SiS_DDC_Index,
9729 SiS_Pr->SiS_DDC_NClk,
9730 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9731 do {
9732 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9733 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9734 if (!watchdog) {
9735 return 0xFFFF;
9736 }
9737 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9738 return 0;
9739 }
9740
9741 /* Check I2C acknowledge */
9742 /* Returns 0 if ack ok, non-0 if ack not ok */
9743 static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9744 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9745 {
9746 unsigned short tempah;
9747
9748 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9749 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9750 SiS_Pr->SiS_DDC_Index,
9751 SiS_Pr->SiS_DDC_NData,
9752 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9753 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9754 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9755 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9756 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9757 return 0;
9758 }
9759
9760 /* End of I2C functions ----------------------- */
9761
9762
9763 /* =============== SiS 315/330 O.E.M. ================= */
9764
9765 #ifdef CONFIG_FB_SIS_315
9766
9767 static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9768 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9769 {
9770 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9771 unsigned short romptr;
9772
9773 if(SiS_Pr->ChipType < SIS_330) {
9774 romptr = SISGETROMW(0x128);
9775 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9776 romptr = SISGETROMW(0x12a);
9777 } else {
9778 romptr = SISGETROMW(0x1a8);
9779 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9780 romptr = SISGETROMW(0x1aa);
9781 }
9782 return romptr;
9783 }
9784
9785 static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9786 GetLCDromptr(struct SiS_Private *SiS_Pr)
9787 {
9788 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9789 unsigned short romptr;
9790
9791 if(SiS_Pr->ChipType < SIS_330) {
9792 romptr = SISGETROMW(0x120);
9793 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9794 romptr = SISGETROMW(0x122);
9795 } else {
9796 romptr = SISGETROMW(0x1a0);
9797 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9798 romptr = SISGETROMW(0x1a2);
9799 }
9800 return romptr;
9801 }
9802
9803 static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9804 GetTVromptr(struct SiS_Private *SiS_Pr)
9805 {
9806 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9807 unsigned short romptr;
9808
9809 if(SiS_Pr->ChipType < SIS_330) {
9810 romptr = SISGETROMW(0x114);
9811 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9812 romptr = SISGETROMW(0x11a);
9813 } else {
9814 romptr = SISGETROMW(0x194);
9815 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9816 romptr = SISGETROMW(0x19a);
9817 }
9818 return romptr;
9819 }
9820
9821 static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9822 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9823 {
9824 unsigned short index;
9825
9826 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9827 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9828 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9829 index >>= 4;
9830 index *= 3;
9831 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9832 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9833 return index;
9834 }
9835 }
9836 }
9837
9838 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9839 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9840 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9841 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9843 } else {
9844 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9845 }
9846 index--;
9847 index *= 3;
9848 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9849 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9850 return index;
9851 }
9852
9853 static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9854 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9855 {
9856 unsigned short index;
9857
9858 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9859 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9860 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9861 return index;
9862 }
9863
9864 static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9865 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9866 {
9867 unsigned short index;
9868
9869 index = 0;
9870 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9871 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9872
9873 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9874
9875 index <<= 1;
9876
9877 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9878 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9879 index++;
9880 }
9881
9882 return index;
9883 }
9884
9885 static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9886 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9887 {
9888 unsigned short index = 0, temp = 0;
9889
9890 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9891 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9892 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9893 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9894 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9895 index = 4;
9896 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9897 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9898 }
9899
9900 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9901 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9902 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9903 index += addme;
9904 temp++;
9905 }
9906 temp += 0x0100;
9907 }
9908 return (unsigned int)(index | (temp << 16));
9909 }
9910
9911 static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9912 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9913 {
9914 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9915 }
9916
9917 #if 0
9918 static unsigned int
9919 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9920 {
9921 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9922 }
9923 #endif
9924
9925 static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9926 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9927 {
9928 int index = 0;
9929
9930 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9931 if(SiS_Pr->SiS_ROMNew) {
9932 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9933 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9934 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9935 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9936 } else {
9937 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9938 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9939 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9940 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9941 }
9942
9943 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9944
9945 return index;
9946 }
9947
9948 static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9949 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9950 {
9951 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9952 unsigned short delay=0,index,myindex,temp,romptr=0;
9953 bool dochiptest = true;
9954
9955 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9956 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9957 } else {
9958 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9959 }
9960
9961 /* Find delay (from ROM, internal tables, PCI subsystem) */
9962
9963 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9964
9965 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9966 romptr = GetRAMDACromptr(SiS_Pr);
9967 }
9968 if(romptr) delay = ROMAddr[romptr];
9969 else {
9970 delay = 0x04;
9971 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9972 if(IS_SIS650) {
9973 delay = 0x0a;
9974 } else if(IS_SIS740) {
9975 delay = 0x00;
9976 } else {
9977 delay = 0x0c;
9978 }
9979 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9980 delay = 0x00;
9981 }
9982 }
9983
9984 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9985
9986 bool gotitfrompci = false;
9987
9988 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9989
9990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9991 if(SiS_Pr->PDC != -1) {
9992 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9994 return;
9995 }
9996 } else {
9997 if(SiS_Pr->PDCA != -1) {
9998 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10000 return;
10001 }
10002 }
10003
10004 /* Custom Panel? */
10005
10006 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10007 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10008 delay = 0x00;
10009 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10010 delay = 0x20;
10011 }
10012 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10013 } else {
10014 delay = 0x0c;
10015 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10016 delay = 0x03;
10017 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10018 delay = 0x00;
10019 }
10020 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10021 if(IS_SIS740) delay = 0x01;
10022 else delay = 0x03;
10023 }
10024 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10025 }
10026 return;
10027 }
10028
10029 /* This is a piece of typical SiS crap: They code the OEM LCD
10030 * delay into the code, at no defined place in the BIOS.
10031 * We now have to start doing a PCI subsystem check here.
10032 */
10033
10034 switch(SiS_Pr->SiS_CustomT) {
10035 case CUT_COMPAQ1280:
10036 case CUT_COMPAQ12802:
10037 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10038 gotitfrompci = true;
10039 dochiptest = false;
10040 delay = 0x03;
10041 }
10042 break;
10043 case CUT_CLEVO1400:
10044 case CUT_CLEVO14002:
10045 gotitfrompci = true;
10046 dochiptest = false;
10047 delay = 0x02;
10048 break;
10049 case CUT_CLEVO1024:
10050 case CUT_CLEVO10242:
10051 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10052 gotitfrompci = true;
10053 dochiptest = false;
10054 delay = 0x33;
10055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10056 delay &= 0x0f;
10057 }
10058 break;
10059 }
10060
10061 /* Could we find it through the PCI ID? If no, use ROM or table */
10062
10063 if(!gotitfrompci) {
10064
10065 index = GetLCDPtrIndexBIOS(SiS_Pr);
10066 myindex = GetLCDPtrIndex(SiS_Pr);
10067
10068 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10069
10070 if(SiS_IsNotM650orLater(SiS_Pr)) {
10071
10072 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10073 /* Always use the second pointer on 650; some BIOSes */
10074 /* still carry old 301 data at the first location */
10075 /* romptr = SISGETROMW(0x120); */
10076 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10077 romptr = SISGETROMW(0x122);
10078 if(!romptr) return;
10079 delay = ROMAddr[(romptr + index)];
10080 } else {
10081 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10082 }
10083
10084 } else {
10085
10086 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10087 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10088 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10089
10090 }
10091
10092 } else if(SiS_Pr->SiS_UseROM &&
10093 (!(SiS_Pr->SiS_ROMNew)) &&
10094 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10095 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10096 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
10097 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
10098 ((romptr = GetLCDromptr(SiS_Pr)))) {
10099
10100 /* Data for 1280x1024 wrong in 301B BIOS */
10101 /* Data for 1600x1200 wrong in 301C BIOS */
10102 delay = ROMAddr[(romptr + index)];
10103
10104 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10105
10106 if(IS_SIS740) delay = 0x03;
10107 else delay = 0x00;
10108
10109 } else {
10110
10111 delay = SiS310_LCDDelayCompensation_301[myindex];
10112 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10113 if(IS_SIS740) delay = 0x01;
10114 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10115 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10116 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10117 if(IS_SIS740) delay = 0x01; /* ? */
10118 else delay = 0x03;
10119 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10120 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10121 if(IS_SIS740) delay = 0x01;
10122 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10123 }
10124
10125 }
10126
10127 } /* got it from PCI */
10128
10129 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10131 dochiptest = false;
10132 }
10133
10134 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10135
10136 index = GetTVPtrIndex(SiS_Pr);
10137
10138 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10139
10140 if(SiS_IsNotM650orLater(SiS_Pr)) {
10141
10142 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10143 /* Always use the second pointer on 650; some BIOSes */
10144 /* still carry old 301 data at the first location */
10145 /* romptr = SISGETROMW(0x114); */
10146 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10147 romptr = SISGETROMW(0x11a);
10148 if(!romptr) return;
10149 delay = ROMAddr[romptr + index];
10150
10151 } else {
10152
10153 delay = SiS310_TVDelayCompensation_301B[index];
10154
10155 }
10156
10157 } else {
10158
10159 switch(SiS_Pr->SiS_CustomT) {
10160 case CUT_COMPAQ1280:
10161 case CUT_COMPAQ12802:
10162 case CUT_CLEVO1400:
10163 case CUT_CLEVO14002:
10164 delay = 0x02;
10165 dochiptest = false;
10166 break;
10167 case CUT_CLEVO1024:
10168 case CUT_CLEVO10242:
10169 delay = 0x03;
10170 dochiptest = false;
10171 break;
10172 default:
10173 delay = SiS310_TVDelayCompensation_651301LV[index];
10174 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10175 delay = SiS310_TVDelayCompensation_651302LV[index];
10176 }
10177 }
10178 }
10179
10180 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10181
10182 romptr = GetTVromptr(SiS_Pr);
10183 if(!romptr) return;
10184 delay = ROMAddr[romptr + index];
10185
10186 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10187
10188 delay = SiS310_TVDelayCompensation_LVDS[index];
10189
10190 } else {
10191
10192 delay = SiS310_TVDelayCompensation_301[index];
10193 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10194 if(IS_SIS740) {
10195 delay = SiS310_TVDelayCompensation_740301B[index];
10196 /* LV: use 301 data? BIOS bug? */
10197 } else {
10198 delay = SiS310_TVDelayCompensation_301B[index];
10199 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10200 }
10201 }
10202
10203 }
10204
10205 if(SiS_LCDAEnabled(SiS_Pr)) {
10206 delay &= 0x0f;
10207 dochiptest = false;
10208 }
10209
10210 } else return;
10211
10212 /* Write delay */
10213
10214 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10215
10216 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10217
10218 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10219 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10220 delay &= 0x0f;
10221 delay |= 0xb0;
10222 } else if(temp == 6) {
10223 delay &= 0x0f;
10224 delay |= 0xc0;
10225 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10226 delay = 0x35;
10227 }
10228 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10229
10230 } else {
10231
10232 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10233
10234 }
10235
10236 } else { /* LVDS */
10237
10238 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10239 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10240 } else {
10241 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10242 delay <<= 4;
10243 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10244 } else {
10245 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10246 }
10247 }
10248
10249 }
10250
10251 }
10252
10253 static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10254 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10255 {
10256 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10257 unsigned short index,temp,temp1,romptr=0;
10258
10259 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10260
10261 if(ModeNo<=0x13)
10262 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10263 else
10264 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10265
10266 temp = GetTVPtrIndex(SiS_Pr);
10267 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10268 temp1 = temp;
10269
10270 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10271 if(SiS_Pr->ChipType >= SIS_661) {
10272 temp1 = GetOEMTVPtr661(SiS_Pr);
10273 temp1 >>= 1;
10274 romptr = SISGETROMW(0x260);
10275 if(SiS_Pr->ChipType >= SIS_760) {
10276 romptr = SISGETROMW(0x360);
10277 }
10278 } else if(SiS_Pr->ChipType >= SIS_330) {
10279 romptr = SISGETROMW(0x192);
10280 } else {
10281 romptr = SISGETROMW(0x112);
10282 }
10283 }
10284
10285 if(romptr) {
10286 temp1 <<= 1;
10287 temp = ROMAddr[romptr + temp1 + index];
10288 } else {
10289 temp = SiS310_TVAntiFlick1[temp][index];
10290 }
10291 temp <<= 4;
10292
10293 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10294 }
10295
10296 static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10297 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10298 {
10299 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10300 unsigned short index,temp,temp1,romptr=0;
10301
10302 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10303
10304 if(ModeNo <= 0x13)
10305 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10306 else
10307 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10308
10309 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10310 if(SiS_Pr->ChipType >= SIS_661) {
10311 romptr = SISGETROMW(0x26c);
10312 if(SiS_Pr->ChipType >= SIS_760) {
10313 romptr = SISGETROMW(0x36c);
10314 }
10315 temp1 = GetOEMTVPtr661(SiS_Pr);
10316 temp1 >>= 1;
10317 } else if(SiS_Pr->ChipType >= SIS_330) {
10318 romptr = SISGETROMW(0x1a4);
10319 } else {
10320 romptr = SISGETROMW(0x124);
10321 }
10322 }
10323
10324 if(romptr) {
10325 temp1 <<= 1;
10326 temp = ROMAddr[romptr + temp1 + index];
10327 } else {
10328 temp = SiS310_TVEdge1[temp][index];
10329 }
10330 temp <<= 5;
10331 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10332 }
10333
10334 static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10335 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10336 {
10337 unsigned short index, temp, i, j;
10338
10339 if(ModeNo <= 0x13) {
10340 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10341 } else {
10342 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10343 }
10344
10345 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10346
10347 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10348 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10349 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10350 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10351
10352 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10353 for(i=0x35, j=0; i<=0x38; i++, j++) {
10354 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10355 }
10356 for(i=0x48; i<=0x4A; i++, j++) {
10357 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10358 }
10359 } else {
10360 for(i=0x35, j=0; i<=0x38; i++, j++) {
10361 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10362 }
10363 }
10364 }
10365
10366 static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10367 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10368 {
10369 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10370 unsigned short index,temp,i,j,resinfo,romptr=0;
10371 unsigned int lindex;
10372
10373 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10374
10375 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10376 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10377
10378 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10379 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10380 lindex <<= 2;
10381 for(j=0, i=0x31; i<=0x34; i++, j++) {
10382 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10383 }
10384 return;
10385 }
10386
10387 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10388 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10389
10390 if(ModeNo<=0x13) {
10391 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10392 } else {
10393 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10394 }
10395
10396 temp = GetTVPtrIndex(SiS_Pr);
10397 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10398 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10399 */
10400 if(SiS_Pr->SiS_UseROM) {
10401 romptr = SISGETROMW(0x116);
10402 if(SiS_Pr->ChipType >= SIS_330) {
10403 romptr = SISGETROMW(0x196);
10404 }
10405 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10406 romptr = SISGETROMW(0x11c);
10407 if(SiS_Pr->ChipType >= SIS_330) {
10408 romptr = SISGETROMW(0x19c);
10409 }
10410 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10411 romptr = SISGETROMW(0x116);
10412 if(SiS_Pr->ChipType >= SIS_330) {
10413 romptr = SISGETROMW(0x196);
10414 }
10415 }
10416 }
10417 }
10418 if(romptr) {
10419 romptr += (temp << 2);
10420 for(j=0, i=0x31; i<=0x34; i++, j++) {
10421 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10422 }
10423 } else {
10424 index = temp % 2;
10425 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10426 for(j=0, i=0x31; i<=0x34; i++, j++) {
10427 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10428 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10429 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10430 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10431 else
10432 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10433 }
10434 }
10435
10436 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10437 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10438 if((resinfo == SIS_RI_640x480) ||
10439 (resinfo == SIS_RI_800x600)) {
10440 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10442 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10444 } else if(resinfo == SIS_RI_1024x768) {
10445 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10447 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10449 }
10450 }
10451 }
10452 }
10453
10454 static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10455 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10456 unsigned short ModeIdIndex, unsigned short RTI)
10457 {
10458 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10459 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10460
10461 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10462 return;
10463
10464 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10465 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10466
10467 if(SiS_Pr->SiS_ROMNew) {
10468 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10469 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10470 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10471 index = 25;
10472 if(SiS_Pr->UseCustomMode) {
10473 index = SiS_Pr->CSRClock;
10474 } else if(ModeNo > 0x13) {
10475 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10476 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10477 }
10478 if(index < 25) index = 25;
10479 index = ((index / 25) - 1) << 1;
10480 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10481 index++;
10482 }
10483 romptr = SISGETROMW(0x104);
10484 delay = ROMAddr[romptr + index];
10485 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10486 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10488 } else {
10489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10491 }
10492 return;
10493 }
10494 }
10495
10496 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10497
10498 if(SiS_Pr->UseCustomMode) delay = 0x04;
10499 else if(ModeNo <= 0x13) delay = 0x04;
10500 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10501 delay |= (delay << 8);
10502
10503 if(SiS_Pr->ChipType >= XGI_20) {
10504
10505 delay = 0x0606;
10506 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10507
10508 delay = 0x0404;
10509 if(SiS_Pr->SiS_XGIROM) {
10510 index = GetTVPtrIndex(SiS_Pr);
10511 if((romptr = SISGETROMW(0x35e))) {
10512 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10513 delay |= (delay << 8);
10514 }
10515 }
10516
10517 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10518 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10519 delay -= 0x0404;
10520 }
10521 }
10522 }
10523
10524 } else if(SiS_Pr->ChipType >= SIS_340) {
10525
10526 delay = 0x0606;
10527 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10528 delay = 0x0404;
10529 }
10530 /* TODO (eventually) */
10531
10532 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10533
10534 /* 3. TV */
10535
10536 index = GetOEMTVPtr661(SiS_Pr);
10537 if(SiS_Pr->SiS_ROMNew) {
10538 romptr = SISGETROMW(0x106);
10539 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10540 delay = ROMAddr[romptr + index];
10541 } else {
10542 delay = 0x04;
10543 if(index > 3) delay = 0;
10544 }
10545
10546 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10547
10548 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10549
10550 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10551 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10552
10553 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10554
10555 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10556 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10557 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10558
10559 } else {
10560
10561 /* TMDS: Set our own, since BIOS has no idea */
10562 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10563 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10564 switch(SiS_Pr->SiS_LCDResInfo) {
10565 case Panel_1024x768: delay = 0x0008; break;
10566 case Panel_1280x720: delay = 0x0004; break;
10567 case Panel_1280x768:
10568 case Panel_1280x768_2:delay = 0x0004; break;
10569 case Panel_1280x800:
10570 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10571 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10572 case Panel_1280x1024: delay = 0x1e04; break;
10573 case Panel_1400x1050: delay = 0x0004; break;
10574 case Panel_1600x1200: delay = 0x0400; break;
10575 case Panel_1680x1050: delay = 0x0e04; break;
10576 default:
10577 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10578 delay = 0x0008;
10579 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10580 delay = 0x1e04;
10581 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10582 delay = 0x0004;
10583 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10584 delay = 0x0400;
10585 } else
10586 delay = 0x0e04;
10587 break;
10588 }
10589 }
10590
10591 /* Override by detected or user-set values */
10592 /* (but only if, for some reason, we can't read value from BIOS) */
10593 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10594 delay = SiS_Pr->PDC & 0x1f;
10595 }
10596 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10597 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10598 }
10599
10600 }
10601
10602 }
10603
10604 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10605 delay >>= 8;
10606 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10607 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10608 } else {
10609 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10611 }
10612 }
10613
10614 static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10615 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10616 {
10617 unsigned short infoflag;
10618 unsigned char temp;
10619
10620 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10621
10622 if(ModeNo <= 0x13) {
10623 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10624 } else if(SiS_Pr->UseCustomMode) {
10625 infoflag = SiS_Pr->CInfoFlag;
10626 } else {
10627 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10628 }
10629
10630 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10631 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10632 }
10633
10634 infoflag &= 0xc0;
10635
10636 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10637 temp = (infoflag >> 6) | 0x0c;
10638 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10639 temp ^= 0x04;
10640 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10641 }
10642 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10643 } else {
10644 temp = 0x30;
10645 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10646 temp |= infoflag;
10647 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10648 temp = 0;
10649 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10650 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10651 }
10652 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10653 }
10654
10655 }
10656 }
10657
10658 static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10659 SetPanelParms661(struct SiS_Private *SiS_Pr)
10660 {
10661 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10662 unsigned short romptr, temp1, temp2;
10663
10664 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10665 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10666 }
10667
10668 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10669 if(SiS_Pr->LVDSHL != -1) {
10670 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10671 }
10672 }
10673
10674 if(SiS_Pr->SiS_ROMNew) {
10675
10676 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10677 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10678 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10679 temp2 = 0xfc;
10680 if(SiS_Pr->LVDSHL != -1) {
10681 temp1 &= 0xfc;
10682 temp2 = 0xf3;
10683 }
10684 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10685 }
10686 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10687 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10688 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10689 }
10690 }
10691
10692 }
10693 }
10694
10695 static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10696 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10697 {
10698 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10699 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10700 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10701 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10702 SetPanelParms661(SiS_Pr);
10703 }
10704 } else {
10705 SetDelayComp(SiS_Pr,ModeNo);
10706 }
10707
10708 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10709 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10710 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10711 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10712 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10713 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10714 }
10715 }
10716 }
10717
10718 static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10719 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10720 unsigned short ModeIdIndex, unsigned short RRTI)
10721 {
10722 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10723
10724 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10725
10726 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10727 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10728 SetPanelParms661(SiS_Pr);
10729 }
10730
10731 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10732 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10733 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10734 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10735 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10736 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10737 }
10738 }
10739 }
10740 }
10741
10742 /* FinalizeLCD
10743 * This finalizes some CRT2 registers for the very panel used.
10744 * If we have a backup if these registers, we use it; otherwise
10745 * we set the register according to most BIOSes. However, this
10746 * function looks quite different in every BIOS, so you better
10747 * pray that we have a backup...
10748 */
10749 static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10750 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10751 {
10752 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10753 unsigned short resinfo,modeflag;
10754
10755 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10756 if(SiS_Pr->SiS_ROMNew) return;
10757
10758 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10759 if(SiS_Pr->LVDSHL != -1) {
10760 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10761 }
10762 }
10763
10764 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10765 if(SiS_Pr->UseCustomMode) return;
10766
10767 switch(SiS_Pr->SiS_CustomT) {
10768 case CUT_COMPAQ1280:
10769 case CUT_COMPAQ12802:
10770 case CUT_CLEVO1400:
10771 case CUT_CLEVO14002:
10772 return;
10773 }
10774
10775 if(ModeNo <= 0x13) {
10776 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10777 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10778 } else {
10779 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10780 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10781 }
10782
10783 if(IS_SIS650) {
10784 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10785 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10786 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10787 } else {
10788 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10789 }
10790 }
10791 }
10792
10793 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10794 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10795 /* Maybe all panels? */
10796 if(SiS_Pr->LVDSHL == -1) {
10797 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10798 }
10799 return;
10800 }
10801 }
10802
10803 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10804 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10805 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10806 if(SiS_Pr->LVDSHL == -1) {
10807 /* Maybe all panels? */
10808 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10809 }
10810 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10811 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10812 if(tempch == 3) {
10813 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10817 }
10818 }
10819 return;
10820 }
10821 }
10822 }
10823
10824 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10825 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10826 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10827 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10828 #ifdef SET_EMI
10829 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10830 #endif
10831 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10832 }
10833 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10834 if(SiS_Pr->LVDSHL == -1) {
10835 /* Maybe ACER only? */
10836 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10837 }
10838 }
10839 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10840 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10841 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10842 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10843 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10844 if(tempch == 0x03) {
10845 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10849 }
10850 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10851 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10853 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10861 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10863 if(ModeNo <= 0x13) {
10864 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10865 if((resinfo == 0) || (resinfo == 2)) return;
10866 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10867 if((resinfo == 1) || (resinfo == 3)) return;
10868 }
10869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10870 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10871 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10872 #if 0
10873 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10874 tempbx--;
10875 temp = tempbx & 0xff;
10876 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10877 temp = (tempbx >> 8) & 0x03;
10878 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10879 #endif
10880 }
10881 } else if(ModeNo <= 0x13) {
10882 if(ModeNo <= 1) {
10883 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10887 }
10888 if(!(modeflag & HalfDCLK)) {
10889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10895 if(ModeNo == 0x12) {
10896 switch(tempch) {
10897 case 0:
10898 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10899 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10904 break;
10905 case 2:
10906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10908 break;
10909 case 3:
10910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10911 break;
10912 }
10913 }
10914 }
10915 }
10916 }
10917 } else {
10918 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10919 tempcl &= 0x0f;
10920 tempbh &= 0x70;
10921 tempbh >>= 4;
10922 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10923 tempbx = (tempbh << 8) | tempbl;
10924 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10925 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10926 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10927 tempbx = 770;
10928 } else {
10929 if(tempbx > 770) tempbx = 770;
10930 if(SiS_Pr->SiS_VGAVDE < 600) {
10931 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10932 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10933 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10934 tempbx -= tempax;
10935 }
10936 }
10937 } else return;
10938 }
10939 temp = tempbx & 0xff;
10940 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10941 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10942 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10943 }
10944 }
10945 }
10946
10947 #endif
10948
10949 /* ================= SiS 300 O.E.M. ================== */
10950
10951 #ifdef CONFIG_FB_SIS_300
10952
10953 static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10954 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10955 unsigned short RefTabIndex)
10956 {
10957 unsigned short crt2crtc=0, modeflag, myindex=0;
10958 unsigned char temp;
10959 int i;
10960
10961 if(ModeNo <= 0x13) {
10962 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10963 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10964 } else {
10965 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10966 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10967 }
10968
10969 crt2crtc &= 0x3f;
10970
10971 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10972 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10973 }
10974
10975 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10976 if(modeflag & HalfDCLK) myindex = 1;
10977
10978 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10979 for(i=0; i<7; i++) {
10980 if(barco_p1[myindex][crt2crtc][i][0]) {
10981 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10982 barco_p1[myindex][crt2crtc][i][0],
10983 barco_p1[myindex][crt2crtc][i][2],
10984 barco_p1[myindex][crt2crtc][i][1]);
10985 }
10986 }
10987 }
10988 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10989 if(temp & 0x80) {
10990 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10991 temp++;
10992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10993 }
10994 }
10995 }
10996
10997 static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10998 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10999 {
11000 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11001 unsigned short tempbx=0,romptr=0;
11002 static const unsigned char customtable300[] = {
11003 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11005 };
11006 static const unsigned char customtable630[] = {
11007 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11009 };
11010
11011 if(SiS_Pr->ChipType == SIS_300) {
11012
11013 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11014 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11015 tempbx -= 2;
11016 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11017 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11018 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11019 }
11020 if(SiS_Pr->SiS_UseROM) {
11021 if(ROMAddr[0x235] & 0x80) {
11022 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11023 if(Flag) {
11024 romptr = SISGETROMW(0x255);
11025 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11026 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11027 if(tempbx == 0xFF) return 0xFFFF;
11028 }
11029 tempbx <<= 1;
11030 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11031 }
11032 }
11033
11034 } else {
11035
11036 if(Flag) {
11037 if(SiS_Pr->SiS_UseROM) {
11038 romptr = SISGETROMW(0x255);
11039 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11040 else tempbx = 0xff;
11041 } else {
11042 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11043 }
11044 if(tempbx == 0xFF) return 0xFFFF;
11045 tempbx <<= 2;
11046 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11047 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11048 return tempbx;
11049 }
11050 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11051 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11052 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11053
11054 }
11055
11056 return tempbx;
11057 }
11058
11059 static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11060 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11061 {
11062 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11063 unsigned short index,temp,romptr=0;
11064
11065 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11066
11067 if(SiS_Pr->SiS_UseROM) {
11068 if(!(ROMAddr[0x237] & 0x01)) return;
11069 if(!(ROMAddr[0x237] & 0x02)) return;
11070 romptr = SISGETROMW(0x24b);
11071 }
11072
11073 /* The Panel Compensation Delay should be set according to tables
11074 * here. Unfortunately, various BIOS versions don't care about
11075 * a uniform way using eg. ROM byte 0x220, but use different
11076 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11077 * Thus we don't set this if the user selected a custom pdc or if
11078 * we otherwise detected a valid pdc.
11079 */
11080 if(SiS_Pr->PDC != -1) return;
11081
11082 temp = GetOEMLCDPtr(SiS_Pr, 0);
11083
11084 if(SiS_Pr->UseCustomMode)
11085 index = 0;
11086 else
11087 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11088
11089 if(SiS_Pr->ChipType != SIS_300) {
11090 if(romptr) {
11091 romptr += (temp * 2);
11092 romptr = SISGETROMW(romptr);
11093 romptr += index;
11094 temp = ROMAddr[romptr];
11095 } else {
11096 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11097 temp = SiS300_OEMLCDDelay2[temp][index];
11098 } else {
11099 temp = SiS300_OEMLCDDelay3[temp][index];
11100 }
11101 }
11102 } else {
11103 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11104 if(romptr) {
11105 romptr += (temp * 2);
11106 romptr = SISGETROMW(romptr);
11107 romptr += index;
11108 temp = ROMAddr[romptr];
11109 } else {
11110 temp = SiS300_OEMLCDDelay5[temp][index];
11111 }
11112 } else {
11113 if(SiS_Pr->SiS_UseROM) {
11114 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11115 if(romptr) {
11116 romptr += (temp * 2);
11117 romptr = SISGETROMW(romptr);
11118 romptr += index;
11119 temp = ROMAddr[romptr];
11120 } else {
11121 temp = SiS300_OEMLCDDelay4[temp][index];
11122 }
11123 } else {
11124 temp = SiS300_OEMLCDDelay4[temp][index];
11125 }
11126 }
11127 }
11128 temp &= 0x3c;
11129 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11130 }
11131
11132 static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11133 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11134 {
11135 #if 0 /* Unfinished; Data table missing */
11136 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11137 unsigned short index,temp;
11138
11139 if((SiS_Pr->SiS_UseROM) {
11140 if(!(ROMAddr[0x237] & 0x01)) return;
11141 if(!(ROMAddr[0x237] & 0x04)) return;
11142 /* No rom pointer in BIOS header! */
11143 }
11144
11145 temp = GetOEMLCDPtr(SiS_Pr, 1);
11146 if(temp == 0xFFFF) return;
11147
11148 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11149 for(i=0x14, j=0; i<=0x17; i++, j++) {
11150 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11151 }
11152 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11153
11154 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11155 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11156 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11157 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11158 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11159 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11160 }
11161 #endif
11162 }
11163
11164 static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)11165 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11166 {
11167 unsigned short index;
11168
11169 index = 0;
11170 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11171 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11172 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11173 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11174 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11175 } else {
11176 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11177 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11178 }
11179 return index;
11180 }
11181
11182 static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11183 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11184 {
11185 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11186 unsigned short index,temp,romptr=0;
11187
11188 if(SiS_Pr->SiS_UseROM) {
11189 if(!(ROMAddr[0x238] & 0x01)) return;
11190 if(!(ROMAddr[0x238] & 0x02)) return;
11191 romptr = SISGETROMW(0x241);
11192 }
11193
11194 temp = GetOEMTVPtr(SiS_Pr);
11195
11196 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11197
11198 if(romptr) {
11199 romptr += (temp * 2);
11200 romptr = SISGETROMW(romptr);
11201 romptr += index;
11202 temp = ROMAddr[romptr];
11203 } else {
11204 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11205 temp = SiS300_OEMTVDelay301[temp][index];
11206 } else {
11207 temp = SiS300_OEMTVDelayLVDS[temp][index];
11208 }
11209 }
11210 temp &= 0x3c;
11211 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11212 }
11213
11214 static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11215 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11216 {
11217 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11218 unsigned short index,temp,romptr=0;
11219
11220 if(SiS_Pr->SiS_UseROM) {
11221 if(!(ROMAddr[0x238] & 0x01)) return;
11222 if(!(ROMAddr[0x238] & 0x04)) return;
11223 romptr = SISGETROMW(0x243);
11224 }
11225
11226 temp = GetOEMTVPtr(SiS_Pr);
11227
11228 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11229
11230 if(romptr) {
11231 romptr += (temp * 2);
11232 romptr = SISGETROMW(romptr);
11233 romptr += index;
11234 temp = ROMAddr[romptr];
11235 } else {
11236 temp = SiS300_OEMTVFlicker[temp][index];
11237 }
11238 temp &= 0x70;
11239 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11240 }
11241
11242 static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11243 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11244 {
11245 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11246 unsigned short index,i,j,temp,romptr=0;
11247
11248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11249
11250 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11251
11252 if(SiS_Pr->SiS_UseROM) {
11253 if(!(ROMAddr[0x238] & 0x01)) return;
11254 if(!(ROMAddr[0x238] & 0x08)) return;
11255 romptr = SISGETROMW(0x245);
11256 }
11257
11258 temp = GetOEMTVPtr(SiS_Pr);
11259
11260 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11261
11262 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11263 for(i=0x31, j=0; i<=0x34; i++, j++) {
11264 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11265 }
11266 } else {
11267 if(romptr) {
11268 romptr += (temp * 2);
11269 romptr = SISGETROMW(romptr);
11270 romptr += (index * 4);
11271 for(i=0x31, j=0; i<=0x34; i++, j++) {
11272 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11273 }
11274 } else {
11275 for(i=0x31, j=0; i<=0x34; i++, j++) {
11276 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11277 }
11278 }
11279 }
11280 }
11281
11282 static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11283 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11284 {
11285 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11286 unsigned short index,temp,i,j,romptr=0;
11287
11288 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11289
11290 if(SiS_Pr->SiS_UseROM) {
11291 if(!(ROMAddr[0x238] & 0x01)) return;
11292 if(!(ROMAddr[0x238] & 0x10)) return;
11293 romptr = SISGETROMW(0x247);
11294 }
11295
11296 temp = GetOEMTVPtr(SiS_Pr);
11297
11298 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11299 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11300 /* NTSCJ uses NTSC filters */
11301
11302 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11303
11304 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11305 for(i=0x35, j=0; i<=0x38; i++, j++) {
11306 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11307 }
11308 for(i=0x48; i<=0x4A; i++, j++) {
11309 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11310 }
11311 } else {
11312 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11313 romptr += (temp * 2);
11314 romptr = SISGETROMW(romptr);
11315 romptr += (index * 4);
11316 for(i=0x35, j=0; i<=0x38; i++, j++) {
11317 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11318 }
11319 } else {
11320 for(i=0x35, j=0; i<=0x38; i++, j++) {
11321 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11322 }
11323 }
11324 }
11325 }
11326
11327 static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11328 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11329 {
11330 unsigned short ModeIdIndex;
11331 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11332
11333 if(*ModeNo <= 5) *ModeNo |= 1;
11334
11335 for(ModeIdIndex=0; ; ModeIdIndex++) {
11336 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11337 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11338 }
11339
11340 if(*ModeNo != 0x07) {
11341 if(*ModeNo > 0x03) return ModeIdIndex;
11342 if(VGAINFO & 0x80) return ModeIdIndex;
11343 ModeIdIndex++;
11344 }
11345
11346 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11347 /* else 350 lines */
11348 return ModeIdIndex;
11349 }
11350
11351 static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11352 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11353 unsigned short RefTableIndex)
11354 {
11355 unsigned short OEMModeIdIndex = 0;
11356
11357 if(!SiS_Pr->UseCustomMode) {
11358 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11359 if(!(OEMModeIdIndex)) return;
11360 }
11361
11362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11363 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11364 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11365 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11366 }
11367 }
11368 if(SiS_Pr->UseCustomMode) return;
11369 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11370 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11371 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11372 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11373 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11374 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11375 }
11376 }
11377 }
11378 #endif
11379
11380