Linux 4.18.10
[linux/fpc-iii.git] / drivers / video / fbdev / sis / init301.c
blob27a2b72e50e84b45e5ba1b292daf4bd386442143
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)
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
12 * If distributed as part of the Linux kernel, the following license terms
13 * apply:
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
29 * Otherwise, the following license terms apply:
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.
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56 * Used by permission.
60 #if 1
61 #define SET_EMI /* 302LV/ELV: Set EMI values */
62 #endif
64 #if 1
65 #define SET_PWD /* 301/302LV: Set PWD */
66 #endif
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) */
72 #include "init301.h"
74 #ifdef CONFIG_FB_SIS_300
75 #include "oem300.h"
76 #endif
78 #ifdef CONFIG_FB_SIS_315
79 #include "oem310.h"
80 #endif
82 #define SiS_I2CDELAY 1000
83 #define SiS_I2CDELAYSHORT 150
85 static const unsigned char SiS_YPbPrTable[3][64] = {
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
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
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
130 static const unsigned char SiS_TVPhase[] =
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 */
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
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
174 /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
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
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
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
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
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
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,
248 #ifdef CONFIG_FB_SIS_315
249 /* 661 et al LCD data structure (2.03.00) */
250 static const unsigned char SiS_LCDStruct661[] = {
251 /* 1024x768 */
252 /* type|CR37| HDE | VDE | HT | VT | hss | hse */
253 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
254 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
255 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
256 /* VESA non-VESA noscale */
257 /* 1280x1024 */
258 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
259 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
260 /* 1400x1050 */
261 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
262 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
263 /* 1600x1200 */
264 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
265 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
266 /* 1280x768 (_2) */
267 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
268 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
269 /* 1280x720 */
270 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
271 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
272 /* 1280x800 (_2) */
273 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
274 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
275 /* 1680x1050 */
276 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
277 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
278 /* 1280x800_3 */
279 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
280 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
281 /* 800x600 */
282 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
283 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
284 /* 1280x854 */
285 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
286 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
288 #endif
290 #ifdef CONFIG_FB_SIS_300
291 static unsigned char SiS300_TrumpionData[14][80] = {
292 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
293 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
294 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
295 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
296 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
297 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
298 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
299 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
300 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
301 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
302 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
303 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
304 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
305 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
306 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
307 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
308 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
309 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
310 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
311 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
312 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
313 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
314 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
315 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
316 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
317 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
318 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
319 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
320 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
321 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
322 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
323 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
324 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
325 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
326 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
327 /* variant 2 */
328 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
329 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
330 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
331 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
332 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
333 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
334 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
335 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
336 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
337 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
338 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
339 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
340 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
341 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
342 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
343 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
344 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
345 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
346 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
347 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
348 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
349 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
350 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
351 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
352 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
353 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
354 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
355 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
356 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
357 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
358 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
359 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
360 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
361 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
362 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
364 #endif
366 #ifdef CONFIG_FB_SIS_315
367 static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
368 static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
369 static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
370 static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
371 #endif /* 315 */
373 #ifdef CONFIG_FB_SIS_300
374 static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
375 #endif
377 static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
378 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
379 bool checkcr32, unsigned int VBFlags2);
380 static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
381 static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
382 unsigned char *buffer);
383 static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
384 static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
385 static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
386 static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
387 static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
388 static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
389 static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
390 static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
391 static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
392 static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
393 static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
394 static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
395 static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
397 #ifdef CONFIG_FB_SIS_300
398 static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
399 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
400 static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
401 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
402 #endif
403 #ifdef CONFIG_FB_SIS_315
404 static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
405 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
406 static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
407 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
408 static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
409 #endif
411 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
412 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
414 /*********************************************/
415 /* HELPER: Lock/Unlock CRT2 */
416 /*********************************************/
418 void
419 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
421 if(SiS_Pr->ChipType == XGI_20)
422 return;
423 else if(SiS_Pr->ChipType >= SIS_315H)
424 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
425 else
426 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
429 static
430 void
431 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
433 if(SiS_Pr->ChipType == XGI_20)
434 return;
435 else if(SiS_Pr->ChipType >= SIS_315H)
436 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
437 else
438 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
441 /*********************************************/
442 /* HELPER: Write SR11 */
443 /*********************************************/
445 static void
446 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
448 if(SiS_Pr->ChipType >= SIS_661) {
449 DataAND &= 0x0f;
450 DataOR &= 0x0f;
452 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
455 /*********************************************/
456 /* HELPER: Get Pointer to LCD structure */
457 /*********************************************/
459 #ifdef CONFIG_FB_SIS_315
460 static unsigned char *
461 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
463 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
464 unsigned char *myptr = NULL;
465 unsigned short romindex = 0, reg = 0, idx = 0;
467 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
468 * due to the variaty of panels the BIOS doesn't know about.
469 * Exception: If the BIOS has better knowledge (such as in case
470 * of machines with a 301C and a panel that does not support DDC)
471 * use the BIOS data as well.
474 if((SiS_Pr->SiS_ROMNew) &&
475 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
477 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
478 else reg = 0x7d;
480 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
482 if(idx < (8*26)) {
483 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
485 romindex = SISGETROMW(0x100);
486 if(romindex) {
487 romindex += idx;
488 myptr = &ROMAddr[romindex];
491 return myptr;
494 static unsigned short
495 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
497 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
498 unsigned short romptr = 0;
500 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
501 * due to the variaty of panels the BIOS doesn't know about.
502 * Exception: If the BIOS has better knowledge (such as in case
503 * of machines with a 301C and a panel that does not support DDC)
504 * use the BIOS data as well.
507 if((SiS_Pr->SiS_ROMNew) &&
508 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
509 romptr = SISGETROMW(0x102);
510 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
513 return romptr;
515 #endif
517 /*********************************************/
518 /* Adjust Rate for CRT2 */
519 /*********************************************/
521 static bool
522 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
523 unsigned short RRTI, unsigned short *i)
525 unsigned short checkmask=0, modeid, infoflag;
527 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
529 if(SiS_Pr->SiS_VBType & VB_SISVB) {
531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
533 checkmask |= SupportRAMDAC2;
534 if(SiS_Pr->ChipType >= SIS_315H) {
535 checkmask |= SupportRAMDAC2_135;
536 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
537 checkmask |= SupportRAMDAC2_162;
538 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
539 checkmask |= SupportRAMDAC2_202;
544 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
546 checkmask |= SupportLCD;
547 if(SiS_Pr->ChipType >= SIS_315H) {
548 if(SiS_Pr->SiS_VBType & VB_SISVB) {
549 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
550 if(modeid == 0x2e) checkmask |= Support64048060Hz;
555 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
557 checkmask |= SupportHiVision;
559 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
561 checkmask |= SupportTV;
562 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
563 checkmask |= SupportTV1024;
564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
565 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
566 checkmask |= SupportYPbPr750p;
573 } else { /* LVDS */
575 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
576 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
577 checkmask |= SupportCHTV;
581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
582 checkmask |= SupportLCD;
587 /* Look backwards in table for matching CRT2 mode */
588 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
589 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
590 if(infoflag & checkmask) return true;
591 if((*i) == 0) break;
594 /* Look through the whole mode-section of the table from the beginning
595 * for a matching CRT2 mode if no mode was found yet.
597 for((*i) = 0; ; (*i)++) {
598 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
599 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
600 if(infoflag & checkmask) return true;
602 return false;
605 /*********************************************/
606 /* Get rate index */
607 /*********************************************/
609 unsigned short
610 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
612 unsigned short RRTI,i,backup_i;
613 unsigned short modeflag,index,temp,backupindex;
614 static const unsigned short LCDRefreshIndex[] = {
615 0x00, 0x00, 0x01, 0x01,
616 0x01, 0x01, 0x01, 0x01,
617 0x01, 0x01, 0x01, 0x01,
618 0x01, 0x01, 0x01, 0x01,
619 0x00, 0x00, 0x00, 0x00
622 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
623 if(ModeNo == 0xfe) return 0;
625 if(ModeNo <= 0x13) {
626 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
627 } else {
628 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
631 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
633 if(modeflag & HalfDCLK) return 0;
637 if(ModeNo < 0x14) return 0xFFFF;
639 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
640 backupindex = index;
642 if(index > 0) index--;
644 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
645 if(SiS_Pr->SiS_VBType & VB_SISVB) {
646 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
647 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
648 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
650 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
651 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
652 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
653 if(index > temp) index = temp;
656 } else {
657 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
658 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
664 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
665 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
667 if(SiS_Pr->ChipType >= SIS_315H) {
668 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
669 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
670 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
671 if(backupindex <= 1) RRTI++;
676 i = 0;
677 do {
678 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
679 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
680 temp &= ModeTypeMask;
681 if(temp < SiS_Pr->SiS_ModeType) break;
682 i++;
683 index--;
684 } while(index != 0xFFFF);
686 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
687 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
688 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
689 if(temp & InterlaceMode) i++;
693 i--;
695 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
696 backup_i = i;
697 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
698 i = backup_i;
702 return (RRTI + i);
705 /*********************************************/
706 /* STORE CRT2 INFO in CR34 */
707 /*********************************************/
709 static void
710 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
712 unsigned short temp1, temp2;
714 /* Store CRT1 ModeNo in CR34 */
715 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
716 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
717 temp2 = ~(SetInSlaveMode >> 8);
718 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
721 /*********************************************/
722 /* HELPER: GET SOME DATA FROM BIOS ROM */
723 /*********************************************/
725 #ifdef CONFIG_FB_SIS_300
726 static bool
727 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
729 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
730 unsigned short temp,temp1;
732 if(SiS_Pr->SiS_UseROM) {
733 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
734 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
735 temp1 = SISGETROMW(0x23b);
736 if(temp1 & temp) return true;
739 return false;
742 static bool
743 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
745 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
746 unsigned short temp,temp1;
748 if(SiS_Pr->SiS_UseROM) {
749 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
750 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
751 temp1 = SISGETROMW(0x23d);
752 if(temp1 & temp) return true;
755 return false;
757 #endif
759 /*********************************************/
760 /* HELPER: DELAY FUNCTIONS */
761 /*********************************************/
763 void
764 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
766 while (delaytime-- > 0)
767 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
770 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
771 static void
772 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
774 SiS_DDC2Delay(SiS_Pr, delay * 36);
776 #endif
778 #ifdef CONFIG_FB_SIS_315
779 static void
780 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
782 while(delay--) {
783 SiS_GenericDelay(SiS_Pr, 6623);
786 #endif
788 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
789 static void
790 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
792 while(delay--) {
793 SiS_GenericDelay(SiS_Pr, 66);
796 #endif
798 static void
799 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
801 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
802 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
803 unsigned short PanelID, DelayIndex, Delay=0;
804 #endif
806 if(SiS_Pr->ChipType < SIS_315H) {
808 #ifdef CONFIG_FB_SIS_300
810 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
811 if(SiS_Pr->SiS_VBType & VB_SISVB) {
812 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
813 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
815 DelayIndex = PanelID >> 4;
816 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
817 Delay = 3;
818 } else {
819 if(DelayTime >= 2) DelayTime -= 2;
820 if(!(DelayTime & 0x01)) {
821 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
822 } else {
823 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
825 if(SiS_Pr->SiS_UseROM) {
826 if(ROMAddr[0x220] & 0x40) {
827 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
828 else Delay = (unsigned short)ROMAddr[0x226];
832 SiS_ShortDelay(SiS_Pr, Delay);
834 #endif /* CONFIG_FB_SIS_300 */
836 } else {
838 #ifdef CONFIG_FB_SIS_315
840 if((SiS_Pr->ChipType >= SIS_661) ||
841 (SiS_Pr->ChipType <= SIS_315PRO) ||
842 (SiS_Pr->ChipType == SIS_330) ||
843 (SiS_Pr->SiS_ROMNew)) {
845 if(!(DelayTime & 0x01)) {
846 SiS_DDC2Delay(SiS_Pr, 0x1000);
847 } else {
848 SiS_DDC2Delay(SiS_Pr, 0x4000);
851 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
852 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
853 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
855 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
856 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
857 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
858 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
860 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
861 DelayIndex = PanelID & 0x0f;
862 } else {
863 DelayIndex = PanelID >> 4;
865 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
866 Delay = 3;
867 } else {
868 if(DelayTime >= 2) DelayTime -= 2;
869 if(!(DelayTime & 0x01)) {
870 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
871 } else {
872 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
874 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
875 if(ROMAddr[0x13c] & 0x40) {
876 if(!(DelayTime & 0x01)) {
877 Delay = (unsigned short)ROMAddr[0x17e];
878 } else {
879 Delay = (unsigned short)ROMAddr[0x17f];
884 SiS_ShortDelay(SiS_Pr, Delay);
887 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
889 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
890 if(!(DelayTime & 0x01)) {
891 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
892 } else {
893 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
895 Delay <<= 8;
896 SiS_DDC2Delay(SiS_Pr, Delay);
900 #endif /* CONFIG_FB_SIS_315 */
905 #ifdef CONFIG_FB_SIS_315
906 static void
907 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
909 int i;
910 for(i = 0; i < DelayLoop; i++) {
911 SiS_PanelDelay(SiS_Pr, DelayTime);
914 #endif
916 /*********************************************/
917 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
918 /*********************************************/
920 void
921 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
923 unsigned short watchdog;
925 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
926 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
928 watchdog = 65535;
929 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
930 watchdog = 65535;
931 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
934 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
935 static void
936 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
938 unsigned short watchdog;
940 watchdog = 65535;
941 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
942 watchdog = 65535;
943 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
945 #endif
947 static void
948 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
950 if(SiS_Pr->ChipType < SIS_315H) {
951 #ifdef CONFIG_FB_SIS_300
952 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
953 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
955 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
956 SiS_WaitRetrace1(SiS_Pr);
957 } else {
958 SiS_WaitRetrace2(SiS_Pr, 0x25);
960 #endif
961 } else {
962 #ifdef CONFIG_FB_SIS_315
963 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
964 SiS_WaitRetrace1(SiS_Pr);
965 } else {
966 SiS_WaitRetrace2(SiS_Pr, 0x30);
968 #endif
972 static void
973 SiS_VBWait(struct SiS_Private *SiS_Pr)
975 unsigned short tempal,temp,i,j;
977 temp = 0;
978 for(i = 0; i < 3; i++) {
979 for(j = 0; j < 100; j++) {
980 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
981 if(temp & 0x01) {
982 if((tempal & 0x08)) continue;
983 else break;
984 } else {
985 if(!(tempal & 0x08)) continue;
986 else break;
989 temp ^= 0x01;
993 static void
994 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
996 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
997 SiS_VBWait(SiS_Pr);
998 } else {
999 SiS_WaitRetrace1(SiS_Pr);
1003 /*********************************************/
1004 /* HELPER: MISC */
1005 /*********************************************/
1007 #ifdef CONFIG_FB_SIS_300
1008 static bool
1009 SiS_Is301B(struct SiS_Private *SiS_Pr)
1011 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1012 return false;
1014 #endif
1016 static bool
1017 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1019 if(SiS_Pr->ChipType == SIS_730) {
1020 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1022 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1023 return false;
1026 bool
1027 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1029 #ifdef CONFIG_FB_SIS_315
1030 if(SiS_Pr->ChipType >= SIS_315H) {
1031 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1032 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1035 #endif
1036 return false;
1039 bool
1040 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1042 #ifdef CONFIG_FB_SIS_315
1043 unsigned short flag;
1045 if(SiS_Pr->ChipType >= SIS_315H) {
1046 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1047 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1049 #endif
1050 return false;
1053 #ifdef CONFIG_FB_SIS_315
1054 static bool
1055 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1057 if(SiS_IsVAMode(SiS_Pr)) return true;
1058 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1059 return false;
1061 #endif
1063 static bool
1064 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1066 #ifdef CONFIG_FB_SIS_315
1067 if(SiS_Pr->ChipType >= SIS_315H) {
1068 if((SiS_CRT2IsLCD(SiS_Pr)) ||
1069 (SiS_IsVAMode(SiS_Pr))) {
1070 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1073 #endif
1074 return false;
1077 #ifdef CONFIG_FB_SIS_315
1078 static bool
1079 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1081 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1082 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1083 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1085 return false;
1087 #endif
1089 #ifdef CONFIG_FB_SIS_315
1090 static bool
1091 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1093 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1094 return false;
1096 #endif
1098 #ifdef CONFIG_FB_SIS_315
1099 static bool
1100 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1102 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1103 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1105 return false;
1107 #endif
1109 #ifdef CONFIG_FB_SIS_315
1110 static bool
1111 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1113 unsigned short flag;
1115 if(SiS_Pr->ChipType == SIS_650) {
1116 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1117 /* Check for revision != A0 only */
1118 if((flag == 0xe0) || (flag == 0xc0) ||
1119 (flag == 0xb0) || (flag == 0x90)) return false;
1120 } else if(SiS_Pr->ChipType >= SIS_661) return false;
1121 return true;
1123 #endif
1125 #ifdef CONFIG_FB_SIS_315
1126 static bool
1127 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1129 if(SiS_Pr->ChipType >= SIS_315H) {
1130 /* YPrPb = 0x08 */
1131 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1133 return false;
1135 #endif
1137 #ifdef CONFIG_FB_SIS_315
1138 static bool
1139 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1141 if(SiS_Pr->ChipType >= SIS_315H) {
1142 /* Scart = 0x04 */
1143 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1145 return false;
1147 #endif
1149 #ifdef CONFIG_FB_SIS_315
1150 static bool
1151 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1153 unsigned short flag;
1155 if(SiS_Pr->ChipType >= SIS_315H) {
1156 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1157 if(flag & SetCRT2ToTV) return true;
1158 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1159 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
1160 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
1161 } else {
1162 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1163 if(flag & SetCRT2ToTV) return true;
1165 return false;
1167 #endif
1169 #ifdef CONFIG_FB_SIS_315
1170 static bool
1171 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1173 unsigned short flag;
1175 if(SiS_Pr->ChipType >= SIS_315H) {
1176 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1177 if(flag & SetCRT2ToLCD) return true;
1178 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1179 if(flag & SetToLCDA) return true;
1180 } else {
1181 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1182 if(flag & SetCRT2ToLCD) return true;
1184 return false;
1186 #endif
1188 static bool
1189 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1191 unsigned short flag;
1193 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1194 return true;
1195 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1196 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1197 if((flag == 1) || (flag == 2)) return true;
1199 return false;
1202 static bool
1203 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1205 unsigned short flag;
1207 if(SiS_HaveBridge(SiS_Pr)) {
1208 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1209 if(SiS_Pr->ChipType < SIS_315H) {
1210 flag &= 0xa0;
1211 if((flag == 0x80) || (flag == 0x20)) return true;
1212 } else {
1213 flag &= 0x50;
1214 if((flag == 0x40) || (flag == 0x10)) return true;
1217 return false;
1220 static bool
1221 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1223 unsigned short flag1;
1225 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1226 if(flag1 & (SetInSlaveMode >> 8)) return true;
1227 return false;
1230 /*********************************************/
1231 /* GET VIDEO BRIDGE CONFIG INFO */
1232 /*********************************************/
1234 /* Setup general purpose IO for Chrontel communication */
1235 #ifdef CONFIG_FB_SIS_300
1236 void
1237 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1239 unsigned int acpibase;
1240 unsigned short temp;
1242 if(!(SiS_Pr->SiS_ChSW)) return;
1244 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1245 acpibase &= 0xFFFF;
1246 if(!acpibase) return;
1247 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
1248 temp &= 0xFEFF;
1249 SiS_SetRegShort((acpibase + 0x3c), temp);
1250 temp = SiS_GetRegShort((acpibase + 0x3c));
1251 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
1252 temp &= 0xFEFF;
1253 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1254 SiS_SetRegShort((acpibase + 0x3a), temp);
1255 temp = SiS_GetRegShort((acpibase + 0x3a));
1257 #endif
1259 void
1260 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1261 unsigned short ModeIdIndex, int checkcrt2mode)
1263 unsigned short tempax, tempbx, temp;
1264 unsigned short modeflag, resinfo = 0;
1266 SiS_Pr->SiS_SetFlag = 0;
1268 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1270 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1272 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1273 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1276 tempbx = 0;
1278 if(SiS_HaveBridge(SiS_Pr)) {
1280 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1281 tempbx |= temp;
1282 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1283 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1284 tempbx |= tempax;
1286 #ifdef CONFIG_FB_SIS_315
1287 if(SiS_Pr->ChipType >= SIS_315H) {
1288 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1289 if(ModeNo == 0x03) {
1290 /* Mode 0x03 is never in driver mode */
1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1293 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1294 /* Reset LCDA setting if not driver mode */
1295 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1297 if(IS_SIS650) {
1298 if(SiS_Pr->SiS_UseLCDA) {
1299 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1300 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1301 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1306 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1307 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1308 tempbx |= SetCRT2ToLCDA;
1312 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1313 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1314 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1315 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1316 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1317 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1318 tempbx |= SetCRT2ToYPbPr525750;
1323 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1324 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1325 if(temp & SetToLCDA) {
1326 tempbx |= SetCRT2ToLCDA;
1328 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1329 if(temp & EnableCHYPbPr) {
1330 tempbx |= SetCRT2ToCHYPbPr;
1336 #endif /* CONFIG_FB_SIS_315 */
1338 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1339 tempbx &= ~(SetCRT2ToRAMDAC);
1342 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1343 temp = SetCRT2ToSVIDEO |
1344 SetCRT2ToAVIDEO |
1345 SetCRT2ToSCART |
1346 SetCRT2ToLCDA |
1347 SetCRT2ToLCD |
1348 SetCRT2ToRAMDAC |
1349 SetCRT2ToHiVision |
1350 SetCRT2ToYPbPr525750;
1351 } else {
1352 if(SiS_Pr->ChipType >= SIS_315H) {
1353 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1354 temp = SetCRT2ToAVIDEO |
1355 SetCRT2ToSVIDEO |
1356 SetCRT2ToSCART |
1357 SetCRT2ToLCDA |
1358 SetCRT2ToLCD |
1359 SetCRT2ToCHYPbPr;
1360 } else {
1361 temp = SetCRT2ToLCDA |
1362 SetCRT2ToLCD;
1364 } else {
1365 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1366 temp = SetCRT2ToTV | SetCRT2ToLCD;
1367 } else {
1368 temp = SetCRT2ToLCD;
1373 if(!(tempbx & temp)) {
1374 tempax = DisableCRT2Display;
1375 tempbx = 0;
1378 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1380 unsigned short clearmask = ( DriverMode |
1381 DisableCRT2Display |
1382 LoadDACFlag |
1383 SetNotSimuMode |
1384 SetInSlaveMode |
1385 SetPALTV |
1386 SwitchCRT2 |
1387 SetSimuScanMode );
1389 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1390 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1391 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1392 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1393 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1394 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1396 } else {
1398 if(SiS_Pr->ChipType >= SIS_315H) {
1399 if(tempbx & SetCRT2ToLCDA) {
1400 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1403 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1404 if(tempbx & SetCRT2ToTV) {
1405 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1408 if(tempbx & SetCRT2ToLCD) {
1409 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1411 if(SiS_Pr->ChipType >= SIS_315H) {
1412 if(tempbx & SetCRT2ToLCDA) {
1413 tempbx |= SetCRT2ToLCD;
1419 if(tempax & DisableCRT2Display) {
1420 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1421 tempbx = SetSimuScanMode | DisableCRT2Display;
1425 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1427 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1428 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1429 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1430 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1431 modeflag &= (~CRT2Mode);
1435 if(!(tempbx & SetSimuScanMode)) {
1436 if(tempbx & SwitchCRT2) {
1437 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1438 if(resinfo != SIS_RI_1600x1200) {
1439 tempbx |= SetSimuScanMode;
1442 } else {
1443 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1444 if(!(tempbx & DriverMode)) {
1445 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1446 tempbx |= SetSimuScanMode;
1453 if(!(tempbx & DisableCRT2Display)) {
1454 if(tempbx & DriverMode) {
1455 if(tempbx & SetSimuScanMode) {
1456 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1457 if(resinfo != SIS_RI_1600x1200) {
1458 tempbx |= SetInSlaveMode;
1462 } else {
1463 tempbx |= SetInSlaveMode;
1469 SiS_Pr->SiS_VBInfo = tempbx;
1471 #ifdef CONFIG_FB_SIS_300
1472 if(SiS_Pr->ChipType == SIS_630) {
1473 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1475 #endif
1477 #if 0
1478 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1479 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1480 #endif
1483 /*********************************************/
1484 /* DETERMINE YPbPr MODE */
1485 /*********************************************/
1487 void
1488 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1491 unsigned char temp;
1493 /* Note: This variable is only used on 30xLV systems.
1494 * CR38 has a different meaning on LVDS/CH7019 systems.
1495 * On 661 and later, these bits moved to CR35.
1497 * On 301, 301B, only HiVision 1080i is supported.
1498 * On 30xLV, 301C, only YPbPr 1080i is supported.
1501 SiS_Pr->SiS_YPbPr = 0;
1502 if(SiS_Pr->ChipType >= SIS_661) return;
1504 if(SiS_Pr->SiS_VBType) {
1505 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1506 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1510 if(SiS_Pr->ChipType >= SIS_315H) {
1511 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1512 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1513 if(temp & 0x08) {
1514 switch((temp >> 4)) {
1515 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1516 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1517 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1518 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1526 /*********************************************/
1527 /* DETERMINE TVMode flag */
1528 /*********************************************/
1530 void
1531 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1533 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1534 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1535 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1537 SiS_Pr->SiS_TVMode = 0;
1539 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1540 if(SiS_Pr->UseCustomMode) return;
1542 if(ModeNo > 0x13) {
1543 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1546 if(SiS_Pr->ChipType < SIS_661) {
1548 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1550 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1551 temp = 0;
1552 if((SiS_Pr->ChipType == SIS_630) ||
1553 (SiS_Pr->ChipType == SIS_730)) {
1554 temp = 0x35;
1555 romindex = 0xfe;
1556 } else if(SiS_Pr->ChipType >= SIS_315H) {
1557 temp = 0x38;
1558 if(SiS_Pr->ChipType < XGI_20) {
1559 romindex = 0xf3;
1560 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1563 if(temp) {
1564 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1565 OutputSelect = ROMAddr[romindex];
1566 if(!(OutputSelect & EnablePALMN)) {
1567 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1570 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1571 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1572 if(temp1 & EnablePALM) { /* 0x40 */
1573 SiS_Pr->SiS_TVMode |= TVSetPALM;
1574 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1575 } else if(temp1 & EnablePALN) { /* 0x80 */
1576 SiS_Pr->SiS_TVMode |= TVSetPALN;
1578 } else {
1579 if(temp1 & EnableNTSCJ) { /* 0x40 */
1580 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1584 /* Translate HiVision/YPbPr to our new flags */
1585 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1586 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1587 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1588 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1589 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1590 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1591 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1592 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1593 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1594 SiS_Pr->SiS_TVMode |= TVSetPAL;
1597 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1598 if(SiS_Pr->SiS_CHOverScan) {
1599 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1600 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1601 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1602 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1604 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1605 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1606 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1607 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1610 if(SiS_Pr->SiS_CHSOverScan) {
1611 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1614 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1615 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1616 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1617 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1618 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1619 } else {
1620 if(temp & EnableNTSCJ) {
1621 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1627 } else { /* 661 and later */
1629 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1630 if(temp1 & 0x01) {
1631 SiS_Pr->SiS_TVMode |= TVSetPAL;
1632 if(temp1 & 0x08) {
1633 SiS_Pr->SiS_TVMode |= TVSetPALN;
1634 } else if(temp1 & 0x04) {
1635 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1636 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1638 SiS_Pr->SiS_TVMode |= TVSetPALM;
1640 } else {
1641 if(temp1 & 0x02) {
1642 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1645 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1646 if(SiS_Pr->SiS_CHOverScan) {
1647 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1648 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1652 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1653 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1654 temp1 &= 0xe0;
1655 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1656 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1657 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1658 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1659 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1661 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1662 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1663 SiS_Pr->SiS_TVMode |= TVAspect169;
1664 } else {
1665 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1666 if(temp1 & 0x02) {
1667 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1668 SiS_Pr->SiS_TVMode |= TVAspect169;
1669 } else {
1670 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1672 } else {
1673 SiS_Pr->SiS_TVMode |= TVAspect43;
1680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1682 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1684 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1685 SiS_Pr->SiS_TVMode |= TVSetPAL;
1686 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1687 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1688 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1689 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1693 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1694 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1695 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1699 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1700 if(resinfo == SIS_RI_1024x768) {
1701 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1702 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1703 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1704 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1709 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1710 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1711 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1712 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1713 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1714 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1715 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1716 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1717 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1723 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1726 /*********************************************/
1727 /* GET LCD INFO */
1728 /*********************************************/
1730 static unsigned short
1731 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1733 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1734 /* Translate my LCDResInfo to BIOS value */
1735 switch(temp) {
1736 case Panel_1280x768_2: temp = Panel_1280x768; break;
1737 case Panel_1280x800_2: temp = Panel_1280x800; break;
1738 case Panel_1280x854: temp = Panel661_1280x854; break;
1740 return temp;
1743 static void
1744 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1746 #ifdef CONFIG_FB_SIS_315
1747 unsigned char *ROMAddr;
1748 unsigned short temp;
1750 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1751 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1752 SiS_Pr->SiS_NeedRomModeData = true;
1753 SiS_Pr->PanelHT = temp;
1755 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1756 SiS_Pr->SiS_NeedRomModeData = true;
1757 SiS_Pr->PanelVT = temp;
1759 SiS_Pr->PanelHRS = SISGETROMW(10);
1760 SiS_Pr->PanelHRE = SISGETROMW(12);
1761 SiS_Pr->PanelVRS = SISGETROMW(14);
1762 SiS_Pr->PanelVRE = SISGETROMW(16);
1763 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1764 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1765 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1766 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1767 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1768 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1769 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1772 #endif
1775 static void
1776 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1777 const unsigned char *nonscalingmodes)
1779 int i = 0;
1780 while(nonscalingmodes[i] != 0xff) {
1781 if(nonscalingmodes[i++] == resinfo) {
1782 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1783 (SiS_Pr->UsePanelScaler == -1)) {
1784 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1786 break;
1791 void
1792 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1794 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1795 bool panelcanscale = false;
1796 #ifdef CONFIG_FB_SIS_300
1797 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1798 static const unsigned char SiS300SeriesLCDRes[] =
1799 { 0, 1, 2, 3, 7, 4, 5, 8,
1800 0, 0, 10, 0, 0, 0, 0, 15 };
1801 #endif
1802 #ifdef CONFIG_FB_SIS_315
1803 unsigned char *myptr = NULL;
1804 #endif
1806 SiS_Pr->SiS_LCDResInfo = 0;
1807 SiS_Pr->SiS_LCDTypeInfo = 0;
1808 SiS_Pr->SiS_LCDInfo = 0;
1809 SiS_Pr->PanelHRS = 999; /* HSync start */
1810 SiS_Pr->PanelHRE = 999; /* HSync end */
1811 SiS_Pr->PanelVRS = 999; /* VSync start */
1812 SiS_Pr->PanelVRE = 999; /* VSync end */
1813 SiS_Pr->SiS_NeedRomModeData = false;
1815 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1816 SiS_Pr->Alternate1600x1200 = false;
1818 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1820 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1822 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1823 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1824 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1825 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1828 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1830 /* For broken BIOSes: Assume 1024x768 */
1831 if(temp == 0) temp = 0x02;
1833 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1834 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1835 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1836 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1837 } else {
1838 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1840 temp &= 0x0f;
1841 #ifdef CONFIG_FB_SIS_300
1842 if(SiS_Pr->ChipType < SIS_315H) {
1843 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1844 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1845 if(temp < 0x0f) temp &= 0x07;
1847 /* Translate 300 series LCDRes to 315 series for unified usage */
1848 temp = SiS300SeriesLCDRes[temp];
1850 #endif
1852 /* Translate to our internal types */
1853 #ifdef CONFIG_FB_SIS_315
1854 if(SiS_Pr->ChipType == SIS_550) {
1855 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1856 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1857 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1858 } else if(SiS_Pr->ChipType >= SIS_661) {
1859 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1861 #endif
1863 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1864 if(temp == Panel310_1280x768) {
1865 temp = Panel_1280x768_2;
1867 if(SiS_Pr->SiS_ROMNew) {
1868 if(temp == Panel661_1280x800) {
1869 temp = Panel_1280x800_2;
1874 SiS_Pr->SiS_LCDResInfo = temp;
1876 #ifdef CONFIG_FB_SIS_300
1877 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1878 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1879 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1880 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1881 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1882 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1883 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1886 #endif
1888 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1889 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1890 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1891 } else {
1892 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1893 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1896 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1897 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1898 /* Need temp below! */
1900 /* These must/can't scale no matter what */
1901 switch(SiS_Pr->SiS_LCDResInfo) {
1902 case Panel_320x240_1:
1903 case Panel_320x240_2:
1904 case Panel_320x240_3:
1905 case Panel_1280x960:
1906 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1907 break;
1908 case Panel_640x480:
1909 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1912 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1914 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1915 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1917 /* Dual link, Pass 1:1 BIOS default, etc. */
1918 #ifdef CONFIG_FB_SIS_315
1919 if(SiS_Pr->ChipType >= SIS_661) {
1920 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1921 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1923 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1924 if(SiS_Pr->SiS_ROMNew) {
1925 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1926 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1927 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1930 } else if(SiS_Pr->ChipType >= SIS_315H) {
1931 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1932 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1934 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1935 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1936 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1937 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1938 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1939 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1941 } else if(!(SiS_Pr->SiS_ROMNew)) {
1942 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1943 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1944 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1945 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1947 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1948 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1949 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1950 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1951 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1956 #endif
1958 /* Pass 1:1 */
1959 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1960 /* Always center screen on LVDS (if scaling is disabled) */
1961 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1962 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1963 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1964 /* Always center screen on SiS LVDS (if scaling is disabled) */
1965 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1966 } else {
1967 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1968 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1969 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1973 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1974 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1976 switch(SiS_Pr->SiS_LCDResInfo) {
1977 case Panel_320x240_1:
1978 case Panel_320x240_2:
1979 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1980 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1981 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1982 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1983 break;
1984 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1985 SiS_Pr->PanelVRE = 3;
1986 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1987 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1988 break;
1989 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1990 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1991 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1992 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1993 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1994 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1995 break;
1996 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1997 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1998 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1999 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
2000 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2001 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2002 break;
2003 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2004 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2005 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2006 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2007 if(SiS_Pr->ChipType < SIS_315H) {
2008 SiS_Pr->PanelHRS = 23;
2009 SiS_Pr->PanelVRE = 5;
2011 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2012 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2013 SiS_GetLCDInfoBIOS(SiS_Pr);
2014 break;
2015 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
2016 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2017 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2018 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2019 if(SiS_Pr->ChipType < SIS_315H) {
2020 SiS_Pr->PanelHRS = 23;
2021 SiS_Pr->PanelVRE = 5;
2023 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2024 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2025 break;
2026 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
2027 break;
2028 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
2029 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
2030 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
2031 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
2032 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2033 /* Data above for TMDS (projector); get from BIOS for LVDS */
2034 SiS_GetLCDInfoBIOS(SiS_Pr);
2035 break;
2036 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2037 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2038 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
2039 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2040 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2041 } else {
2042 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
2043 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2044 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2045 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2046 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2048 break;
2049 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2050 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
2051 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2052 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2053 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2054 SiS_GetLCDInfoBIOS(SiS_Pr);
2055 break;
2056 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2057 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
2058 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
2059 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2060 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2061 SiS_GetLCDInfoBIOS(SiS_Pr);
2062 break;
2063 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2064 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
2065 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2066 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2067 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2068 SiS_GetLCDInfoBIOS(SiS_Pr);
2069 break;
2070 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
2071 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
2072 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
2073 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2074 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2075 SiS_GetLCDInfoBIOS(SiS_Pr);
2076 break;
2077 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
2078 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
2079 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2080 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2081 if(resinfo == SIS_RI_1280x1024) {
2082 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2083 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2085 break;
2086 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2087 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2088 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2089 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2090 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2091 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2092 SiS_GetLCDInfoBIOS(SiS_Pr);
2093 break;
2094 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2095 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2096 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2097 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2098 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2099 SiS_GetLCDInfoBIOS(SiS_Pr);
2100 break;
2101 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2102 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
2103 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
2104 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2105 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2106 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2107 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2108 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
2109 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
2110 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
2111 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2112 SiS_Pr->Alternate1600x1200 = true;
2114 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2115 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
2116 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2117 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2119 SiS_GetLCDInfoBIOS(SiS_Pr);
2120 break;
2121 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2122 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
2123 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
2124 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2125 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2126 SiS_GetLCDInfoBIOS(SiS_Pr);
2127 break;
2128 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2129 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2130 break;
2131 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
2132 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2133 break;
2134 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
2135 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2136 break;
2137 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2138 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2139 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
2140 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
2141 if(SiS_Pr->CP_PreferredIndex != -1) {
2142 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2143 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2144 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2145 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2146 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2147 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2148 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2149 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2150 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2151 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2152 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2153 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2154 if(SiS_Pr->CP_PrefClock) {
2155 int idx;
2156 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2157 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2158 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2159 else idx = VCLK_CUSTOM_315;
2160 SiS_Pr->SiS_VCLKData[idx].CLOCK =
2161 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2162 SiS_Pr->SiS_VCLKData[idx].SR2B =
2163 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2164 SiS_Pr->SiS_VCLKData[idx].SR2C =
2165 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2168 break;
2169 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2170 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2171 break;
2174 /* Special cases */
2175 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
2176 (SiS_Pr->SiS_IF_DEF_DSTN) ||
2177 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2178 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2179 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2180 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2181 SiS_Pr->PanelHRS = 999;
2182 SiS_Pr->PanelHRE = 999;
2185 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2186 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2187 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2188 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2189 SiS_Pr->PanelVRS = 999;
2190 SiS_Pr->PanelVRE = 999;
2193 /* DontExpand overrule */
2194 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2196 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2197 /* No scaling for this mode on any panel (LCD=CRT2)*/
2198 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2201 switch(SiS_Pr->SiS_LCDResInfo) {
2203 case Panel_Custom:
2204 case Panel_1152x864:
2205 case Panel_1280x768: /* TMDS only */
2206 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2207 break;
2209 case Panel_800x600: {
2210 static const unsigned char nonscalingmodes[] = {
2211 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2213 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2214 break;
2216 case Panel_1024x768: {
2217 static const unsigned char nonscalingmodes[] = {
2218 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2219 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2220 0xff
2222 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2223 break;
2225 case Panel_1280x720: {
2226 static const unsigned char nonscalingmodes[] = {
2227 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2228 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2229 0xff
2231 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2232 if(SiS_Pr->PanelHT == 1650) {
2233 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2235 break;
2237 case Panel_1280x768_2: { /* LVDS only */
2238 static const unsigned char nonscalingmodes[] = {
2239 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2240 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2241 SIS_RI_1152x768,0xff
2243 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2244 switch(resinfo) {
2245 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2246 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2248 break;
2250 break;
2252 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
2253 static const unsigned char nonscalingmodes[] = {
2254 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2255 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2256 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2258 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2259 break;
2261 case Panel_1280x800_2: { /* SiS LVDS */
2262 static const unsigned char nonscalingmodes[] = {
2263 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2264 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2265 SIS_RI_1152x768,0xff
2267 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2268 switch(resinfo) {
2269 case SIS_RI_1280x720:
2270 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
2271 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2273 break;
2275 break;
2277 case Panel_1280x854: { /* SiS LVDS */
2278 static const unsigned char nonscalingmodes[] = {
2279 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2280 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2281 SIS_RI_1152x768,0xff
2283 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2284 switch(resinfo) {
2285 case SIS_RI_1280x720:
2286 case SIS_RI_1280x768:
2287 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2288 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2290 break;
2292 break;
2294 case Panel_1280x960: {
2295 static const unsigned char nonscalingmodes[] = {
2296 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2297 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2298 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2299 SIS_RI_1280x854,0xff
2301 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2302 break;
2304 case Panel_1280x1024: {
2305 static const unsigned char nonscalingmodes[] = {
2306 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2307 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2308 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2309 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2311 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2312 break;
2314 case Panel_1400x1050: {
2315 static const unsigned char nonscalingmodes[] = {
2316 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2317 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2318 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2319 SIS_RI_1280x960,0xff
2321 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2322 switch(resinfo) {
2323 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2324 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2326 break;
2327 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2328 break;
2330 break;
2332 case Panel_1600x1200: {
2333 static const unsigned char nonscalingmodes[] = {
2334 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2335 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2336 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2337 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2339 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2340 break;
2342 case Panel_1680x1050: {
2343 static const unsigned char nonscalingmodes[] = {
2344 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2345 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2346 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2347 SIS_RI_1360x1024,0xff
2349 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2350 break;
2355 #ifdef CONFIG_FB_SIS_300
2356 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2357 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2358 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2362 if(SiS_Pr->ChipType < SIS_315H) {
2363 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2364 if(SiS_Pr->SiS_UseROM) {
2365 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2366 if(!(ROMAddr[0x235] & 0x02)) {
2367 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2371 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2372 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2373 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2377 #endif
2379 /* Special cases */
2381 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2382 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2385 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2386 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2389 switch(SiS_Pr->SiS_LCDResInfo) {
2390 case Panel_640x480:
2391 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2392 break;
2393 case Panel_1280x800:
2394 /* Don't pass 1:1 by default (TMDS special) */
2395 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2396 break;
2397 case Panel_1280x960:
2398 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2399 break;
2400 case Panel_Custom:
2401 if((!SiS_Pr->CP_PrefClock) ||
2402 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2403 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2405 break;
2408 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2409 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2412 /* (In)validate LCDPass11 flag */
2413 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2414 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2417 /* LVDS DDA */
2418 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2420 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2421 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2422 if(ModeNo == 0x12) {
2423 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2424 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2426 } else if(ModeNo > 0x13) {
2427 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2428 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2429 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2430 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2438 if(modeflag & HalfDCLK) {
2439 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2440 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2441 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2442 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2443 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2444 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2445 } else if(ModeNo > 0x13) {
2446 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2447 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2448 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2449 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2456 /* VESA timing */
2457 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2458 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2459 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2461 } else {
2462 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2465 #if 0
2466 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2467 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2468 #endif
2471 /*********************************************/
2472 /* GET VCLK */
2473 /*********************************************/
2475 unsigned short
2476 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2477 unsigned short RefreshRateTableIndex)
2479 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2480 unsigned short resinfo, tempbx;
2481 const unsigned char *CHTVVCLKPtr = NULL;
2483 if(ModeNo <= 0x13) {
2484 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2485 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2486 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2487 VCLKIndexGENCRT = VCLKIndexGEN;
2488 } else {
2489 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2490 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2491 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2492 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2493 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2496 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2498 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2500 CRT2Index >>= 6;
2501 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2503 if(SiS_Pr->ChipType < SIS_315H) {
2504 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2505 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2506 VCLKIndex = VCLKIndexGEN;
2508 } else {
2509 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2510 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2511 switch(resinfo) {
2512 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2513 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2514 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2515 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2516 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2517 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2518 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2519 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2520 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2521 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2522 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2523 default: VCLKIndex = VCLKIndexGEN;
2526 if(ModeNo <= 0x13) {
2527 if(SiS_Pr->ChipType <= SIS_315PRO) {
2528 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2529 } else {
2530 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2533 if(SiS_Pr->ChipType <= SIS_315PRO) {
2534 if(VCLKIndex == 0) VCLKIndex = 0x41;
2535 if(VCLKIndex == 1) VCLKIndex = 0x43;
2536 if(VCLKIndex == 4) VCLKIndex = 0x44;
2541 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2543 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2544 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2545 else VCLKIndex = HiTVVCLK;
2546 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2547 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2548 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2549 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2550 else VCLKIndex = TVVCLK;
2552 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2553 else VCLKIndex += TVCLKBASE_315;
2555 } else { /* VGA2 */
2557 VCLKIndex = VCLKIndexGENCRT;
2558 if(SiS_Pr->ChipType < SIS_315H) {
2559 if(ModeNo > 0x13) {
2560 if( (SiS_Pr->ChipType == SIS_630) &&
2561 (SiS_Pr->ChipRevision >= 0x30)) {
2562 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2564 /* Better VGA2 clock for 1280x1024@75 */
2565 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2570 } else { /* If not programming CRT2 */
2572 VCLKIndex = VCLKIndexGENCRT;
2573 if(SiS_Pr->ChipType < SIS_315H) {
2574 if(ModeNo > 0x13) {
2575 if( (SiS_Pr->ChipType != SIS_630) &&
2576 (SiS_Pr->ChipType != SIS_300) ) {
2577 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2583 } else { /* LVDS */
2585 VCLKIndex = CRT2Index;
2587 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2589 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2591 VCLKIndex &= 0x1f;
2592 tempbx = 0;
2593 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2594 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2595 tempbx += 2;
2596 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2597 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2599 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2600 tempbx = 4;
2601 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2602 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2603 tempbx = 6;
2604 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2607 switch(tempbx) {
2608 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2609 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2610 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2611 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2612 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2613 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2614 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2615 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2616 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2617 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2619 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2621 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2623 if(SiS_Pr->ChipType < SIS_315H) {
2624 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2625 } else {
2626 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2629 #ifdef CONFIG_FB_SIS_300
2630 /* Special Timing: Barco iQ Pro R series */
2631 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2633 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2634 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2635 if(SiS_Pr->ChipType < SIS_315H) {
2636 VCLKIndex = VCLK34_300;
2637 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2638 } else {
2639 VCLKIndex = VCLK34_315;
2640 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2643 #endif
2645 } else {
2647 VCLKIndex = VCLKIndexGENCRT;
2648 if(SiS_Pr->ChipType < SIS_315H) {
2649 if(ModeNo > 0x13) {
2650 if( (SiS_Pr->ChipType == SIS_630) &&
2651 (SiS_Pr->ChipRevision >= 0x30) ) {
2652 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2658 } else { /* if not programming CRT2 */
2660 VCLKIndex = VCLKIndexGENCRT;
2661 if(SiS_Pr->ChipType < SIS_315H) {
2662 if(ModeNo > 0x13) {
2663 if( (SiS_Pr->ChipType != SIS_630) &&
2664 (SiS_Pr->ChipType != SIS_300) ) {
2665 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2667 #if 0
2668 if(SiS_Pr->ChipType == SIS_730) {
2669 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2670 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2672 #endif
2680 return VCLKIndex;
2683 /*********************************************/
2684 /* SET CRT2 MODE TYPE REGISTERS */
2685 /*********************************************/
2687 static void
2688 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2690 unsigned short i, j, modeflag, tempah=0;
2691 short tempcl;
2692 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2693 unsigned short tempbl;
2694 #endif
2695 #ifdef CONFIG_FB_SIS_315
2696 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2697 unsigned short tempah2, tempbl2;
2698 #endif
2700 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2704 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2705 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2707 } else {
2709 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2710 if(SiS_Pr->ChipType >= SIS_315H) {
2711 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2714 tempcl = SiS_Pr->SiS_ModeType;
2716 if(SiS_Pr->ChipType < SIS_315H) {
2718 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2720 /* For 301BDH: (with LCD via LVDS) */
2721 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2722 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2723 tempbl &= 0xef;
2724 tempbl |= 0x02;
2725 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2726 tempbl |= 0x10;
2727 tempbl &= 0xfd;
2729 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2732 if(ModeNo > 0x13) {
2733 tempcl -= ModeVGA;
2734 if(tempcl >= 0) {
2735 tempah = ((0x10 >> tempcl) | 0x80);
2737 } else tempah = 0x80;
2739 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2741 #endif /* CONFIG_FB_SIS_300 */
2743 } else {
2745 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2747 if(ModeNo > 0x13) {
2748 tempcl -= ModeVGA;
2749 if(tempcl >= 0) {
2750 tempah = (0x08 >> tempcl);
2751 if (tempah == 0) tempah = 1;
2752 tempah |= 0x40;
2754 } else tempah = 0x40;
2756 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2758 #endif /* CONFIG_FB_SIS_315 */
2762 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2764 if(SiS_Pr->ChipType < SIS_315H) {
2765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2766 } else {
2767 #ifdef CONFIG_FB_SIS_315
2768 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2769 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2770 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2771 if(IS_SIS740) {
2772 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2773 } else {
2774 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2777 #endif
2780 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2782 tempah = 0x01;
2783 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2784 tempah |= 0x02;
2786 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2787 tempah ^= 0x05;
2788 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2789 tempah ^= 0x01;
2793 if(SiS_Pr->ChipType < SIS_315H) {
2795 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2797 tempah = (tempah << 5) & 0xFF;
2798 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2799 tempah = (tempah >> 5) & 0xFF;
2801 } else {
2803 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2804 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2805 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2806 tempah &= ~0x08;
2810 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2811 tempah |= 0x10;
2814 tempah |= 0x80;
2815 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2816 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2819 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2820 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2821 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2822 tempah |= 0x20;
2827 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2829 tempah = 0x80;
2830 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2831 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2834 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2836 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2837 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2838 tempah |= 0x40;
2842 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2844 } else { /* LVDS */
2846 if(SiS_Pr->ChipType >= SIS_315H) {
2848 #ifdef CONFIG_FB_SIS_315
2849 /* LVDS can only be slave in 8bpp modes */
2850 tempah = 0x80;
2851 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2852 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2853 tempah |= 0x02;
2857 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2859 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2861 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2863 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2864 #endif
2866 } else {
2868 #ifdef CONFIG_FB_SIS_300
2869 tempah = 0;
2870 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2871 tempah |= 0x02;
2873 tempah <<= 5;
2875 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2878 #endif
2884 } /* LCDA */
2886 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2888 if(SiS_Pr->ChipType >= SIS_315H) {
2890 #ifdef CONFIG_FB_SIS_315
2891 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2893 /* The following is nearly unpreditable and varies from machine
2894 * to machine. Especially the 301DH seems to be a real trouble
2895 * maker. Some BIOSes simply set the registers (like in the
2896 * NoLCD-if-statements here), some set them according to the
2897 * LCDA stuff. It is very likely that some machines are not
2898 * treated correctly in the following, very case-orientated
2899 * code. What do I do then...?
2902 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2904 if(!(IS_SIS740)) {
2905 tempah = 0x04; /* For all bridges */
2906 tempbl = 0xfb;
2907 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2908 tempah = 0x00;
2909 if(SiS_IsDualEdge(SiS_Pr)) {
2910 tempbl = 0xff;
2913 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2916 /* The following two are responsible for eventually wrong colors
2917 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2918 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2919 * in a 650 box (Jake). What is the criteria?
2920 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2921 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2922 * chipset than the bridge revision.
2925 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2926 tempah = 0x30;
2927 tempbl = 0xc0;
2928 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2929 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2930 tempah = 0x00;
2931 tempbl = 0x00;
2933 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2934 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2935 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2936 /* Fixes "TV-blue-bug" on 315+301 */
2937 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2938 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2939 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2940 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2941 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2942 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2943 tempah = 0x30; tempah2 = 0xc0;
2944 tempbl = 0xcf; tempbl2 = 0x3f;
2945 if(SiS_Pr->SiS_TVBlue == 0) {
2946 tempah = tempah2 = 0x00;
2947 } else if(SiS_Pr->SiS_TVBlue == -1) {
2948 /* Set on 651/M650, clear on 315/650 */
2949 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2950 tempah = tempah2 = 0x00;
2953 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2954 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2955 } else {
2956 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2957 tempbl = 0xcf; tempbl2 = 0x3f;
2958 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2959 tempah = tempah2 = 0x00;
2960 if(SiS_IsDualEdge(SiS_Pr)) {
2961 tempbl = tempbl2 = 0xff;
2964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2965 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2968 if(IS_SIS740) {
2969 tempah = 0x80;
2970 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2971 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2972 } else {
2973 tempah = 0x00;
2974 tempbl = 0x7f;
2975 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2976 tempbl = 0xff;
2977 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2979 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2982 #endif /* CONFIG_FB_SIS_315 */
2984 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2986 #ifdef CONFIG_FB_SIS_300
2987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2989 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2990 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2991 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2992 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2993 } else {
2994 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2996 #endif
3000 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3001 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
3002 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3003 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3007 } else { /* LVDS */
3009 #ifdef CONFIG_FB_SIS_315
3010 if(SiS_Pr->ChipType >= SIS_315H) {
3012 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3014 tempah = 0x04;
3015 tempbl = 0xfb;
3016 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3017 tempah = 0x00;
3018 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3020 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3022 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3023 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3026 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3028 } else if(SiS_Pr->ChipType == SIS_550) {
3030 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3031 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3036 #endif
3042 /*********************************************/
3043 /* GET RESOLUTION DATA */
3044 /*********************************************/
3046 unsigned short
3047 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3049 if(ModeNo <= 0x13)
3050 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3051 else
3052 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3055 static void
3056 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3058 unsigned short xres, yres, modeflag=0, resindex;
3060 if(SiS_Pr->UseCustomMode) {
3061 xres = SiS_Pr->CHDisplay;
3062 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3063 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3064 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3065 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3066 return;
3069 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3071 if(ModeNo <= 0x13) {
3072 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3073 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3074 } else {
3075 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3076 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3077 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3080 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3082 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3083 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3084 if(yres == 350) yres = 400;
3086 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3087 if(ModeNo == 0x12) yres = 400;
3091 if(modeflag & HalfDCLK) xres <<= 1;
3092 if(modeflag & DoubleScanMode) yres <<= 1;
3096 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3098 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3099 switch(SiS_Pr->SiS_LCDResInfo) {
3100 case Panel_1024x768:
3101 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3102 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3103 if(yres == 350) yres = 357;
3104 if(yres == 400) yres = 420;
3105 if(yres == 480) yres = 525;
3108 break;
3109 case Panel_1280x1024:
3110 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3111 /* BIOS bug - does this regardless of scaling */
3112 if(yres == 400) yres = 405;
3114 if(yres == 350) yres = 360;
3115 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3116 if(yres == 360) yres = 375;
3118 break;
3119 case Panel_1600x1200:
3120 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3121 if(yres == 1024) yres = 1056;
3123 break;
3127 } else {
3129 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3130 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3131 if(xres == 720) xres = 640;
3133 } else if(xres == 720) xres = 640;
3135 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3136 yres = 400;
3137 if(SiS_Pr->ChipType >= SIS_315H) {
3138 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3139 } else {
3140 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3142 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3146 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3147 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3150 /*********************************************/
3151 /* GET CRT2 TIMING DATA */
3152 /*********************************************/
3154 static void
3155 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3156 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3157 unsigned short *ResIndex)
3159 unsigned short tempbx=0, tempal=0, resinfo=0;
3161 if(ModeNo <= 0x13) {
3162 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3163 } else {
3164 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3165 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3168 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3170 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
3172 tempbx = SiS_Pr->SiS_LCDResInfo;
3173 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3175 /* patch index */
3176 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3177 if (resinfo == SIS_RI_1280x800) tempal = 9;
3178 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3179 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3180 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3181 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3182 if (resinfo == SIS_RI_1280x768) tempal = 9;
3185 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3186 /* Pass 1:1 only (center-screen handled outside) */
3187 /* This is never called for the panel's native resolution */
3188 /* since Pass1:1 will not be set in this case */
3189 tempbx = 100;
3190 if(ModeNo >= 0x13) {
3191 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3195 #ifdef CONFIG_FB_SIS_315
3196 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3197 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3198 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3199 tempbx = 200;
3200 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3204 #endif
3206 } else { /* TV */
3208 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3209 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3210 tempbx = 2;
3211 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3212 tempbx = 13;
3213 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3215 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3216 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3217 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3218 else tempbx = 5;
3219 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3220 } else {
3221 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3222 else tempbx = 4;
3223 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3228 tempal &= 0x3F;
3230 if(ModeNo > 0x13) {
3231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3232 switch(resinfo) {
3233 case SIS_RI_720x480:
3234 tempal = 6;
3235 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
3236 break;
3237 case SIS_RI_720x576:
3238 case SIS_RI_768x576:
3239 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3240 tempal = 6;
3241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3242 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
3244 break;
3245 case SIS_RI_800x480:
3246 tempal = 4;
3247 break;
3248 case SIS_RI_512x384:
3249 case SIS_RI_1024x768:
3250 tempal = 7;
3251 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3252 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
3254 break;
3255 case SIS_RI_1280x720:
3256 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3257 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3259 break;
3264 *CRT2Index = tempbx;
3265 *ResIndex = tempal;
3267 } else { /* LVDS, 301B-DH (if running on LCD) */
3269 tempbx = 0;
3270 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3272 tempbx = 90;
3273 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3274 tempbx = 92;
3275 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3276 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3278 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3279 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3281 if(tempbx != 99) {
3282 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3285 } else {
3287 switch(SiS_Pr->SiS_LCDResInfo) {
3288 case Panel_640x480: tempbx = 12; break;
3289 case Panel_320x240_1: tempbx = 10; break;
3290 case Panel_320x240_2:
3291 case Panel_320x240_3: tempbx = 14; break;
3292 case Panel_800x600: tempbx = 16; break;
3293 case Panel_1024x600: tempbx = 18; break;
3294 case Panel_1152x768:
3295 case Panel_1024x768: tempbx = 20; break;
3296 case Panel_1280x768: tempbx = 22; break;
3297 case Panel_1280x1024: tempbx = 24; break;
3298 case Panel_1400x1050: tempbx = 26; break;
3299 case Panel_1600x1200: tempbx = 28; break;
3300 #ifdef CONFIG_FB_SIS_300
3301 case Panel_Barco1366: tempbx = 80; break;
3302 #endif
3305 switch(SiS_Pr->SiS_LCDResInfo) {
3306 case Panel_320x240_1:
3307 case Panel_320x240_2:
3308 case Panel_320x240_3:
3309 case Panel_640x480:
3310 break;
3311 default:
3312 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3315 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3317 #ifdef CONFIG_FB_SIS_300
3318 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3319 tempbx = 82;
3320 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3321 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3322 tempbx = 84;
3323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3325 #endif
3329 (*CRT2Index) = tempbx;
3330 (*ResIndex) = tempal & 0x1F;
3334 static void
3335 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3336 unsigned short RefreshRateTableIndex)
3338 unsigned short tempax=0, tempbx=0, index, dotclock;
3339 unsigned short temp1=0, modeflag=0, tempcx=0;
3341 SiS_Pr->SiS_RVBHCMAX = 1;
3342 SiS_Pr->SiS_RVBHCFACT = 1;
3344 if(ModeNo <= 0x13) {
3346 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3347 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3349 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3350 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3351 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3353 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3355 } else {
3357 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3358 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3360 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3361 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3362 tempax &= 0x03FF;
3363 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3364 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3365 tempcx &= 0x0100;
3366 tempcx <<= 2;
3367 tempbx |= tempcx;
3368 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3370 dotclock = 8;
3374 if(temp1 & 0x01) tempbx |= 0x0100;
3375 if(temp1 & 0x20) tempbx |= 0x0200;
3377 tempax += 5;
3378 tempax *= dotclock;
3379 if(modeflag & HalfDCLK) tempax <<= 1;
3381 tempbx++;
3383 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3384 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3387 static void
3388 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3389 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3391 unsigned short ResIndex;
3393 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3394 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3395 if(SiS_Pr->UseCustomMode) {
3396 ResIndex = SiS_Pr->CHTotal;
3397 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3398 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3399 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3400 } else {
3401 if(ModeNo < 0x13) {
3402 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3403 } else {
3404 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3406 if(ResIndex == 0x09) {
3407 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3408 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3410 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3411 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3412 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3413 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3415 } else {
3416 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3417 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3419 } else {
3420 /* This handles custom modes and custom panels */
3421 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3422 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3423 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3424 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3425 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3426 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3430 static void
3431 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3432 unsigned short RefreshRateTableIndex)
3434 unsigned short CRT2Index, ResIndex, backup;
3435 const struct SiS_LVDSData *LVDSData = NULL;
3437 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3439 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3440 SiS_Pr->SiS_RVBHCMAX = 1;
3441 SiS_Pr->SiS_RVBHCFACT = 1;
3442 SiS_Pr->SiS_NewFlickerMode = 0;
3443 SiS_Pr->SiS_RVBHRS = 50;
3444 SiS_Pr->SiS_RY1COE = 0;
3445 SiS_Pr->SiS_RY2COE = 0;
3446 SiS_Pr->SiS_RY3COE = 0;
3447 SiS_Pr->SiS_RY4COE = 0;
3448 SiS_Pr->SiS_RVBHRS2 = 0;
3451 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3453 #ifdef CONFIG_FB_SIS_315
3454 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3455 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3456 #endif
3458 } else {
3460 /* 301BDH needs LVDS Data */
3461 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3462 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3463 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3466 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3467 &CRT2Index, &ResIndex);
3469 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3471 switch(CRT2Index) {
3472 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3473 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3474 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3475 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3476 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3477 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3478 #ifdef CONFIG_FB_SIS_300
3479 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3480 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3481 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3482 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3483 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3484 #endif
3485 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3486 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3487 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3488 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3489 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3490 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3491 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3492 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3493 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3496 if(LVDSData) {
3497 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3498 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3499 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3500 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3501 } else {
3502 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3505 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3506 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3507 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3508 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3509 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3510 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3511 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3512 #ifdef CONFIG_FB_SIS_300
3513 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3514 if(ResIndex < 0x08) {
3515 SiS_Pr->SiS_HDE = 1280;
3516 SiS_Pr->SiS_VDE = 1024;
3519 #endif
3525 static void
3526 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3527 unsigned short RefreshRateTableIndex)
3529 unsigned char *ROMAddr = NULL;
3530 unsigned short tempax, tempbx, modeflag, romptr=0;
3531 unsigned short resinfo, CRT2Index, ResIndex;
3532 const struct SiS_LCDData *LCDPtr = NULL;
3533 const struct SiS_TVData *TVPtr = NULL;
3534 #ifdef CONFIG_FB_SIS_315
3535 short resinfo661;
3536 #endif
3538 if(ModeNo <= 0x13) {
3539 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3540 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3541 } else if(SiS_Pr->UseCustomMode) {
3542 modeflag = SiS_Pr->CModeFlag;
3543 resinfo = 0;
3544 } else {
3545 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3546 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3547 #ifdef CONFIG_FB_SIS_315
3548 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3549 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3550 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3551 (resinfo661 >= 0) &&
3552 (SiS_Pr->SiS_NeedRomModeData) ) {
3553 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3554 if((romptr = (SISGETROMW(21)))) {
3555 romptr += (resinfo661 * 10);
3556 ROMAddr = SiS_Pr->VirtualRomBase;
3560 #endif
3563 SiS_Pr->SiS_NewFlickerMode = 0;
3564 SiS_Pr->SiS_RVBHRS = 50;
3565 SiS_Pr->SiS_RY1COE = 0;
3566 SiS_Pr->SiS_RY2COE = 0;
3567 SiS_Pr->SiS_RY3COE = 0;
3568 SiS_Pr->SiS_RY4COE = 0;
3569 SiS_Pr->SiS_RVBHRS2 = 0;
3571 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3573 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3575 if(SiS_Pr->UseCustomMode) {
3577 SiS_Pr->SiS_RVBHCMAX = 1;
3578 SiS_Pr->SiS_RVBHCFACT = 1;
3579 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3580 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3582 tempax = SiS_Pr->CHTotal;
3583 if(modeflag & HalfDCLK) tempax <<= 1;
3584 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3585 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3587 } else {
3589 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3593 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3595 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3596 &CRT2Index,&ResIndex);
3598 switch(CRT2Index) {
3599 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3600 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3601 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3602 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3603 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3604 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3605 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3606 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3607 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3608 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3609 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3610 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3611 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3612 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3615 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3616 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3617 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3618 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3619 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3620 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3621 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3622 if(modeflag & HalfDCLK) {
3623 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3624 if(SiS_Pr->SiS_RVBHRS2) {
3625 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3626 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3627 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3628 else SiS_Pr->SiS_RVBHRS2 += tempax;
3630 } else {
3631 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3633 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3635 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3637 if((resinfo == SIS_RI_960x600) ||
3638 (resinfo == SIS_RI_1024x768) ||
3639 (resinfo == SIS_RI_1280x1024) ||
3640 (resinfo == SIS_RI_1280x720)) {
3641 SiS_Pr->SiS_NewFlickerMode = 0x40;
3644 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3646 SiS_Pr->SiS_HT = ExtHiTVHT;
3647 SiS_Pr->SiS_VT = ExtHiTVVT;
3648 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3649 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3650 SiS_Pr->SiS_HT = StHiTVHT;
3651 SiS_Pr->SiS_VT = StHiTVVT;
3655 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3657 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3658 SiS_Pr->SiS_HT = 1650;
3659 SiS_Pr->SiS_VT = 750;
3660 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3661 SiS_Pr->SiS_HT = NTSCHT;
3662 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3663 SiS_Pr->SiS_VT = NTSCVT;
3664 } else {
3665 SiS_Pr->SiS_HT = NTSCHT;
3666 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3667 SiS_Pr->SiS_VT = NTSCVT;
3670 } else {
3672 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3673 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3674 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3675 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3677 if(modeflag & HalfDCLK) {
3678 SiS_Pr->SiS_RY1COE = 0x00;
3679 SiS_Pr->SiS_RY2COE = 0xf4;
3680 SiS_Pr->SiS_RY3COE = 0x10;
3681 SiS_Pr->SiS_RY4COE = 0x38;
3684 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3685 SiS_Pr->SiS_HT = NTSCHT;
3686 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3687 SiS_Pr->SiS_VT = NTSCVT;
3688 } else {
3689 SiS_Pr->SiS_HT = PALHT;
3690 SiS_Pr->SiS_VT = PALVT;
3695 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3697 SiS_Pr->SiS_RVBHCMAX = 1;
3698 SiS_Pr->SiS_RVBHCFACT = 1;
3700 if(SiS_Pr->UseCustomMode) {
3702 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3703 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3705 tempax = SiS_Pr->CHTotal;
3706 if(modeflag & HalfDCLK) tempax <<= 1;
3707 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3708 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3710 } else {
3712 bool gotit = false;
3714 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3716 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3717 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3718 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3719 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3720 gotit = true;
3722 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3724 #ifdef CONFIG_FB_SIS_315
3725 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3726 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3727 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3728 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3729 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3730 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3731 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3732 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3733 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3734 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3735 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3736 else SiS_Pr->SiS_RVBHRS2 += tempax;
3738 if(SiS_Pr->SiS_VGAHT) gotit = true;
3739 else {
3740 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3741 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3742 SiS_Pr->SiS_RVBHCMAX = 1;
3743 SiS_Pr->SiS_RVBHCFACT = 1;
3744 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3745 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3746 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3747 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3748 SiS_Pr->SiS_RVBHRS2 = 0;
3749 gotit = true;
3751 #endif
3755 if(!gotit) {
3757 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3758 &CRT2Index,&ResIndex);
3760 switch(CRT2Index) {
3761 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3762 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3763 case Panel_1280x720 :
3764 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3765 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3766 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3767 case Panel_1280x800 :
3768 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3769 case Panel_1280x800_2 :
3770 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3771 case Panel_1280x854 :
3772 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3773 case Panel_1280x960 :
3774 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3775 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3776 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3777 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3778 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3779 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3780 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3781 case Panel_1680x1050 :
3782 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3783 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3784 #ifdef CONFIG_FB_SIS_315
3785 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3786 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3787 #endif
3788 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3791 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3792 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3793 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3794 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3795 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3796 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3800 tempax = SiS_Pr->PanelXRes;
3801 tempbx = SiS_Pr->PanelYRes;
3803 switch(SiS_Pr->SiS_LCDResInfo) {
3804 case Panel_1024x768:
3805 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3806 if(SiS_Pr->ChipType < SIS_315H) {
3807 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3808 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3810 } else {
3811 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3812 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3813 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3814 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3815 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3816 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3818 break;
3819 case Panel_1280x960:
3820 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3821 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3822 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3823 break;
3824 case Panel_1280x1024:
3825 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3826 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3827 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3828 break;
3829 case Panel_1600x1200:
3830 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3831 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3832 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3834 break;
3837 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3838 tempax = SiS_Pr->SiS_VGAHDE;
3839 tempbx = SiS_Pr->SiS_VGAVDE;
3842 SiS_Pr->SiS_HDE = tempax;
3843 SiS_Pr->SiS_VDE = tempbx;
3848 static void
3849 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3850 unsigned short RefreshRateTableIndex)
3853 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3856 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3857 } else {
3858 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3859 /* Need LVDS Data for LCD on 301B-DH */
3860 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3861 } else {
3862 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3866 } else {
3868 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3873 /*********************************************/
3874 /* GET LVDS DES (SKEW) DATA */
3875 /*********************************************/
3877 static const struct SiS_LVDSDes *
3878 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3880 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3882 #ifdef CONFIG_FB_SIS_300
3883 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3885 if(SiS_Pr->ChipType < SIS_315H) {
3886 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3887 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3888 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3889 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3890 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3892 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3893 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3894 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3895 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3901 #endif
3902 return PanelDesPtr;
3905 static void
3906 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3907 unsigned short RefreshRateTableIndex)
3909 unsigned short modeflag, ResIndex;
3910 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3912 SiS_Pr->SiS_LCDHDES = 0;
3913 SiS_Pr->SiS_LCDVDES = 0;
3915 /* Some special cases */
3916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3918 /* Trumpion */
3919 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3920 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3921 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3922 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3925 return;
3928 /* 640x480 on LVDS */
3929 if(SiS_Pr->ChipType < SIS_315H) {
3930 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3931 SiS_Pr->SiS_LCDHDES = 8;
3932 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3933 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3934 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3935 return;
3939 } /* LCD */
3941 if( (SiS_Pr->UseCustomMode) ||
3942 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3943 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3944 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3945 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3946 return;
3949 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3950 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3952 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3954 #ifdef CONFIG_FB_SIS_315
3955 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3956 /* non-pass 1:1 only, see above */
3957 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3958 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3960 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3961 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3964 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3965 switch(SiS_Pr->SiS_CustomT) {
3966 case CUT_UNIWILL1024:
3967 case CUT_UNIWILL10242:
3968 case CUT_CLEVO1400:
3969 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3970 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3972 break;
3974 switch(SiS_Pr->SiS_LCDResInfo) {
3975 case Panel_1280x1024:
3976 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3977 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3979 break;
3980 case Panel_1280x800: /* Verified for Averatec 6240 */
3981 case Panel_1280x800_2: /* Verified for Asus A4L */
3982 case Panel_1280x854: /* Not verified yet FIXME */
3983 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3984 break;
3987 #endif
3989 } else {
3991 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3993 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3994 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3997 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3999 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
4000 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
4002 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4004 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4005 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4007 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4008 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4009 } else {
4010 if(SiS_Pr->ChipType < SIS_315H) {
4011 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4012 } else {
4013 switch(SiS_Pr->SiS_LCDResInfo) {
4014 case Panel_800x600:
4015 case Panel_1024x768:
4016 case Panel_1280x1024:
4017 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4018 break;
4019 case Panel_1400x1050:
4020 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4021 break;
4026 } else {
4028 if(SiS_Pr->ChipType < SIS_315H) {
4029 #ifdef CONFIG_FB_SIS_300
4030 switch(SiS_Pr->SiS_LCDResInfo) {
4031 case Panel_800x600:
4032 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4033 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4034 } else {
4035 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4036 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4037 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4038 else SiS_Pr->SiS_LCDVDES -= 4;
4040 break;
4041 case Panel_1024x768:
4042 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4043 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4044 } else {
4045 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4046 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4047 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4049 break;
4050 case Panel_1024x600:
4051 default:
4052 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4053 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4054 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4055 } else {
4056 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4058 break;
4061 switch(SiS_Pr->SiS_LCDTypeInfo) {
4062 case 1:
4063 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4064 break;
4065 case 3: /* 640x480 only? */
4066 SiS_Pr->SiS_LCDHDES = 8;
4067 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4068 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4069 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4070 break;
4072 #endif
4073 } else {
4074 #ifdef CONFIG_FB_SIS_315
4075 switch(SiS_Pr->SiS_LCDResInfo) {
4076 case Panel_1024x768:
4077 case Panel_1280x1024:
4078 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4079 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4081 break;
4082 case Panel_320x240_1:
4083 case Panel_320x240_2:
4084 case Panel_320x240_3:
4085 SiS_Pr->SiS_LCDVDES = 524;
4086 break;
4088 #endif
4092 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4093 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4094 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4095 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4096 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4097 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4098 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4099 if(SiS_Pr->ChipType < SIS_315H) {
4100 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4101 } else {
4102 #ifdef CONFIG_FB_SIS_315
4103 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
4104 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4105 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4106 if(!(modeflag & HalfDCLK)) {
4107 SiS_Pr->SiS_LCDHDES = 320;
4108 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4109 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4111 #endif
4120 /*********************************************/
4121 /* DISABLE VIDEO BRIDGE */
4122 /*********************************************/
4124 #ifdef CONFIG_FB_SIS_315
4125 static int
4126 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4128 int ret = 0;
4129 #ifdef SET_PWD
4130 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4131 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4132 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4133 unsigned short temp;
4135 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4136 (romptr) &&
4137 (SiS_Pr->SiS_PWDOffset) ) {
4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4140 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4141 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4142 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4143 temp = 0x00;
4144 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4145 temp = 0x80;
4146 ret = 1;
4148 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4150 #endif
4151 return ret;
4153 #endif
4155 /* NEVER use any variables (VBInfo), this will be called
4156 * from outside the context of modeswitch!
4157 * MUST call getVBType before calling this
4159 void
4160 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4162 #ifdef CONFIG_FB_SIS_315
4163 unsigned short tempah, pushax=0, modenum;
4164 #endif
4165 unsigned short temp=0;
4167 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4169 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
4171 if(SiS_Pr->ChipType < SIS_315H) {
4173 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4175 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4176 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4177 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4178 } else {
4179 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4181 SiS_PanelDelay(SiS_Pr, 3);
4183 if(SiS_Is301B(SiS_Pr)) {
4184 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4185 SiS_ShortDelay(SiS_Pr,1);
4187 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4188 SiS_DisplayOff(SiS_Pr);
4189 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4190 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4191 SiS_UnLockCRT2(SiS_Pr);
4192 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4193 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4194 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4196 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4197 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4198 SiS_PanelDelay(SiS_Pr, 2);
4199 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4200 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4201 } else {
4202 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4206 #endif /* CONFIG_FB_SIS_300 */
4208 } else {
4210 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4212 int didpwd = 0;
4213 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4214 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4216 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4218 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4220 #ifdef SET_EMI
4221 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4222 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4223 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4226 #endif
4228 didpwd = SiS_HandlePWD(SiS_Pr);
4230 if( (modenum <= 0x13) ||
4231 (SiS_IsVAMode(SiS_Pr)) ||
4232 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4233 if(!didpwd) {
4234 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4235 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4236 } else {
4237 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4241 if(!custom1) {
4242 SiS_DDC2Delay(SiS_Pr,0xff00);
4243 SiS_DDC2Delay(SiS_Pr,0xe000);
4244 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4245 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4246 if(IS_SIS740) {
4247 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4249 SiS_PanelDelay(SiS_Pr, 3);
4254 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4255 /* if(SiS_Pr->ChipType < SIS_340) {*/
4256 tempah = 0xef;
4257 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4258 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4259 /*}*/
4262 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4263 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4266 tempah = 0x3f;
4267 if(SiS_IsDualEdge(SiS_Pr)) {
4268 tempah = 0x7f;
4269 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4271 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4273 if((SiS_IsVAMode(SiS_Pr)) ||
4274 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4276 SiS_DisplayOff(SiS_Pr);
4277 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4278 SiS_PanelDelay(SiS_Pr, 2);
4280 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4281 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4285 if((!(SiS_IsVAMode(SiS_Pr))) ||
4286 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4288 if(!(SiS_IsDualEdge(SiS_Pr))) {
4289 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4290 SiS_DisplayOff(SiS_Pr);
4292 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4294 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4295 SiS_PanelDelay(SiS_Pr, 2);
4298 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4299 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4300 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4301 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4302 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4306 if(SiS_IsNotM650orLater(SiS_Pr)) {
4307 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4310 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4312 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4313 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4314 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4316 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4317 if(!didpwd) {
4318 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4320 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4323 if(!custom1) {
4324 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4325 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4326 if(SiS_IsVAorLCD(SiS_Pr)) {
4327 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4334 #endif /* CONFIG_FB_SIS_315 */
4338 } else { /* ============ For 301 ================ */
4340 if(SiS_Pr->ChipType < SIS_315H) {
4341 #ifdef CONFIG_FB_SIS_300
4342 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4343 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4344 SiS_PanelDelay(SiS_Pr, 3);
4346 #endif
4349 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4350 SiS_DisplayOff(SiS_Pr);
4352 if(SiS_Pr->ChipType >= SIS_315H) {
4353 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4356 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4358 if(SiS_Pr->ChipType >= SIS_315H) {
4359 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4360 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4361 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4362 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4363 } else {
4364 #ifdef CONFIG_FB_SIS_300
4365 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4366 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4367 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4368 SiS_PanelDelay(SiS_Pr, 2);
4369 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4371 #endif
4376 } else { /* ============ For LVDS =============*/
4378 if(SiS_Pr->ChipType < SIS_315H) {
4380 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4382 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4383 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4386 if(SiS_Pr->ChipType == SIS_730) {
4387 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4388 SiS_WaitVBRetrace(SiS_Pr);
4390 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4391 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4392 SiS_PanelDelay(SiS_Pr, 3);
4394 } else {
4395 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4396 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4397 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4398 SiS_WaitVBRetrace(SiS_Pr);
4399 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4400 SiS_DisplayOff(SiS_Pr);
4402 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4403 SiS_PanelDelay(SiS_Pr, 3);
4409 SiS_DisplayOff(SiS_Pr);
4411 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4413 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4414 SiS_UnLockCRT2(SiS_Pr);
4415 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4416 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4418 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4419 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4420 SiS_PanelDelay(SiS_Pr, 2);
4421 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4424 #endif /* CONFIG_FB_SIS_300 */
4426 } else {
4428 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4430 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4431 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4432 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4433 /* } */
4436 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4438 if(SiS_Pr->ChipType == SIS_740) {
4439 temp = SiS_GetCH701x(SiS_Pr,0x61);
4440 if(temp < 1) {
4441 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4442 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4445 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4446 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4447 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4451 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4452 (SiS_IsVAMode(SiS_Pr)) ) {
4453 SiS_Chrontel701xBLOff(SiS_Pr);
4454 SiS_Chrontel701xOff(SiS_Pr);
4457 if(SiS_Pr->ChipType != SIS_740) {
4458 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4459 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4460 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4466 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4467 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4468 SiS_PanelDelay(SiS_Pr, 3);
4471 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4472 (!(SiS_IsDualEdge(SiS_Pr))) ||
4473 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4474 SiS_DisplayOff(SiS_Pr);
4477 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4478 (!(SiS_IsDualEdge(SiS_Pr))) ||
4479 (!(SiS_IsVAMode(SiS_Pr))) ) {
4480 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4483 if(SiS_Pr->ChipType == SIS_740) {
4484 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4487 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4489 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4490 (!(SiS_IsDualEdge(SiS_Pr))) ||
4491 (!(SiS_IsVAMode(SiS_Pr))) ) {
4492 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4495 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4496 if(SiS_CRT2IsLCD(SiS_Pr)) {
4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4498 if(SiS_Pr->ChipType == SIS_550) {
4499 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4500 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4503 } else {
4504 if(SiS_Pr->ChipType == SIS_740) {
4505 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4506 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4508 } else if(SiS_IsVAMode(SiS_Pr)) {
4509 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4513 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4514 if(SiS_IsDualEdge(SiS_Pr)) {
4515 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4516 } else {
4517 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4521 SiS_UnLockCRT2(SiS_Pr);
4523 if(SiS_Pr->ChipType == SIS_550) {
4524 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4525 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4526 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4527 (!(SiS_IsDualEdge(SiS_Pr))) ||
4528 (!(SiS_IsVAMode(SiS_Pr))) ) {
4529 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4532 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4533 if(SiS_CRT2IsLCD(SiS_Pr)) {
4534 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4535 SiS_PanelDelay(SiS_Pr, 2);
4536 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4541 #endif /* CONFIG_FB_SIS_315 */
4543 } /* 315 series */
4545 } /* LVDS */
4549 /*********************************************/
4550 /* ENABLE VIDEO BRIDGE */
4551 /*********************************************/
4553 /* NEVER use any variables (VBInfo), this will be called
4554 * from outside the context of a mode switch!
4555 * MUST call getVBType before calling this
4557 static
4558 void
4559 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4561 unsigned short temp=0, tempah;
4562 #ifdef CONFIG_FB_SIS_315
4563 unsigned short temp1, pushax=0;
4564 bool delaylong = false;
4565 #endif
4567 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4569 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4571 if(SiS_Pr->ChipType < SIS_315H) {
4573 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4575 if(SiS_CRT2IsLCD(SiS_Pr)) {
4576 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4577 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4578 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4579 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4581 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4582 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4583 SiS_PanelDelay(SiS_Pr, 0);
4588 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4589 (SiS_CRT2IsLCD(SiS_Pr))) {
4591 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4592 SiS_DisplayOn(SiS_Pr);
4593 SiS_UnLockCRT2(SiS_Pr);
4594 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4595 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4596 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4597 } else {
4598 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4600 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4601 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4602 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4603 SiS_PanelDelay(SiS_Pr, 1);
4605 SiS_WaitVBRetrace(SiS_Pr);
4606 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4610 } else {
4612 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4613 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4614 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4615 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4617 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4618 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4619 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4620 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4621 SiS_DisplayOn(SiS_Pr);
4622 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4623 if(SiS_CRT2IsLCD(SiS_Pr)) {
4624 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4625 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4626 SiS_PanelDelay(SiS_Pr, 1);
4628 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4636 #endif /* CONFIG_FB_SIS_300 */
4638 } else {
4640 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4642 #ifdef SET_EMI
4643 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4644 int didpwd = 0;
4645 /* unsigned short emidelay=0; */
4646 #endif
4648 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4650 #ifdef SET_EMI
4651 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4652 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4654 #endif
4657 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4658 /*if(SiS_Pr->ChipType < SIS_340) { */
4659 tempah = 0x10;
4660 if(SiS_LCDAEnabled(SiS_Pr)) {
4661 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4662 else tempah = 0x08;
4664 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4665 /*}*/
4668 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4670 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4671 SiS_DisplayOff(SiS_Pr);
4672 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4673 if(IS_SIS740) {
4674 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4677 didpwd = SiS_HandlePWD(SiS_Pr);
4679 if(SiS_IsVAorLCD(SiS_Pr)) {
4680 if(!didpwd) {
4681 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4682 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4683 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4684 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4685 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4686 SiS_GenericDelay(SiS_Pr, 17664);
4689 } else {
4690 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4691 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4692 SiS_GenericDelay(SiS_Pr, 17664);
4697 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4698 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4699 delaylong = true;
4704 if(!(SiS_IsVAMode(SiS_Pr))) {
4706 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4707 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4708 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4709 if(!(tempah & SetCRT2ToRAMDAC)) {
4710 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4713 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4715 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4717 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4718 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4720 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4721 SiS_PanelDelay(SiS_Pr, 2);
4724 } else {
4726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4730 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4733 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4734 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4735 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4736 /* Enable "LVDS PLL power on" (even on 301C) */
4737 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4738 /* Enable "LVDS Driver Power on" (even on 301C) */
4739 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4743 tempah = 0xc0;
4744 if(SiS_IsDualEdge(SiS_Pr)) {
4745 tempah = 0x80;
4746 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4748 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4750 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4752 SiS_PanelDelay(SiS_Pr, 2);
4754 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4755 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4757 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4758 #ifdef SET_EMI
4759 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4760 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4761 SiS_GenericDelay(SiS_Pr, 2048);
4763 #endif
4764 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4766 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4767 #ifdef SET_EMI
4768 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4770 if(SiS_Pr->SiS_ROMNew) {
4771 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4772 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4773 if(romptr) {
4774 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4775 SiS_Pr->EMI_30 = 0;
4776 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4777 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4778 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4779 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4780 /* emidelay = SISGETROMW((romptr + 0x22)); */
4781 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4785 /* (P4_30|0x40) */
4786 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4787 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4788 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4789 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4790 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4791 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4792 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4793 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4794 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4796 if(SiS_Pr->HaveEMI) {
4797 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4798 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4799 } else {
4800 r30 = 0;
4803 /* EMI_30 is read at driver start; however, the BIOS sets this
4804 * (if it is used) only if the LCD is in use. In case we caught
4805 * the machine while on TV output, this bit is not set and we
4806 * don't know if it should be set - hence our detection is wrong.
4807 * Work-around this here:
4810 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4811 switch((cr36 & 0x0f)) {
4812 case 2:
4813 r30 |= 0x40;
4814 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4815 if(!SiS_Pr->HaveEMI) {
4816 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4817 if((cr36 & 0xf0) == 0x30) {
4818 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4821 break;
4822 case 3: /* 1280x1024 */
4823 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4824 if(!SiS_Pr->HaveEMI) {
4825 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4826 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4827 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4830 break;
4831 case 9: /* 1400x1050 */
4832 r30 |= 0x40;
4833 if(!SiS_Pr->HaveEMI) {
4834 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4835 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4836 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4839 break;
4840 case 11: /* 1600x1200 - unknown */
4841 r30 |= 0x40;
4842 if(!SiS_Pr->HaveEMI) {
4843 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4848 /* BIOS values don't work so well sometimes */
4849 if(!SiS_Pr->OverruleEMI) {
4850 #ifdef COMPAL_HACK
4851 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4852 if((cr36 & 0x0f) == 0x09) {
4853 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4856 #endif
4857 #ifdef COMPAQ_HACK
4858 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4859 if((cr36 & 0x0f) == 0x03) {
4860 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4863 #endif
4864 #ifdef ASUS_HACK
4865 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4866 if((cr36 & 0x0f) == 0x02) {
4867 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4868 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4869 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4870 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4873 #endif
4876 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4877 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4878 SiS_GenericDelay(SiS_Pr, 2048);
4880 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4881 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4882 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4883 #endif /* SET_EMI */
4885 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4887 #ifdef SET_EMI
4888 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4889 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4890 if(r30 & 0x40) {
4891 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4892 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4893 if(delaylong) {
4894 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4895 delaylong = false;
4897 SiS_WaitVBRetrace(SiS_Pr);
4898 SiS_WaitVBRetrace(SiS_Pr);
4899 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4900 SiS_GenericDelay(SiS_Pr, 1280);
4902 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4903 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4906 #endif
4910 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4911 if(SiS_IsVAorLCD(SiS_Pr)) {
4912 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4913 if(delaylong) {
4914 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4916 SiS_WaitVBRetrace(SiS_Pr);
4917 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4918 SiS_GenericDelay(SiS_Pr, 2048);
4919 SiS_WaitVBRetrace(SiS_Pr);
4921 if(!didpwd) {
4922 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4923 } else {
4924 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4929 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4930 SiS_DisplayOn(SiS_Pr);
4931 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4935 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4936 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4939 #endif /* CONFIG_FB_SIS_315 */
4943 } else { /* ============ For 301 ================ */
4945 if(SiS_Pr->ChipType < SIS_315H) {
4946 if(SiS_CRT2IsLCD(SiS_Pr)) {
4947 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4948 SiS_PanelDelay(SiS_Pr, 0);
4952 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4953 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4954 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4955 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4957 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4959 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4961 if(SiS_Pr->ChipType >= SIS_315H) {
4962 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4963 if(!(temp & 0x80)) {
4964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4968 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4970 SiS_VBLongWait(SiS_Pr);
4971 SiS_DisplayOn(SiS_Pr);
4972 if(SiS_Pr->ChipType >= SIS_315H) {
4973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4975 SiS_VBLongWait(SiS_Pr);
4977 if(SiS_Pr->ChipType < SIS_315H) {
4978 if(SiS_CRT2IsLCD(SiS_Pr)) {
4979 SiS_PanelDelay(SiS_Pr, 1);
4980 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4986 } else { /* =================== For LVDS ================== */
4988 if(SiS_Pr->ChipType < SIS_315H) {
4990 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4992 if(SiS_CRT2IsLCD(SiS_Pr)) {
4993 if(SiS_Pr->ChipType == SIS_730) {
4994 SiS_PanelDelay(SiS_Pr, 1);
4995 SiS_PanelDelay(SiS_Pr, 1);
4996 SiS_PanelDelay(SiS_Pr, 1);
4998 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4999 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
5000 SiS_PanelDelay(SiS_Pr, 0);
5004 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5005 SiS_DisplayOn(SiS_Pr);
5006 SiS_UnLockCRT2(SiS_Pr);
5007 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5008 if(SiS_BridgeInSlavemode(SiS_Pr)) {
5009 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5010 } else {
5011 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5014 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5015 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5016 SiS_WaitVBRetrace(SiS_Pr);
5017 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5021 if(SiS_CRT2IsLCD(SiS_Pr)) {
5022 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5023 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5024 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5025 SiS_PanelDelay(SiS_Pr, 1);
5026 SiS_PanelDelay(SiS_Pr, 1);
5028 SiS_WaitVBRetrace(SiS_Pr);
5029 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5034 #endif /* CONFIG_FB_SIS_300 */
5036 } else {
5038 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5040 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5041 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
5042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5043 /*}*/
5046 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5047 if(SiS_CRT2IsLCD(SiS_Pr)) {
5048 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5049 SiS_PanelDelay(SiS_Pr, 0);
5053 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5054 SiS_UnLockCRT2(SiS_Pr);
5056 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5058 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5059 temp = SiS_GetCH701x(SiS_Pr,0x66);
5060 temp &= 0x20;
5061 SiS_Chrontel701xBLOff(SiS_Pr);
5064 if(SiS_Pr->ChipType != SIS_550) {
5065 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5068 if(SiS_Pr->ChipType == SIS_740) {
5069 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5070 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5071 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5076 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5077 if(!(temp1 & 0x80)) {
5078 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5081 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5082 if(temp) {
5083 SiS_Chrontel701xBLOn(SiS_Pr);
5087 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5088 if(SiS_CRT2IsLCD(SiS_Pr)) {
5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5090 if(SiS_Pr->ChipType == SIS_550) {
5091 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5092 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5095 } else if(SiS_IsVAMode(SiS_Pr)) {
5096 if(SiS_Pr->ChipType != SIS_740) {
5097 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5101 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5102 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5105 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5106 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5107 SiS_Chrontel701xOn(SiS_Pr);
5109 if( (SiS_IsVAMode(SiS_Pr)) ||
5110 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5111 SiS_ChrontelDoSomething1(SiS_Pr);
5115 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5116 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5117 if( (SiS_IsVAMode(SiS_Pr)) ||
5118 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5119 SiS_Chrontel701xBLOn(SiS_Pr);
5120 SiS_ChrontelInitTVVSync(SiS_Pr);
5123 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5124 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5125 if(SiS_CRT2IsLCD(SiS_Pr)) {
5126 SiS_PanelDelay(SiS_Pr, 1);
5127 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5132 #endif /* CONFIG_FB_SIS_315 */
5134 } /* 310 series */
5136 } /* LVDS */
5140 /*********************************************/
5141 /* SET PART 1 REGISTER GROUP */
5142 /*********************************************/
5144 /* Set CRT2 OFFSET / PITCH */
5145 static void
5146 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5147 unsigned short RRTI)
5149 unsigned short offset;
5150 unsigned char temp;
5152 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5154 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5156 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5157 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5159 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5160 if(offset & 0x07) temp++;
5161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5164 /* Set CRT2 sync and PanelLink mode */
5165 static void
5166 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5168 unsigned short tempah=0, tempbl, infoflag;
5170 tempbl = 0xC0;
5172 if(SiS_Pr->UseCustomMode) {
5173 infoflag = SiS_Pr->CInfoFlag;
5174 } else {
5175 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5178 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
5180 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5181 tempah = 0;
5182 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5183 tempah = SiS_Pr->SiS_LCDInfo;
5184 } else tempah = infoflag >> 8;
5185 tempah &= 0xC0;
5186 tempah |= 0x20;
5187 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5188 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5189 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5190 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5191 tempah |= 0xf0;
5193 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5194 (SiS_Pr->SiS_IF_DEF_DSTN) ||
5195 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5196 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5197 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5198 tempah |= 0x30;
5200 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5201 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5202 tempah &= ~0xc0;
5205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5206 if(SiS_Pr->ChipType >= SIS_315H) {
5207 tempah >>= 3;
5208 tempah &= 0x18;
5209 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5210 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5211 } else {
5212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5214 } else {
5215 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5218 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5220 if(SiS_Pr->ChipType < SIS_315H) {
5222 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
5224 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
5226 tempah = infoflag >> 8;
5227 tempbl = 0;
5228 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5229 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5230 tempah = SiS_Pr->SiS_LCDInfo;
5231 tempbl = (tempah >> 6) & 0x03;
5234 tempah &= 0xC0;
5235 tempah |= 0x20;
5236 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5237 tempah |= 0xc0;
5238 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5239 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5243 } else { /* 630 - 301 */
5245 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5246 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5251 #endif /* CONFIG_FB_SIS_300 */
5253 } else {
5255 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
5257 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5259 tempbl = 0;
5260 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5261 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5262 tempah = infoflag >> 8;
5263 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5264 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5266 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5267 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5268 tempah = infoflag >> 8;
5269 tempbl = 0x03;
5270 } else {
5271 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5272 tempbl = (tempah >> 6) & 0x03;
5273 tempbl |= 0x08;
5274 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5276 tempah &= 0xC0;
5277 tempah |= 0x20;
5278 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5281 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5282 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5283 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5287 } else { /* 315 - TMDS */
5289 tempah = tempbl = infoflag >> 8;
5290 if(!SiS_Pr->UseCustomMode) {
5291 tempbl = 0;
5292 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5293 if(ModeNo <= 0x13) {
5294 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5297 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5298 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5299 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5300 tempah = SiS_Pr->SiS_LCDInfo;
5301 tempbl = (tempah >> 6) & 0x03;
5306 tempah &= 0xC0;
5307 tempah |= 0x20;
5308 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5309 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5310 /* Imitate BIOS bug */
5311 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5313 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5314 tempah >>= 3;
5315 tempah &= 0x18;
5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5317 } else {
5318 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5319 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5321 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5327 #endif /* CONFIG_FB_SIS_315 */
5332 /* Set CRT2 FIFO on 300/540/630/730 */
5333 #ifdef CONFIG_FB_SIS_300
5334 static void
5335 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5337 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5338 unsigned short temp, index, modeidindex, refreshratetableindex;
5339 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5340 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5341 unsigned int data, pci50, pciA0;
5342 static const unsigned char colortharray[] = {
5343 1, 1, 2, 2, 3, 4
5346 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5348 if(!SiS_Pr->CRT1UsesCustomMode) {
5350 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5351 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5352 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5353 SiS_Pr->SiS_SelectCRT2Rate = 0;
5354 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5356 if(CRT1ModeNo >= 0x13) {
5357 /* Get VCLK */
5358 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5359 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5361 /* Get colordepth */
5362 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5363 if(!colorth) colorth++;
5366 } else {
5368 CRT1ModeNo = 0xfe;
5370 /* Get VCLK */
5371 VCLK = SiS_Pr->CSRClock_CRT1;
5373 /* Get color depth */
5374 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5378 if(CRT1ModeNo >= 0x13) {
5379 /* Get MCLK */
5380 if(SiS_Pr->ChipType == SIS_300) {
5381 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5382 } else {
5383 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5385 index &= 0x07;
5386 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5388 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5389 if(!temp) temp++;
5390 temp <<= 2;
5392 data2 = temp - ((colorth * VCLK) / MCLK);
5394 temp = (28 * 16) % data2;
5395 data2 = (28 * 16) / data2;
5396 if(temp) data2++;
5398 if(SiS_Pr->ChipType == SIS_300) {
5400 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5401 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5403 } else {
5405 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5406 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5408 if(SiS_Pr->ChipType == SIS_730) {
5410 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5411 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5413 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5414 index = 0; /* -- do it like the BIOS anyway... */
5416 } else {
5418 pci50 >>= 24;
5419 pciA0 >>= 24;
5421 index = (pci50 >> 1) & 0x07;
5423 if(pci50 & 0x01) index += 6;
5424 if(!(pciA0 & 0x01)) index += 24;
5426 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5430 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5431 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5435 data += data2; /* CRT1 Request Period */
5437 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5438 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5440 if(!SiS_Pr->UseCustomMode) {
5442 CRT2ModeNo = ModeNo;
5443 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5445 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5447 /* Get VCLK */
5448 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5449 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5451 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5452 if(SiS_Pr->SiS_UseROM) {
5453 if(ROMAddr[0x220] & 0x01) {
5454 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5459 } else {
5461 /* Get VCLK */
5462 CRT2ModeNo = 0xfe;
5463 VCLK = SiS_Pr->CSRClock;
5467 /* Get colordepth */
5468 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5469 if(!colorth) colorth++;
5471 data = data * VCLK * colorth;
5472 temp = data % (MCLK << 4);
5473 data = data / (MCLK << 4);
5474 if(temp) data++;
5476 if(data < 6) data = 6;
5477 else if(data > 0x14) data = 0x14;
5479 if(SiS_Pr->ChipType == SIS_300) {
5480 temp = 0x16;
5481 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5482 temp = 0x13;
5483 } else {
5484 temp = 0x16;
5485 if(( (SiS_Pr->ChipType == SIS_630) ||
5486 (SiS_Pr->ChipType == SIS_730) ) &&
5487 (SiS_Pr->ChipRevision >= 0x30))
5488 temp = 0x1b;
5490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5492 if((SiS_Pr->ChipType == SIS_630) &&
5493 (SiS_Pr->ChipRevision >= 0x30)) {
5494 if(data > 0x13) data = 0x13;
5496 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5498 } else { /* If mode <= 0x13, we just restore everything */
5500 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5501 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5505 #endif
5507 /* Set CRT2 FIFO on 315/330 series */
5508 #ifdef CONFIG_FB_SIS_315
5509 static void
5510 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5512 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5513 if( (SiS_Pr->ChipType == SIS_760) &&
5514 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5515 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5516 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5517 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5522 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5523 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5524 } else {
5525 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5529 #endif
5531 static unsigned short
5532 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5534 unsigned int tempax,tempbx;
5536 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5537 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5538 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5539 return (unsigned short)tempax;
5542 /* Set Part 1 / SiS bridge slave mode */
5543 static void
5544 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5545 unsigned short RefreshRateTableIndex)
5547 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5548 static const unsigned short CRTranslation[] = {
5549 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5550 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5551 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5552 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5553 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5554 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5557 if(ModeNo <= 0x13) {
5558 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5559 } else if(SiS_Pr->UseCustomMode) {
5560 modeflag = SiS_Pr->CModeFlag;
5561 xres = SiS_Pr->CHDisplay;
5562 } else {
5563 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5564 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5567 /* The following is only done if bridge is in slave mode: */
5569 if(SiS_Pr->ChipType >= SIS_315H) {
5570 if(xres >= 1600) { /* BIOS: == 1600 */
5571 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5575 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5577 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5578 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5580 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5582 SiS_Pr->CHBlankStart += 16;
5585 SiS_Pr->CHBlankEnd = 32;
5586 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5587 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5590 temp = SiS_Pr->SiS_VGAHT - 96;
5591 if(!(modeflag & HalfDCLK)) temp -= 32;
5592 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5593 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5594 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5595 temp -= 3;
5596 temp <<= 3;
5597 } else {
5598 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5600 SiS_Pr->CHSyncStart = temp;
5602 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5604 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5606 VGAVDE = SiS_Pr->SiS_VGAVDE;
5607 if (VGAVDE == 357) VGAVDE = 350;
5608 else if(VGAVDE == 360) VGAVDE = 350;
5609 else if(VGAVDE == 375) VGAVDE = 350;
5610 else if(VGAVDE == 405) VGAVDE = 400;
5611 else if(VGAVDE == 420) VGAVDE = 400;
5612 else if(VGAVDE == 525) VGAVDE = 480;
5613 else if(VGAVDE == 1056) VGAVDE = 1024;
5614 SiS_Pr->CVDisplay = VGAVDE;
5616 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5618 SiS_Pr->CVBlankEnd = 1;
5619 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5621 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5622 SiS_Pr->CVSyncStart = VGAVDE + temp;
5624 temp >>= 3;
5625 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5627 SiS_CalcCRRegisters(SiS_Pr, 0);
5628 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5630 for(i = 0; i <= 7; i++) {
5631 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5633 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5634 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5636 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5637 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5639 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5640 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5643 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5644 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5646 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5647 if(modeflag & DoubleScanMode) temp |= 0x80;
5648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5650 temp = 0;
5651 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5652 if(modeflag & HalfDCLK) temp |= 0x08;
5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5655 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5656 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5658 temp = 0;
5659 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5660 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5664 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5665 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5668 /* Setup panel link
5669 * This is used for LVDS, LCDA and Chrontel TV output
5670 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5672 static void
5673 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5674 unsigned short RefreshRateTableIndex)
5676 unsigned short modeflag, resinfo = 0;
5677 unsigned short push2, tempax, tempbx, tempcx, temp;
5678 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5679 bool islvds = false, issis = false, chkdclkfirst = false;
5680 #ifdef CONFIG_FB_SIS_300
5681 unsigned short crt2crtc = 0;
5682 #endif
5683 #ifdef CONFIG_FB_SIS_315
5684 unsigned short pushcx;
5685 #endif
5687 if(ModeNo <= 0x13) {
5688 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5689 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5690 #ifdef CONFIG_FB_SIS_300
5691 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5692 #endif
5693 } else if(SiS_Pr->UseCustomMode) {
5694 modeflag = SiS_Pr->CModeFlag;
5695 } else {
5696 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5697 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5698 #ifdef CONFIG_FB_SIS_300
5699 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5700 #endif
5703 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5704 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5705 islvds = true;
5708 /* is really sis if sis bridge, but not 301B-DH */
5709 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5710 issis = true;
5713 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5714 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5715 chkdclkfirst = true;
5719 #ifdef CONFIG_FB_SIS_315
5720 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5721 if(IS_SIS330) {
5722 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5723 } else if(IS_SIS740) {
5724 if(islvds) {
5725 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5727 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5728 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5730 } else {
5731 if(islvds) {
5732 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5733 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5734 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5735 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5736 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5737 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5738 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5739 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5745 #endif
5747 /* Horizontal */
5749 tempax = SiS_Pr->SiS_LCDHDES;
5750 if(islvds) {
5751 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5752 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5753 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5754 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5755 tempax -= 8;
5761 temp = (tempax & 0x0007);
5762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5763 temp = (tempax >> 3) & 0x00FF;
5764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5766 tempbx = SiS_Pr->SiS_HDE;
5767 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5768 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5769 tempbx = SiS_Pr->PanelXRes;
5771 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5772 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5773 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5774 tempbx >>= 1;
5778 tempax += tempbx;
5779 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5781 temp = tempax;
5782 if(temp & 0x07) temp += 8;
5783 temp >>= 3;
5784 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5786 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5788 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5789 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5790 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5794 tempcx += tempax;
5795 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5797 temp = (tempcx >> 3) & 0x00FF;
5798 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5799 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5800 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5801 switch(ModeNo) {
5802 case 0x04:
5803 case 0x05:
5804 case 0x0d: temp = 0x56; break;
5805 case 0x10: temp = 0x60; break;
5806 case 0x13: temp = 0x5f; break;
5807 case 0x40:
5808 case 0x41:
5809 case 0x4f:
5810 case 0x43:
5811 case 0x44:
5812 case 0x62:
5813 case 0x56:
5814 case 0x53:
5815 case 0x5d:
5816 case 0x5e: temp = 0x54; break;
5821 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5823 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5824 temp += 2;
5825 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5826 temp += 8;
5827 if(SiS_Pr->PanelHRE != 999) {
5828 temp = tempcx + SiS_Pr->PanelHRE;
5829 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5830 temp >>= 3;
5833 } else {
5834 temp += 10;
5837 temp &= 0x1F;
5838 temp |= ((tempcx & 0x07) << 5);
5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5841 /* Vertical */
5843 tempax = SiS_Pr->SiS_VGAVDE;
5844 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5845 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5846 tempax = SiS_Pr->PanelYRes;
5850 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5851 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5853 push2 = tempbx;
5855 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5856 if(SiS_Pr->ChipType < SIS_315H) {
5857 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5858 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5859 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5863 if(islvds) tempcx >>= 1;
5864 else tempcx >>= 2;
5866 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5867 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5868 (SiS_Pr->PanelVRS != 999) ) {
5869 tempcx = SiS_Pr->PanelVRS;
5870 tempbx += tempcx;
5871 if(issis) tempbx++;
5872 } else {
5873 tempbx += tempcx;
5874 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5875 else if(issis) tempbx++;
5878 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5880 temp = tempbx & 0x00FF;
5881 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5882 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5883 if(ModeNo == 0x10) temp = 0xa9;
5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5888 tempcx >>= 3;
5889 tempcx++;
5891 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5892 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5893 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5897 tempcx += tempbx;
5898 temp = tempcx & 0x000F;
5899 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5901 temp = ((tempbx >> 8) & 0x07) << 3;
5902 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5903 if(SiS_Pr->SiS_HDE != 640) {
5904 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5906 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5907 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5908 tempbx = 0x87;
5909 if((SiS_Pr->ChipType >= SIS_315H) ||
5910 (SiS_Pr->ChipRevision >= 0x30)) {
5911 tempbx = 0x07;
5912 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5913 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5915 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5916 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5918 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5919 } else {
5920 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5924 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5926 tempbx = push2; /* BPLVDEE */
5928 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5930 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5931 switch(SiS_Pr->SiS_LCDResInfo) {
5932 case Panel_640x480:
5933 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5934 tempcx = SiS_Pr->SiS_VGAVDE;
5935 break;
5936 case Panel_800x600:
5937 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5938 if(resinfo == SIS_RI_800x600) tempcx++;
5940 break;
5941 case Panel_1024x600:
5942 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5943 if(resinfo == SIS_RI_1024x600) tempcx++;
5944 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5945 if(resinfo == SIS_RI_800x600) tempcx++;
5948 break;
5949 case Panel_1024x768:
5950 if(SiS_Pr->ChipType < SIS_315H) {
5951 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5952 if(resinfo == SIS_RI_1024x768) tempcx++;
5955 break;
5959 temp = ((tempbx >> 8) & 0x07) << 3;
5960 temp |= ((tempcx >> 8) & 0x07);
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5962 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5963 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5965 /* Vertical scaling */
5967 if(SiS_Pr->ChipType < SIS_315H) {
5969 #ifdef CONFIG_FB_SIS_300 /* 300 series */
5970 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5971 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5972 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5973 if(temp) tempeax++;
5975 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5977 temp = (unsigned short)(tempeax & 0x00FF);
5978 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5979 tempvcfact = temp;
5980 #endif /* CONFIG_FB_SIS_300 */
5982 } else {
5984 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5985 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5986 tempebx = SiS_Pr->SiS_VDE;
5987 temp = (tempeax % tempebx);
5988 tempeax = tempeax / tempebx;
5989 if(temp) tempeax++;
5990 tempvcfact = tempeax;
5992 temp = (unsigned short)(tempeax & 0x00FF);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5994 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5996 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5997 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
6000 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
6001 temp = (unsigned short)(tempeax & 0x00FF);
6002 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6003 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6004 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6005 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6006 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6007 temp = 0;
6008 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6009 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6011 #endif
6015 /* Horizontal scaling */
6017 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6018 if(chkdclkfirst) {
6019 if(modeflag & HalfDCLK) tempeax >>= 1;
6021 tempebx = tempeax << 16;
6022 if(SiS_Pr->SiS_HDE == tempeax) {
6023 tempecx = 0xFFFF;
6024 } else {
6025 tempecx = tempebx / SiS_Pr->SiS_HDE;
6026 if(SiS_Pr->ChipType >= SIS_315H) {
6027 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6031 if(SiS_Pr->ChipType >= SIS_315H) {
6032 tempeax = (tempebx / tempecx) - 1;
6033 } else {
6034 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6036 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6037 temp = (unsigned short)(tempecx & 0x00FF);
6038 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6040 if(SiS_Pr->ChipType >= SIS_315H) {
6041 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6042 tempbx = (unsigned short)(tempeax & 0xFFFF);
6043 } else {
6044 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6045 tempbx = tempvcfact & 0x3f;
6046 if(tempbx == 0) tempbx = 64;
6047 tempeax /= tempbx;
6048 tempbx = (unsigned short)(tempeax & 0xFFFF);
6050 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6051 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6052 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6053 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6056 temp = ((tempbx >> 8) & 0x07) << 3;
6057 temp = temp | ((tempecx >> 8) & 0x07);
6058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6059 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6061 tempecx >>= 16; /* BPLHCFACT */
6062 if(!chkdclkfirst) {
6063 if(modeflag & HalfDCLK) tempecx >>= 1;
6065 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6067 temp = (unsigned short)(tempecx & 0x00FF);
6068 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6070 #ifdef CONFIG_FB_SIS_315
6071 if(SiS_Pr->ChipType >= SIS_315H) {
6072 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6073 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6074 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6076 } else {
6077 if(islvds) {
6078 if(SiS_Pr->ChipType == SIS_740) {
6079 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6080 } else {
6081 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6086 #endif
6088 #ifdef CONFIG_FB_SIS_300
6089 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6090 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6091 unsigned char *trumpdata;
6092 int i, j = crt2crtc;
6093 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6094 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6095 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6097 if(SiS_Pr->SiS_UseROM) {
6098 trumpdata = &ROMAddr[0x8001 + (j * 80)];
6099 } else {
6100 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6101 trumpdata = &SiS300_TrumpionData[j][0];
6104 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6105 for(i=0; i<5; i++) {
6106 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6108 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6109 if(ModeNo == 0x13) {
6110 for(i=0; i<4; i++) {
6111 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6113 } else if(ModeNo == 0x10) {
6114 for(i=0; i<4; i++) {
6115 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6116 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6120 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6122 #endif
6124 #ifdef CONFIG_FB_SIS_315
6125 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6130 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6132 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6133 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6134 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6135 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6136 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6137 tempax += 64;
6138 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6139 temp = (tempax >> 8) << 3;
6140 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6141 tempax += 32; /* Blpe = lBlps+32 */
6142 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
6144 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6146 tempax = SiS_Pr->SiS_VDE;
6147 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6148 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6149 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6150 tempax >>= 1;
6151 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6152 temp = (tempax >> 8) << 3;
6153 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6155 tempeax = SiS_Pr->SiS_HDE;
6156 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6157 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6158 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6159 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6160 temp = tempeax & 0x7f;
6161 tempeax >>= 7;
6162 if(temp) tempeax++;
6163 temp = tempeax & 0x3f;
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6166 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6167 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6168 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6170 tempax = SiS_Pr->SiS_HDE;
6171 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6172 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6173 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6174 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6175 pushcx = tempax;
6176 temp = tempax & 0x00FF;
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6178 temp = ((tempax & 0xFF00) >> 8) << 3;
6179 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6181 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6182 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6183 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6184 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6185 tempeax = tempax * pushcx;
6186 temp = tempeax & 0xFF;
6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6188 temp = (tempeax & 0xFF00) >> 8;
6189 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6190 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6191 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6192 temp = ((tempeax & 0x01000000) >> 24) << 7;
6193 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6198 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6199 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6201 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6220 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6221 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6224 #endif /* CONFIG_FB_SIS_315 */
6227 /* Set Part 1 */
6228 static void
6229 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6230 unsigned short RefreshRateTableIndex)
6232 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6233 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6234 #endif
6235 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6236 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6237 #ifdef CONFIG_FB_SIS_315
6238 unsigned short tempbl=0;
6239 #endif
6241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6242 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6243 return;
6246 if(ModeNo <= 0x13) {
6247 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6248 } else if(SiS_Pr->UseCustomMode) {
6249 modeflag = SiS_Pr->CModeFlag;
6250 } else {
6251 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6252 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6253 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6256 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6258 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6259 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6260 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6262 if(SiS_Pr->ChipType < SIS_315H ) {
6263 #ifdef CONFIG_FB_SIS_300
6264 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6265 #endif
6266 } else {
6267 #ifdef CONFIG_FB_SIS_315
6268 SiS_SetCRT2FIFO_310(SiS_Pr);
6269 #endif
6272 /* 1. Horizontal setup */
6274 if(SiS_Pr->ChipType < SIS_315H ) {
6276 #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
6278 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6281 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6284 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6285 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6287 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6288 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6289 tempbx = pushbx + tempcx;
6290 tempcx <<= 1;
6291 tempcx += tempbx;
6293 bridgeadd = 12;
6295 #endif /* CONFIG_FB_SIS_300 */
6297 } else {
6299 #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
6301 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6302 if(modeflag & HalfDCLK) {
6303 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6304 tempcx >>= 1;
6305 } else {
6306 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6307 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6308 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6309 tempcx = SiS_Pr->SiS_HT - tempax;
6313 tempcx--;
6314 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6315 temp = (tempcx >> 4) & 0xF0;
6316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6318 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6319 tempbx = SiS_Pr->SiS_VGAHDE;
6320 tempcx -= tempbx;
6321 tempcx >>= 2;
6322 if(modeflag & HalfDCLK) {
6323 tempbx >>= 1;
6324 tempcx >>= 1;
6326 tempbx += 16;
6328 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6330 pushbx = tempbx;
6331 tempcx >>= 1;
6332 tempbx += tempcx;
6333 tempcx += tempbx;
6335 bridgeadd = 16;
6337 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6338 if(SiS_Pr->ChipType >= SIS_661) {
6339 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6340 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6341 if(resinfo == SIS_RI_1280x1024) {
6342 tempcx = (tempcx & 0xff00) | 0x30;
6343 } else if(resinfo == SIS_RI_1600x1200) {
6344 tempcx = (tempcx & 0xff00) | 0xff;
6350 #endif /* CONFIG_FB_SIS_315 */
6352 } /* 315/330 series */
6354 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6356 if(SiS_Pr->UseCustomMode) {
6357 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6358 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6359 tempax = SiS_Pr->SiS_VGAHT;
6360 if(modeflag & HalfDCLK) tempax >>= 1;
6361 tempax--;
6362 if(tempcx > tempax) tempcx = tempax;
6365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6366 unsigned char cr4, cr14, cr5, cr15;
6367 if(SiS_Pr->UseCustomMode) {
6368 cr4 = SiS_Pr->CCRT1CRTC[4];
6369 cr14 = SiS_Pr->CCRT1CRTC[14];
6370 cr5 = SiS_Pr->CCRT1CRTC[5];
6371 cr15 = SiS_Pr->CCRT1CRTC[15];
6372 } else {
6373 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6374 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6375 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6376 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6378 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6379 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6380 tempcx &= 0x00FF;
6381 tempcx |= (tempbx & 0xFF00);
6382 tempbx += bridgeadd;
6383 tempcx += bridgeadd;
6384 tempax = SiS_Pr->SiS_VGAHT;
6385 if(modeflag & HalfDCLK) tempax >>= 1;
6386 tempax--;
6387 if(tempcx > tempax) tempcx = tempax;
6390 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6391 tempbx = 1040;
6392 tempcx = 1044; /* HWCursor bug! */
6397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6399 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6401 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6402 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6404 /* 2. Vertical setup */
6406 tempcx = SiS_Pr->SiS_VGAVT - 1;
6407 temp = tempcx & 0x00FF;
6409 if(SiS_Pr->ChipType < SIS_661) {
6410 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6411 if(SiS_Pr->ChipType < SIS_315H) {
6412 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6413 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6414 temp--;
6417 } else {
6418 temp--;
6420 } else if(SiS_Pr->ChipType >= SIS_315H) {
6421 temp--;
6424 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6426 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6427 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6429 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6430 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6432 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6433 tempbx++;
6434 tempax = tempbx;
6435 tempcx++;
6436 tempcx -= tempax;
6437 tempcx >>= 2;
6438 tempbx += tempcx;
6439 if(tempcx < 4) tempcx = 4;
6440 tempcx >>= 2;
6441 tempcx += tempbx;
6442 tempcx++;
6443 } else {
6444 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6445 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6448 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6449 if(SiS_Pr->UseCustomMode) {
6450 tempbx = SiS_Pr->CVSyncStart;
6451 tempcx = SiS_Pr->CVSyncEnd;
6453 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6454 unsigned char cr8, cr7, cr13;
6455 if(SiS_Pr->UseCustomMode) {
6456 cr8 = SiS_Pr->CCRT1CRTC[8];
6457 cr7 = SiS_Pr->CCRT1CRTC[7];
6458 cr13 = SiS_Pr->CCRT1CRTC[13];
6459 tempcx = SiS_Pr->CCRT1CRTC[9];
6460 } else {
6461 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6462 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6463 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6464 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6466 tempbx = cr8;
6467 if(cr7 & 0x04) tempbx |= 0x0100;
6468 if(cr7 & 0x80) tempbx |= 0x0200;
6469 if(cr13 & 0x08) tempbx |= 0x0400;
6472 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6474 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6475 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6477 /* 3. Panel delay compensation */
6479 if(SiS_Pr->ChipType < SIS_315H) {
6481 #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6483 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6484 temp = 0x20;
6485 if(SiS_Pr->ChipType == SIS_300) {
6486 temp = 0x10;
6487 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6488 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6490 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6491 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6493 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6494 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6495 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6496 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6497 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6498 else temp = 0x20;
6500 if(SiS_Pr->SiS_UseROM) {
6501 if(ROMAddr[0x220] & 0x80) {
6502 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6503 temp = ROMAddr[0x221];
6504 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6505 temp = ROMAddr[0x222];
6506 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6507 temp = ROMAddr[0x223];
6508 else
6509 temp = ROMAddr[0x224];
6512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6513 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6516 } else {
6517 temp = 0x20;
6518 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6519 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6521 if(SiS_Pr->SiS_UseROM) {
6522 if(ROMAddr[0x220] & 0x80) {
6523 temp = ROMAddr[0x220];
6526 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6527 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6531 temp &= 0x3c;
6533 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6535 #endif /* CONFIG_FB_SIS_300 */
6537 } else {
6539 #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6541 if(SiS_Pr->ChipType < SIS_661) {
6543 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6545 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6546 else temp = 0x00;
6548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6549 tempbl = 0xF0;
6550 if(SiS_Pr->ChipType == SIS_650) {
6551 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6552 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6556 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6557 temp = 0x08;
6558 tempbl = 0;
6559 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6560 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6564 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6567 } /* < 661 */
6569 tempax = 0;
6570 if(modeflag & DoubleScanMode) tempax |= 0x80;
6571 if(modeflag & HalfDCLK) tempax |= 0x40;
6572 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6574 #endif /* CONFIG_FB_SIS_315 */
6578 } /* Slavemode */
6580 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6581 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6582 /* For 301BDH with LCD, we set up the Panel Link */
6583 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6584 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6585 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6587 } else {
6588 if(SiS_Pr->ChipType < SIS_315H) {
6589 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6590 } else {
6591 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6592 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6593 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6595 } else {
6596 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6602 /*********************************************/
6603 /* SET PART 2 REGISTER GROUP */
6604 /*********************************************/
6606 #ifdef CONFIG_FB_SIS_315
6607 static unsigned char *
6608 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6610 const unsigned char *tableptr = NULL;
6611 unsigned short a, b, p = 0;
6613 a = SiS_Pr->SiS_VGAHDE;
6614 b = SiS_Pr->SiS_HDE;
6615 if(tabletype) {
6616 a = SiS_Pr->SiS_VGAVDE;
6617 b = SiS_Pr->SiS_VDE;
6620 if(a < b) {
6621 tableptr = SiS_Part2CLVX_1;
6622 } else if(a == b) {
6623 tableptr = SiS_Part2CLVX_2;
6624 } else {
6625 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6626 tableptr = SiS_Part2CLVX_4;
6627 } else {
6628 tableptr = SiS_Part2CLVX_3;
6630 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6631 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6632 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6633 else tableptr = SiS_Part2CLVX_5;
6634 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6635 tableptr = SiS_Part2CLVX_6;
6637 do {
6638 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6639 p += 0x42;
6640 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6641 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6643 p += 2;
6644 return ((unsigned char *)&tableptr[p]);
6647 static void
6648 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6649 unsigned short RefreshRateTableIndex)
6651 unsigned char *tableptr;
6652 unsigned char temp;
6653 int i, j;
6655 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6657 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6658 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6659 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6661 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6662 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6663 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6664 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6667 temp = 0x10;
6668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6669 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6672 static bool
6673 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6674 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6675 unsigned short *ResIndex)
6678 if(SiS_Pr->ChipType < SIS_315H) return false;
6680 if(ModeNo <= 0x13)
6681 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6682 else
6683 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6685 (*ResIndex) &= 0x3f;
6686 (*CRT2Index) = 0;
6688 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6689 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6690 (*CRT2Index) = 200;
6694 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6695 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6696 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6699 return (((*CRT2Index) != 0));
6701 #endif
6703 #ifdef CONFIG_FB_SIS_300
6704 static void
6705 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6707 unsigned short tempcx;
6708 static const unsigned char atable[] = {
6709 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6710 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6713 if(!SiS_Pr->UseCustomMode) {
6714 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6715 (SiS_Pr->ChipType == SIS_730) ) &&
6716 (SiS_Pr->ChipRevision > 2) ) &&
6717 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6718 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6719 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6720 if(ModeNo == 0x13) {
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6724 } else if((crt2crtc & 0x3F) == 4) {
6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6728 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6729 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6733 if(SiS_Pr->ChipType < SIS_315H) {
6734 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6735 crt2crtc &= 0x1f;
6736 tempcx = 0;
6737 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6738 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6739 tempcx += 7;
6742 tempcx += crt2crtc;
6743 if(crt2crtc >= 4) {
6744 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6747 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6748 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6749 if(crt2crtc == 4) {
6750 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6754 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6755 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6761 /* For ECS A907. Highly preliminary. */
6762 static void
6763 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6764 unsigned short ModeNo)
6766 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6767 unsigned short crt2crtc, resindex;
6768 int i, j;
6770 if(SiS_Pr->ChipType != SIS_300) return;
6771 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6772 if(SiS_Pr->UseCustomMode) return;
6774 if(ModeNo <= 0x13) {
6775 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6776 } else {
6777 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6780 resindex = crt2crtc & 0x3F;
6781 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6782 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6784 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6785 if(ModeNo > 0x13) {
6786 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6787 resindex = 4;
6790 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6791 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6792 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6793 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6795 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6796 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6798 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6801 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6802 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6804 #endif
6806 static void
6807 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6809 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6810 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6811 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6813 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6814 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6815 static const unsigned char specialtv[] = {
6816 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6817 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6818 0x58,0xe4,0x73,0xda,0x13
6820 int i, j;
6821 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6824 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6825 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6826 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6829 } else {
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6831 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6835 } else {
6836 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6837 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6838 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6840 } else {
6841 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6842 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6847 static void
6848 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6850 unsigned short temp;
6852 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6853 if(SiS_Pr->SiS_VGAVDE == 525) {
6854 temp = 0xc3;
6855 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6856 temp++;
6857 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6859 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6860 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6861 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6862 temp = 0x4d;
6863 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6864 temp++;
6865 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6867 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6871 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6872 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6873 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6874 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6875 /* Not always for LV, see SetGrp2 */
6877 temp = 1;
6878 if(ModeNo <= 0x13) temp = 3;
6879 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6881 #if 0
6882 /* 651+301C, for 1280x768 - do I really need that? */
6883 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6884 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6885 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6886 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6887 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6888 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6889 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6890 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6891 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6892 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6893 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6894 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6895 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6896 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6897 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6898 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6902 #endif
6906 static void
6907 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6908 unsigned short RefreshRateTableIndex)
6910 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6911 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6912 unsigned int longtemp, PhaseIndex;
6913 bool newtvphase;
6914 const unsigned char *TimingPoint;
6915 #ifdef CONFIG_FB_SIS_315
6916 unsigned short resindex, CRT2Index;
6917 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6919 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6920 #endif
6922 if(ModeNo <= 0x13) {
6923 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6924 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6925 } else if(SiS_Pr->UseCustomMode) {
6926 modeflag = SiS_Pr->CModeFlag;
6927 crt2crtc = 0;
6928 } else {
6929 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6930 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6933 temp = 0;
6934 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6935 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6936 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6937 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6939 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6943 PhaseIndex = 0x01; /* SiS_PALPhase */
6944 TimingPoint = SiS_Pr->SiS_PALTiming;
6946 newtvphase = false;
6947 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6948 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6949 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6950 newtvphase = true;
6953 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6955 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6956 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6957 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6958 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6959 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6963 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6965 i = 0;
6966 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6967 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6969 TimingPoint = &SiS_YPbPrTable[i][0];
6971 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6973 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6975 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6977 } else {
6979 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6980 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6981 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6985 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6986 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6987 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6990 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6991 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6992 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6993 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6994 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6995 } else {
6996 PhaseIndex = 0x10; /* SiS_SpecialPhase */
7000 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
7001 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
7004 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7005 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7007 for(i = 0x39; i <= 0x45; i++, j++) {
7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7011 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7012 if(SiS_Pr->SiS_ModeType != ModeText) {
7013 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7017 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7021 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7022 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7024 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7025 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
7026 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7027 else tempax = 440; /* NTSC, YPbPr 525 */
7029 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7030 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7031 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7033 tempax -= SiS_Pr->SiS_VDE;
7034 tempax >>= 1;
7035 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7036 tempax >>= 1;
7038 tempax &= 0x00ff;
7040 temp = tempax + (unsigned short)TimingPoint[0];
7041 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7043 temp = tempax + (unsigned short)TimingPoint[1];
7044 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7046 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7047 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7050 } else {
7051 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7058 tempcx = SiS_Pr->SiS_HT;
7059 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7060 tempcx--;
7061 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7062 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7063 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7065 tempcx = SiS_Pr->SiS_HT >> 1;
7066 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7067 tempcx += 7;
7068 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7069 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7071 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7072 tempbx += tempcx;
7073 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7074 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7076 tempbx += 8;
7077 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7078 tempbx -= 4;
7079 tempcx = tempbx;
7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7083 j += 2;
7084 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7085 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7086 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7088 tempcx += 8;
7089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7090 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7092 tempcx = SiS_Pr->SiS_HT >> 1;
7093 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7094 j += 2;
7095 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7096 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7098 tempcx -= 11;
7099 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7100 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7102 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7104 tempbx = SiS_Pr->SiS_VDE;
7105 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7106 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7107 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7108 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7109 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7110 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7111 tempbx >>= 1;
7112 if(SiS_Pr->ChipType >= SIS_315H) {
7113 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7114 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7115 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7116 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7117 if(crt2crtc == 4) tempbx++;
7121 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7122 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7123 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7125 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7126 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7130 tempbx -= 2;
7131 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7133 temp = (tempcx >> 8) & 0x0F;
7134 temp |= ((tempbx >> 2) & 0xC0);
7135 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7136 temp |= 0x10;
7137 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7141 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7142 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7145 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7146 tempbx = SiS_Pr->SiS_VDE;
7147 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7148 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7149 tempbx >>= 1;
7151 tempbx -= 3;
7152 temp = ((tempbx >> 3) & 0x60) | 0x18;
7153 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7154 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7156 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7157 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7161 tempbx = 0;
7162 if(!(modeflag & HalfDCLK)) {
7163 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7164 tempax = 0;
7165 tempbx |= 0x20;
7169 tempch = tempcl = 0x01;
7170 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7171 if(SiS_Pr->SiS_VGAHDE >= 960) {
7172 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7173 tempcl = 0x20;
7174 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7175 tempch = 20;
7176 tempbx &= ~0x20;
7177 } else {
7178 tempch = 25; /* OK */
7184 if(!(tempbx & 0x20)) {
7185 if(modeflag & HalfDCLK) tempcl <<= 1;
7186 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7187 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7188 tempax = longtemp / SiS_Pr->SiS_HDE;
7189 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7190 tempbx |= ((tempax >> 8) & 0x1F);
7191 tempcx = tempax >> 13;
7194 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7195 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7197 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7199 tempcx &= 0x07;
7200 if(tempbx & 0x20) tempcx = 0;
7201 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7203 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7204 tempbx = 0x0382;
7205 tempcx = 0x007e;
7206 } else {
7207 tempbx = 0x0369;
7208 tempcx = 0x0061;
7210 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7211 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7212 temp = (tempcx & 0x0300) >> 6;
7213 temp |= ((tempbx >> 8) & 0x03);
7214 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7215 temp |= 0x10;
7216 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7217 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7219 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7221 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7222 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7224 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7226 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7227 temp = 0;
7228 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7229 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7234 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7235 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7236 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7237 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7239 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7243 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7244 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7250 /* From here: Part2 LCD setup */
7252 tempbx = SiS_Pr->SiS_HDE;
7253 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7254 tempbx--; /* RHACTE = HDE - 1 */
7255 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7256 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7258 temp = 0x01;
7259 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7260 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7261 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7262 temp = 0x02;
7263 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7264 temp = 0x01;
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7271 tempbx = SiS_Pr->SiS_VDE - 1;
7272 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7273 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7275 tempcx = SiS_Pr->SiS_VT - 1;
7276 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7277 temp = (tempcx >> 3) & 0xE0;
7278 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7279 /* Enable dithering; only do this for 32bpp mode */
7280 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7281 temp |= 0x10;
7284 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7289 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7290 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7292 #ifdef CONFIG_FB_SIS_315
7293 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7294 &CRT2Index, &resindex)) {
7295 switch(CRT2Index) {
7296 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7297 default:
7298 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7301 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7302 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7303 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7304 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7306 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7309 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7312 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7313 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7315 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7317 } else {
7318 #endif
7320 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7321 /* Clevo dual-link 1024x768 */
7322 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7323 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7325 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7326 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7327 tempbx = SiS_Pr->SiS_VDE - 1;
7328 tempcx = SiS_Pr->SiS_VT - 1;
7329 } else {
7330 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7331 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7333 } else {
7334 tempbx = SiS_Pr->PanelYRes;
7335 tempcx = SiS_Pr->SiS_VT;
7336 tempax = 1;
7337 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7338 tempax = SiS_Pr->PanelYRes;
7339 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7340 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7341 tempax = tempcx = 0;
7342 } else {
7343 tempax -= SiS_Pr->SiS_VDE;
7345 tempax >>= 1;
7347 tempcx -= tempax; /* lcdvdes */
7348 tempbx -= tempax; /* lcdvdee */
7351 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7353 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7354 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7356 temp = (tempbx >> 5) & 0x38;
7357 temp |= ((tempcx >> 8) & 0x07);
7358 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7360 tempax = SiS_Pr->SiS_VDE;
7361 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7362 tempax = SiS_Pr->PanelYRes;
7364 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7365 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7366 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7367 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7371 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7372 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7373 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7374 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7375 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7376 if(tempax % 4) { tempax >>= 2; tempax++; }
7377 else { tempax >>= 2; }
7378 tempbx -= (tempax - 1);
7379 } else {
7380 tempbx -= 10;
7381 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7385 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7386 tempbx++;
7387 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7388 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7389 tempbx = 770;
7390 tempcx = 3;
7395 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7397 if(SiS_Pr->UseCustomMode) {
7398 tempbx = SiS_Pr->CVSyncStart;
7401 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7403 temp = (tempbx >> 4) & 0xF0;
7404 tempbx += (tempcx + 1);
7405 temp |= (tempbx & 0x0F);
7407 if(SiS_Pr->UseCustomMode) {
7408 temp &= 0xf0;
7409 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7412 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7414 #ifdef CONFIG_FB_SIS_300
7415 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7416 #endif
7418 bridgeoffset = 7;
7419 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7420 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7421 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7422 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7423 /* Higher bridgeoffset shifts to the LEFT */
7425 temp = 0;
7426 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7427 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7428 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7429 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7432 temp += bridgeoffset;
7433 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7434 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7436 tempcx = SiS_Pr->SiS_HT;
7437 tempax = tempbx = SiS_Pr->SiS_HDE;
7438 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7439 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7440 tempax = SiS_Pr->PanelXRes;
7441 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7444 if(SiS_IsDualLink(SiS_Pr)) {
7445 tempcx >>= 1;
7446 tempbx >>= 1;
7447 tempax >>= 1;
7450 tempbx += bridgeoffset;
7452 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7453 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7455 tempcx = (tempcx - tempax) >> 2;
7457 tempbx += tempcx;
7458 push2 = tempbx;
7460 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7461 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7462 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7463 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7468 if(SiS_Pr->UseCustomMode) {
7469 tempbx = SiS_Pr->CHSyncStart;
7470 if(modeflag & HalfDCLK) tempbx <<= 1;
7471 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7472 tempbx += bridgeoffset;
7475 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7476 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7478 tempbx = push2;
7480 tempcx <<= 1;
7481 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7482 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7484 tempbx += tempcx;
7486 if(SiS_Pr->UseCustomMode) {
7487 tempbx = SiS_Pr->CHSyncEnd;
7488 if(modeflag & HalfDCLK) tempbx <<= 1;
7489 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7490 tempbx += bridgeoffset;
7493 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7495 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7497 #ifdef CONFIG_FB_SIS_300
7498 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7499 #endif
7500 #ifdef CONFIG_FB_SIS_315
7501 } /* CRT2-LCD from table */
7502 #endif
7505 /*********************************************/
7506 /* SET PART 3 REGISTER GROUP */
7507 /*********************************************/
7509 static void
7510 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7512 unsigned short i;
7513 const unsigned char *tempdi;
7515 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7517 #ifndef SIS_CP
7518 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7519 #else
7520 SIS_CP_INIT301_CP
7521 #endif
7523 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7524 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7526 } else {
7527 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7528 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7531 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7532 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7533 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7534 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7537 tempdi = NULL;
7538 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7539 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7540 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7541 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7543 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7544 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7545 tempdi = SiS_HiTVGroup3_1;
7546 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7549 if(tempdi) {
7550 for(i=0; i<=0x3E; i++) {
7551 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7553 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7554 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7555 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7560 #ifdef SIS_CP
7561 SIS_CP_INIT301_CP2
7562 #endif
7565 /*********************************************/
7566 /* SET PART 4 REGISTER GROUP */
7567 /*********************************************/
7569 #ifdef CONFIG_FB_SIS_315
7570 #if 0
7571 static void
7572 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7574 unsigned short temp, temp1, temp2;
7576 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7577 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7578 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7579 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7580 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7581 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7582 temp = (unsigned short)((int)(temp) + shift);
7583 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7584 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7585 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7586 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7587 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7588 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7590 #endif
7592 static void
7593 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7595 unsigned short temp, temp1;
7596 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7598 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7599 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7601 if(SiS_Pr->ChipType >= XGI_20) return;
7603 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7604 if(!(ROMAddr[0x61] & 0x04)) return;
7607 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7608 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7609 if(!(temp & 0x01)) {
7610 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7611 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7612 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7613 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7615 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7616 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7617 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7618 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7619 else temp = 0x0402;
7620 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7621 temp1 = 0;
7622 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7624 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7625 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7626 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7627 if(ModeNo > 0x13) {
7628 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7630 } else {
7631 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7632 if(temp1 == 0x01) temp |= 0x01;
7633 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7634 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7635 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7636 if(ModeNo > 0x13) {
7637 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7641 #if 0
7642 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7643 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7644 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7645 if(resinfo == SIS_RI_1024x768) {
7646 SiS_ShiftXPos(SiS_Pr, 97);
7647 } else {
7648 SiS_ShiftXPos(SiS_Pr, 111);
7650 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7651 SiS_ShiftXPos(SiS_Pr, 136);
7655 #endif
7660 #endif
7662 static void
7663 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7664 unsigned short RefreshRateTableIndex)
7666 unsigned short vclkindex, temp, reg1, reg2;
7668 if(SiS_Pr->UseCustomMode) {
7669 reg1 = SiS_Pr->CSR2B;
7670 reg2 = SiS_Pr->CSR2C;
7671 } else {
7672 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7673 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7674 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7677 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7678 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7682 } else {
7683 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7684 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7686 } else {
7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7692 temp = 0x08;
7693 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7694 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7697 static void
7698 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7700 if(SiS_Pr->ChipType >= SIS_315H) {
7701 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7702 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7703 (SiS_IsVAMode(SiS_Pr))) {
7704 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7705 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7706 } else {
7707 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7712 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7713 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7714 #ifdef SET_EMI
7715 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7716 #endif
7717 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7721 static void
7722 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7723 unsigned short RefreshRateTableIndex)
7725 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7726 unsigned int tempebx, tempeax, templong;
7728 if(ModeNo <= 0x13) {
7729 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7730 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7731 } else if(SiS_Pr->UseCustomMode) {
7732 modeflag = SiS_Pr->CModeFlag;
7733 resinfo = 0;
7734 } else {
7735 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7736 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7739 if(SiS_Pr->ChipType >= SIS_315H) {
7740 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7741 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7742 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7747 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7748 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7749 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7753 if(SiS_Pr->ChipType >= SIS_315H) {
7754 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7755 SiS_SetDualLinkEtc(SiS_Pr);
7756 return;
7760 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7762 tempbx = SiS_Pr->SiS_RVBHCMAX;
7763 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7765 temp = (tempbx >> 1) & 0x80;
7767 tempcx = SiS_Pr->SiS_VGAHT - 1;
7768 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7770 temp |= ((tempcx >> 5) & 0x78);
7772 tempcx = SiS_Pr->SiS_VGAVT - 1;
7773 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7774 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7776 temp |= ((tempcx >> 8) & 0x07);
7777 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7779 tempbx = SiS_Pr->SiS_VGAHDE;
7780 if(modeflag & HalfDCLK) tempbx >>= 1;
7781 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7783 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7784 temp = 0;
7785 if(tempbx > 800) temp = 0x60;
7786 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7787 temp = 0;
7788 if(tempbx > 1024) temp = 0xC0;
7789 else if(tempbx >= 960) temp = 0xA0;
7790 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7791 temp = 0;
7792 if(tempbx >= 1280) temp = 0x40;
7793 else if(tempbx >= 1024) temp = 0x20;
7794 } else {
7795 temp = 0x80;
7796 if(tempbx >= 1024) temp = 0xA0;
7799 temp |= SiS_Pr->Init_P4_0E;
7801 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7802 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7803 temp &= 0xf0;
7804 temp |= 0x0A;
7808 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7810 tempeax = SiS_Pr->SiS_VGAVDE;
7811 tempebx = SiS_Pr->SiS_VDE;
7812 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7813 if(!(temp & 0xE0)) tempebx >>=1;
7816 tempcx = SiS_Pr->SiS_RVBHRS;
7817 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7818 tempcx >>= 8;
7819 tempcx |= 0x40;
7821 if(tempeax <= tempebx) {
7822 tempcx ^= 0x40;
7823 } else {
7824 tempeax -= tempebx;
7827 tempeax *= (256 * 1024);
7828 templong = tempeax % tempebx;
7829 tempeax /= tempebx;
7830 if(templong) tempeax++;
7832 temp = (unsigned short)(tempeax & 0x000000FF);
7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7834 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7835 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7836 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7837 temp |= (tempcx & 0x4F);
7838 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7840 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7842 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7844 /* Calc Linebuffer max address and set/clear decimode */
7845 tempbx = 0;
7846 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7847 tempax = SiS_Pr->SiS_VGAHDE;
7848 if(modeflag & HalfDCLK) tempax >>= 1;
7849 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7850 if(tempax > 800) {
7851 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7852 tempax -= 800;
7853 } else {
7854 tempbx = 0x08;
7855 if(tempax == 960) tempax *= 25; /* Correct */
7856 else if(tempax == 1024) tempax *= 25;
7857 else tempax *= 20;
7858 temp = tempax % 32;
7859 tempax /= 32;
7860 if(temp) tempax++;
7861 tempax++;
7862 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7863 if(resinfo == SIS_RI_1024x768 ||
7864 resinfo == SIS_RI_1024x576 ||
7865 resinfo == SIS_RI_1280x1024 ||
7866 resinfo == SIS_RI_1280x720) {
7867 /* Otherwise white line or garbage at right edge */
7868 tempax = (tempax & 0xff00) | 0x20;
7873 tempax--;
7874 temp = ((tempax >> 4) & 0x30) | tempbx;
7875 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7876 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7878 temp = 0x0036; tempbx = 0xD0;
7879 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7880 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7882 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7883 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7884 temp |= 0x01;
7885 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7886 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7887 temp &= ~0x01;
7892 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7894 tempbx = SiS_Pr->SiS_HT >> 1;
7895 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7896 tempbx -= 2;
7897 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7898 temp = (tempbx >> 5) & 0x38;
7899 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7901 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7902 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7903 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7904 /* LCD-too-dark-error-source, see FinalizeLCD() */
7908 SiS_SetDualLinkEtc(SiS_Pr);
7910 } /* 301B */
7912 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7915 /*********************************************/
7916 /* SET PART 5 REGISTER GROUP */
7917 /*********************************************/
7919 static void
7920 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7925 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7926 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7927 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7928 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7933 /*********************************************/
7934 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7935 /*********************************************/
7937 static bool
7938 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7939 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7940 unsigned short *DisplayType)
7942 unsigned short modeflag = 0;
7943 bool checkhd = true;
7945 /* Pass 1:1 not supported here */
7947 if(ModeNo <= 0x13) {
7948 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7949 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7950 } else {
7951 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7952 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7955 (*ResIndex) &= 0x3F;
7957 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7959 (*DisplayType) = 80;
7960 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7961 (*DisplayType) = 82;
7962 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7963 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7966 if((*DisplayType) != 84) {
7967 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7970 } else {
7972 (*DisplayType = 0);
7973 switch(SiS_Pr->SiS_LCDResInfo) {
7974 case Panel_320x240_1: (*DisplayType) = 50;
7975 checkhd = false;
7976 break;
7977 case Panel_320x240_2: (*DisplayType) = 14;
7978 break;
7979 case Panel_320x240_3: (*DisplayType) = 18;
7980 break;
7981 case Panel_640x480: (*DisplayType) = 10;
7982 break;
7983 case Panel_1024x600: (*DisplayType) = 26;
7984 break;
7985 default: return true;
7988 if(checkhd) {
7989 if(modeflag & HalfDCLK) (*DisplayType)++;
7992 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7993 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7998 return true;
8001 static void
8002 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8003 unsigned short RefreshRateTableIndex)
8005 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8006 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8007 static const unsigned short CRIdx[] = {
8008 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8009 0x07, 0x10, 0x11, 0x15, 0x16
8012 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8013 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8014 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
8015 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8016 return;
8018 if(SiS_Pr->SiS_IF_DEF_LVDS) {
8019 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8020 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8022 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8023 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8024 } else return;
8026 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8028 if(SiS_Pr->ChipType < SIS_315H) {
8029 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8032 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8033 &ResIndex, &DisplayType))) {
8034 return;
8037 switch(DisplayType) {
8038 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
8039 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
8040 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
8041 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
8042 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
8043 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8044 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8045 #if 0 /* Works better with calculated numbers */
8046 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
8047 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
8048 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
8049 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
8050 #endif
8051 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
8052 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
8053 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
8054 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
8055 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8058 if(LVDSCRT1Ptr) {
8060 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8062 for(i = 0; i <= 10; i++) {
8063 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8064 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8067 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8068 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8069 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8072 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8073 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8075 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8076 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8078 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8079 if(modeflag & DoubleScanMode) tempah |= 0x80;
8080 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8082 } else {
8084 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8089 /*********************************************/
8090 /* SET CRT2 ECLK */
8091 /*********************************************/
8093 static void
8094 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8095 unsigned short RefreshRateTableIndex)
8097 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8098 unsigned short clkbase, vclkindex = 0;
8099 unsigned char sr2b, sr2c;
8101 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8102 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8103 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8104 RefreshRateTableIndex--;
8106 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8107 RefreshRateTableIndex);
8108 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8109 } else {
8110 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8111 RefreshRateTableIndex);
8114 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8115 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8117 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8118 if(SiS_Pr->SiS_UseROM) {
8119 if(ROMAddr[0x220] & 0x01) {
8120 sr2b = ROMAddr[0x227];
8121 sr2c = ROMAddr[0x228];
8126 clkbase = 0x02B;
8127 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8128 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8129 clkbase += 3;
8133 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
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,0x10);
8137 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8139 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8140 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8141 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8144 /*********************************************/
8145 /* SET UP CHRONTEL CHIPS */
8146 /*********************************************/
8148 static void
8149 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8150 unsigned short RefreshRateTableIndex)
8152 unsigned short TVType, resindex;
8153 const struct SiS_CHTVRegData *CHTVRegData = NULL;
8155 if(ModeNo <= 0x13)
8156 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8157 else
8158 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8160 resindex &= 0x3F;
8162 TVType = 0;
8163 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8164 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8165 TVType += 2;
8166 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8167 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8169 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8170 TVType = 4;
8171 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8172 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8173 TVType = 6;
8174 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8178 switch(TVType) {
8179 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8180 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8181 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8182 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8183 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8184 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8185 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8186 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8187 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8188 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8192 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8194 #ifdef CONFIG_FB_SIS_300
8196 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8198 /* We don't support modes >800x600 */
8199 if (resindex > 5) return;
8201 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8202 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8203 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8204 } else {
8205 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8206 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8209 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8210 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8211 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8212 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8213 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8215 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8216 minimum text enhancement (S3-2=10),
8217 maximum flicker filter for Chroma channel (S5-4=10)
8218 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8220 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8222 /* Set video bandwidth
8223 High bandwidth Luma composite video filter(S0=1)
8224 low bandwidth Luma S-video filter (S2-1=00)
8225 disable peak filter in S-video channel (S3=0)
8226 high bandwidth Chroma Filter (S5-4=11)
8227 =00110001=0x31
8229 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8231 /* Register 0x3D does not exist in non-macrovision register map
8232 (Maybe this is a macrovision register?)
8234 #ifndef SIS_CP
8235 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8236 #endif
8238 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8239 all other bits a read-only. Macrovision?
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8243 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8244 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8246 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8248 /* Clear DSEN
8250 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8252 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8253 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8254 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8257 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8261 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8264 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8265 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8266 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8267 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8269 } else {
8270 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8271 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8273 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8274 #if 0
8275 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8276 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8280 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8281 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8282 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8283 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8284 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8285 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8286 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8287 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8290 } else { /* ---- PAL ---- */
8291 /* We don't play around with FSCI in PAL mode */
8292 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */
8293 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */
8296 #endif /* 300 */
8298 } else {
8300 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8302 #ifdef CONFIG_FB_SIS_315
8304 unsigned short temp;
8306 /* We don't support modes >1024x768 */
8307 if (resindex > 6) return;
8309 temp = CHTVRegData[resindex].Reg[0];
8310 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8311 SiS_SetCH701x(SiS_Pr,0x00,temp);
8313 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8314 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8315 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8316 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8317 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8318 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8320 temp = CHTVRegData[resindex].Reg[7];
8321 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8322 SiS_SetCH701x(SiS_Pr,0x07,temp);
8324 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8325 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8326 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8327 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8328 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8329 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8330 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8331 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8333 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8334 /* D1 should be set for PAL, PAL-N and NTSC-J,
8335 but I won't do that for PAL unless somebody
8336 tells me to do so. Since the BIOS uses
8337 non-default CIV values and blacklevels,
8338 this might be compensated anyway.
8340 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8341 SiS_SetCH701x(SiS_Pr,0x21,temp);
8343 #endif /* 315 */
8347 #ifdef SIS_CP
8348 SIS_CP_INIT301_CP3
8349 #endif
8353 #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8355 void
8356 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8358 unsigned short temp;
8360 /* Enable Chrontel 7019 LCD panel backlight */
8361 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8362 if(SiS_Pr->ChipType == SIS_740) {
8363 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8364 } else {
8365 temp = SiS_GetCH701x(SiS_Pr,0x66);
8366 temp |= 0x20;
8367 SiS_SetCH701x(SiS_Pr,0x66,temp);
8372 void
8373 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8375 unsigned short temp;
8377 /* Disable Chrontel 7019 LCD panel backlight */
8378 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8379 temp = SiS_GetCH701x(SiS_Pr,0x66);
8380 temp &= 0xDF;
8381 SiS_SetCH701x(SiS_Pr,0x66,temp);
8385 static void
8386 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8388 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8389 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8390 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8391 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8392 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8393 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8394 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8395 const unsigned char *tableptr = NULL;
8396 int i;
8398 /* Set up Power up/down timing */
8400 if(SiS_Pr->ChipType == SIS_740) {
8401 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8402 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8403 else tableptr = table1024_740;
8404 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8405 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8406 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8407 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8408 else tableptr = table1400_740;
8409 } else return;
8410 } else {
8411 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8412 tableptr = table1024_650;
8413 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8414 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8415 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8416 tableptr = table1400_650;
8417 } else return;
8420 for(i=0; i<5; i++) {
8421 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8425 static void
8426 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8428 const unsigned char *tableptr = NULL;
8429 unsigned short tempbh;
8430 int i;
8431 static const unsigned char regtable[] = {
8432 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8433 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8435 static const unsigned char table1024_740[] = {
8436 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8437 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8439 static const unsigned char table1280_740[] = {
8440 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8441 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8443 static const unsigned char table1400_740[] = {
8444 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8445 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8447 static const unsigned char table1600_740[] = {
8448 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8449 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8451 static const unsigned char table1024_650[] = {
8452 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8453 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8455 static const unsigned char table1280_650[] = {
8456 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8457 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8459 static const unsigned char table1400_650[] = {
8460 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8461 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8463 static const unsigned char table1600_650[] = {
8464 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8465 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8468 if(SiS_Pr->ChipType == SIS_740) {
8469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8470 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8471 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8472 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8473 else return;
8474 } else {
8475 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8479 else return;
8482 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8483 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8484 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8485 if(tempbh == 0xc8) {
8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8487 } else if(tempbh == 0xdb) {
8488 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8489 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8490 } else if(tempbh == 0xde) {
8491 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8495 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8496 else tempbh = 0x0c;
8498 for(i = 0; i < tempbh; i++) {
8499 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8501 SiS_ChrontelPowerSequencing(SiS_Pr);
8502 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8503 tempbh |= 0xc0;
8504 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8506 if(SiS_Pr->ChipType == SIS_740) {
8507 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8508 tempbh &= 0xfb;
8509 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8511 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8512 tempbh |= 0x40;
8513 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8514 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8515 tempbh &= 0x3f;
8516 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8520 static void
8521 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8523 unsigned char temp, temp1;
8525 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8526 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8527 temp = SiS_GetCH701x(SiS_Pr,0x47);
8528 temp &= 0x7f; /* Use external VSYNC */
8529 SiS_SetCH701x(SiS_Pr,0x47,temp);
8530 SiS_LongDelay(SiS_Pr, 3);
8531 temp = SiS_GetCH701x(SiS_Pr,0x47);
8532 temp |= 0x80; /* Use internal VSYNC */
8533 SiS_SetCH701x(SiS_Pr,0x47,temp);
8534 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8537 static void
8538 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8540 unsigned short temp;
8542 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8543 if(SiS_Pr->ChipType == SIS_740) {
8544 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8545 temp |= 0x04; /* Invert XCLK phase */
8546 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8548 if(SiS_IsYPbPr(SiS_Pr)) {
8549 temp = SiS_GetCH701x(SiS_Pr,0x01);
8550 temp &= 0x3f;
8551 temp |= 0x80; /* Enable YPrPb (HDTV) */
8552 SiS_SetCH701x(SiS_Pr,0x01,temp);
8554 if(SiS_IsChScart(SiS_Pr)) {
8555 temp = SiS_GetCH701x(SiS_Pr,0x01);
8556 temp &= 0x3f;
8557 temp |= 0xc0; /* Enable SCART + CVBS */
8558 SiS_SetCH701x(SiS_Pr,0x01,temp);
8560 if(SiS_Pr->ChipType == SIS_740) {
8561 SiS_ChrontelResetVSync(SiS_Pr);
8562 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8563 } else {
8564 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8565 temp = SiS_GetCH701x(SiS_Pr,0x49);
8566 if(SiS_IsYPbPr(SiS_Pr)) {
8567 temp = SiS_GetCH701x(SiS_Pr,0x73);
8568 temp |= 0x60;
8569 SiS_SetCH701x(SiS_Pr,0x73,temp);
8571 temp = SiS_GetCH701x(SiS_Pr,0x47);
8572 temp &= 0x7f;
8573 SiS_SetCH701x(SiS_Pr,0x47,temp);
8574 SiS_LongDelay(SiS_Pr, 2);
8575 temp = SiS_GetCH701x(SiS_Pr,0x47);
8576 temp |= 0x80;
8577 SiS_SetCH701x(SiS_Pr,0x47,temp);
8582 static void
8583 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8585 unsigned short temp;
8587 /* Complete power down of LVDS */
8588 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8589 if(SiS_Pr->ChipType == SIS_740) {
8590 SiS_LongDelay(SiS_Pr, 1);
8591 SiS_GenericDelay(SiS_Pr, 5887);
8592 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8593 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8594 } else {
8595 SiS_LongDelay(SiS_Pr, 2);
8596 temp = SiS_GetCH701x(SiS_Pr,0x76);
8597 temp &= 0xfc;
8598 SiS_SetCH701x(SiS_Pr,0x76,temp);
8599 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8604 static void
8605 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8607 unsigned short temp;
8609 if(SiS_Pr->ChipType == SIS_740) {
8611 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8612 temp &= 0x01;
8613 if(!temp) {
8615 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8616 temp = SiS_GetCH701x(SiS_Pr,0x49);
8617 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8620 /* Reset Chrontel 7019 datapath */
8621 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8622 SiS_LongDelay(SiS_Pr, 1);
8623 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8625 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8626 SiS_ChrontelResetVSync(SiS_Pr);
8627 SiS_SetCH701x(SiS_Pr,0x49,temp);
8630 } else {
8632 /* Clear/set/clear GPIO */
8633 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8634 temp &= 0xef;
8635 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8636 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8637 temp |= 0x10;
8638 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8639 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8640 temp &= 0xef;
8641 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8642 temp = SiS_GetCH701x(SiS_Pr,0x61);
8643 if(!temp) {
8644 SiS_SetCH701xForLCD(SiS_Pr);
8648 } else { /* 650 */
8649 /* Reset Chrontel 7019 datapath */
8650 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8651 SiS_LongDelay(SiS_Pr, 1);
8652 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8656 static void
8657 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8659 unsigned short temp;
8661 if(SiS_Pr->ChipType == SIS_740) {
8663 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8664 SiS_ChrontelResetVSync(SiS_Pr);
8667 } else {
8669 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8670 temp = SiS_GetCH701x(SiS_Pr,0x49);
8671 temp &= 1;
8672 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8673 temp = SiS_GetCH701x(SiS_Pr,0x47);
8674 temp &= 0x70;
8675 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8676 SiS_LongDelay(SiS_Pr, 3);
8677 temp = SiS_GetCH701x(SiS_Pr,0x47);
8678 temp |= 0x80;
8679 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8685 static void
8686 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8688 unsigned short temp,temp1;
8690 if(SiS_Pr->ChipType == SIS_740) {
8692 temp = SiS_GetCH701x(SiS_Pr,0x61);
8693 if(temp < 1) {
8694 temp++;
8695 SiS_SetCH701x(SiS_Pr,0x61,temp);
8697 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8698 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8699 SiS_LongDelay(SiS_Pr, 1);
8700 SiS_GenericDelay(SiS_Pr, 5887);
8702 } else { /* 650 */
8704 temp1 = 0;
8705 temp = SiS_GetCH701x(SiS_Pr,0x61);
8706 if(temp < 2) {
8707 temp++;
8708 SiS_SetCH701x(SiS_Pr,0x61,temp);
8709 temp1 = 1;
8711 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8712 temp = SiS_GetCH701x(SiS_Pr,0x66);
8713 temp |= 0x5f;
8714 SiS_SetCH701x(SiS_Pr,0x66,temp);
8715 if(ModeNo > 0x13) {
8716 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8717 SiS_GenericDelay(SiS_Pr, 1023);
8718 } else {
8719 SiS_GenericDelay(SiS_Pr, 767);
8721 } else {
8722 if(!temp1)
8723 SiS_GenericDelay(SiS_Pr, 767);
8725 temp = SiS_GetCH701x(SiS_Pr,0x76);
8726 temp |= 0x03;
8727 SiS_SetCH701x(SiS_Pr,0x76,temp);
8728 temp = SiS_GetCH701x(SiS_Pr,0x66);
8729 temp &= 0x7f;
8730 SiS_SetCH701x(SiS_Pr,0x66,temp);
8731 SiS_LongDelay(SiS_Pr, 1);
8736 static void
8737 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8739 unsigned short temp;
8741 SiS_LongDelay(SiS_Pr, 1);
8743 do {
8744 temp = SiS_GetCH701x(SiS_Pr,0x66);
8745 temp &= 0x04; /* PLL stable? -> bail out */
8746 if(temp == 0x04) break;
8748 if(SiS_Pr->ChipType == SIS_740) {
8749 /* Power down LVDS output, PLL normal operation */
8750 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8753 SiS_SetCH701xForLCD(SiS_Pr);
8755 temp = SiS_GetCH701x(SiS_Pr,0x76);
8756 temp &= 0xfb; /* Reset PLL */
8757 SiS_SetCH701x(SiS_Pr,0x76,temp);
8758 SiS_LongDelay(SiS_Pr, 2);
8759 temp = SiS_GetCH701x(SiS_Pr,0x76);
8760 temp |= 0x04; /* PLL normal operation */
8761 SiS_SetCH701x(SiS_Pr,0x76,temp);
8762 if(SiS_Pr->ChipType == SIS_740) {
8763 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8764 } else {
8765 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8767 SiS_LongDelay(SiS_Pr, 2);
8768 } while(0);
8770 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8773 static void
8774 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8776 unsigned short temp;
8778 temp = SiS_GetCH701x(SiS_Pr,0x03);
8779 temp |= 0x80; /* Set datapath 1 to TV */
8780 temp &= 0xbf; /* Set datapath 2 to LVDS */
8781 SiS_SetCH701x(SiS_Pr,0x03,temp);
8783 if(SiS_Pr->ChipType == SIS_740) {
8785 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8786 temp &= 0xfb; /* Normal XCLK phase */
8787 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8789 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8791 temp = SiS_GetCH701x(SiS_Pr,0x64);
8792 temp |= 0x40; /* ? Bit not defined */
8793 SiS_SetCH701x(SiS_Pr,0x64,temp);
8795 temp = SiS_GetCH701x(SiS_Pr,0x03);
8796 temp &= 0x3f; /* D1 input to both LVDS and TV */
8797 SiS_SetCH701x(SiS_Pr,0x03,temp);
8799 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8800 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8801 SiS_LongDelay(SiS_Pr, 1);
8802 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8803 SiS_ChrontelResetDB(SiS_Pr);
8804 SiS_ChrontelDoSomething2(SiS_Pr);
8805 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8806 } else {
8807 temp = SiS_GetCH701x(SiS_Pr,0x66);
8808 if(temp != 0x45) {
8809 SiS_ChrontelResetDB(SiS_Pr);
8810 SiS_ChrontelDoSomething2(SiS_Pr);
8811 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8815 } else { /* 650 */
8817 SiS_ChrontelResetDB(SiS_Pr);
8818 SiS_ChrontelDoSomething2(SiS_Pr);
8819 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8820 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8821 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8826 #endif /* 315 series */
8828 /*********************************************/
8829 /* MAIN: SET CRT2 REGISTER GROUP */
8830 /*********************************************/
8832 bool
8833 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8835 #ifdef CONFIG_FB_SIS_300
8836 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8837 #endif
8838 unsigned short ModeIdIndex, RefreshRateTableIndex;
8840 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8842 if(!SiS_Pr->UseCustomMode) {
8843 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8844 } else {
8845 ModeIdIndex = 0;
8848 /* Used for shifting CR33 */
8849 SiS_Pr->SiS_SelectCRT2Rate = 4;
8851 SiS_UnLockCRT2(SiS_Pr);
8853 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8855 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8857 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8858 SiS_DisableBridge(SiS_Pr);
8859 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8862 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8865 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8866 SiS_LockCRT2(SiS_Pr);
8867 SiS_DisplayOn(SiS_Pr);
8868 return true;
8871 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8873 /* Set up Panel Link for LVDS and LCDA */
8874 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8875 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8876 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8877 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8878 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8881 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8882 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8885 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8887 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8889 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890 #ifdef CONFIG_FB_SIS_315
8891 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8892 #endif
8893 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8894 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8895 #ifdef CONFIG_FB_SIS_315
8896 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8897 #endif
8898 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8900 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8902 /* For 301BDH (Panel link initialization): */
8903 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8905 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8906 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8907 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8910 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8914 } else {
8916 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8918 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8920 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8922 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8923 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8924 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8925 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8926 #ifdef CONFIG_FB_SIS_315
8927 SiS_SetCH701xForLCD(SiS_Pr);
8928 #endif
8931 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8932 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8939 #ifdef CONFIG_FB_SIS_300
8940 if(SiS_Pr->ChipType < SIS_315H) {
8941 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8942 if(SiS_Pr->SiS_UseOEM) {
8943 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8944 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8945 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8947 } else {
8948 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8951 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8952 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8953 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8954 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8956 SiS_DisplayOn(SiS_Pr);
8960 #endif
8962 #ifdef CONFIG_FB_SIS_315
8963 if(SiS_Pr->ChipType >= SIS_315H) {
8964 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8965 if(SiS_Pr->ChipType < SIS_661) {
8966 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8967 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8968 } else {
8969 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8971 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8974 #endif
8976 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8977 SiS_EnableBridge(SiS_Pr);
8980 SiS_DisplayOn(SiS_Pr);
8982 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8984 /* Disable LCD panel when using TV */
8985 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8986 } else {
8987 /* Disable TV when using LCD */
8988 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8992 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8993 SiS_LockCRT2(SiS_Pr);
8996 return true;
9000 /*********************************************/
9001 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9002 /*********************************************/
9004 void
9005 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9007 /* Switch on LCD backlight on SiS30xLV */
9008 SiS_DDC2Delay(SiS_Pr,0xff00);
9009 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9010 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9011 SiS_WaitVBRetrace(SiS_Pr);
9013 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9014 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9018 void
9019 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9021 /* Switch off LCD backlight on SiS30xLV */
9022 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9023 SiS_DDC2Delay(SiS_Pr,0xff00);
9026 /*********************************************/
9027 /* DDC RELATED FUNCTIONS */
9028 /*********************************************/
9030 static void
9031 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9033 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9034 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9035 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9036 SiS_Pr->SiS_DDC_NData &= 0x0f;
9037 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9041 #ifdef CONFIG_FB_SIS_300
9042 static unsigned char *
9043 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9045 int i, j, num;
9046 unsigned short tempah,temp;
9047 unsigned char *mydataptr;
9049 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9050 mydataptr = dataptr;
9051 num = *mydataptr++;
9052 if(!num) return mydataptr;
9053 if(i) {
9054 SiS_SetStop(SiS_Pr);
9055 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9057 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9058 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9059 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9060 if(temp) continue; /* (ERROR: no ack) */
9061 tempah = *mydataptr++;
9062 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9063 if(temp) continue; /* (ERROR: no ack) */
9064 for(j=0; j<num; j++) {
9065 tempah = *mydataptr++;
9066 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9067 if(temp) break;
9069 if(temp) continue;
9070 if(SiS_SetStop(SiS_Pr)) continue;
9071 return mydataptr;
9073 return NULL;
9076 static bool
9077 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9079 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9080 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9081 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9082 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9083 SiS_SetupDDCN(SiS_Pr);
9085 SiS_SetSwitchDDC2(SiS_Pr);
9087 while(*dataptr) {
9088 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9089 if(!dataptr) return false;
9091 return true;
9093 #endif
9095 /* The Chrontel 700x is connected to the 630/730 via
9096 * the 630/730's DDC/I2C port.
9098 * On 630(S)T chipset, the index changed from 0x11 to
9099 * 0x0a, possibly for working around the DDC problems
9102 static bool
9103 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9105 unsigned short temp, i;
9107 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9108 if(i) {
9109 SiS_SetStop(SiS_Pr);
9110 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9112 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9113 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9114 if(temp) continue; /* (ERROR: no ack) */
9115 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
9116 if(temp) continue; /* (ERROR: no ack) */
9117 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
9118 if(temp) continue; /* (ERROR: no ack) */
9119 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9120 SiS_Pr->SiS_ChrontelInit = 1;
9121 return true;
9123 return false;
9126 /* Write to Chrontel 700x */
9127 void
9128 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9130 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9132 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9134 if(!(SiS_Pr->SiS_ChrontelInit)) {
9135 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9136 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9137 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9138 SiS_SetupDDCN(SiS_Pr);
9141 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9142 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9143 SiS_Pr->SiS_DDC_Index = 0x0a;
9144 SiS_Pr->SiS_DDC_Data = 0x80;
9145 SiS_Pr->SiS_DDC_Clk = 0x40;
9146 SiS_SetupDDCN(SiS_Pr);
9148 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9152 /* Write to Chrontel 701x */
9153 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9154 void
9155 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9157 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9158 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9159 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9160 SiS_SetupDDCN(SiS_Pr);
9161 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9162 SiS_SetChReg(SiS_Pr, reg, val, 0);
9165 static
9166 void
9167 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9169 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9170 SiS_SetCH700x(SiS_Pr, reg, val);
9171 else
9172 SiS_SetCH701x(SiS_Pr, reg, val);
9175 static unsigned short
9176 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9178 unsigned short tempah, temp, i;
9180 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9181 if(i) {
9182 SiS_SetStop(SiS_Pr);
9183 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9185 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9186 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9187 if(temp) continue; /* (ERROR: no ack) */
9188 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9189 if(temp) continue; /* (ERROR: no ack) */
9190 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9191 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9192 if(temp) continue; /* (ERROR: no ack) */
9193 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9194 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9195 SiS_Pr->SiS_ChrontelInit = 1;
9196 return tempah;
9198 return 0xFFFF;
9201 /* Read from Chrontel 700x */
9202 /* Parameter is [Register no (S7-S0)] */
9203 unsigned short
9204 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9206 unsigned short result;
9208 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9210 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9212 if(!(SiS_Pr->SiS_ChrontelInit)) {
9213 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9214 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9215 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9216 SiS_SetupDDCN(SiS_Pr);
9219 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9221 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9222 (!SiS_Pr->SiS_ChrontelInit) ) {
9224 SiS_Pr->SiS_DDC_Index = 0x0a;
9225 SiS_Pr->SiS_DDC_Data = 0x80;
9226 SiS_Pr->SiS_DDC_Clk = 0x40;
9227 SiS_SetupDDCN(SiS_Pr);
9229 result = SiS_GetChReg(SiS_Pr,0x80);
9231 return result;
9234 /* Read from Chrontel 701x */
9235 /* Parameter is [Register no (S7-S0)] */
9236 unsigned short
9237 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9239 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9240 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9241 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9242 SiS_SetupDDCN(SiS_Pr);
9243 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9245 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9247 return SiS_GetChReg(SiS_Pr,0);
9250 /* Read from Chrontel 70xx */
9251 /* Parameter is [Register no (S7-S0)] */
9252 static
9253 unsigned short
9254 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9256 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9257 return SiS_GetCH700x(SiS_Pr, tempbx);
9258 else
9259 return SiS_GetCH701x(SiS_Pr, tempbx);
9262 void
9263 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9264 unsigned char myor, unsigned short myand)
9266 unsigned short tempbl;
9268 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9269 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9272 /* Our own DDC functions */
9273 static
9274 unsigned short
9275 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9276 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9277 unsigned int VBFlags2)
9279 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9280 unsigned char flag, cr32;
9281 unsigned short temp = 0, myadaptnum = adaptnum;
9283 if(adaptnum != 0) {
9284 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9285 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9288 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9290 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9292 SiS_Pr->SiS_DDC_SecAddr = 0;
9293 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9294 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9295 SiS_Pr->SiS_DDC_Index = 0x11;
9296 flag = 0xff;
9298 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9300 #if 0
9301 if(VBFlags2 & VB2_SISBRIDGE) {
9302 if(myadaptnum == 0) {
9303 if(!(cr32 & 0x20)) {
9304 myadaptnum = 2;
9305 if(!(cr32 & 0x10)) {
9306 myadaptnum = 1;
9307 if(!(cr32 & 0x08)) {
9308 myadaptnum = 0;
9314 #endif
9316 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9318 if(myadaptnum != 0) {
9319 flag = 0;
9320 if(VBFlags2 & VB2_SISBRIDGE) {
9321 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9322 SiS_Pr->SiS_DDC_Index = 0x0f;
9326 if(!(VBFlags2 & VB2_301)) {
9327 if((cr32 & 0x80) && (checkcr32)) {
9328 if(myadaptnum >= 1) {
9329 if(!(cr32 & 0x08)) {
9330 myadaptnum = 1;
9331 if(!(cr32 & 0x10)) return 0xFFFF;
9337 temp = 4 - (myadaptnum * 2);
9338 if(flag) temp = 0;
9340 } else { /* 315/330 series */
9342 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9344 if(VBFlags2 & VB2_SISBRIDGE) {
9345 if(myadaptnum == 2) {
9346 myadaptnum = 1;
9350 if(myadaptnum == 1) {
9351 flag = 0;
9352 if(VBFlags2 & VB2_SISBRIDGE) {
9353 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9354 SiS_Pr->SiS_DDC_Index = 0x0f;
9358 if((cr32 & 0x80) && (checkcr32)) {
9359 if(myadaptnum >= 1) {
9360 if(!(cr32 & 0x08)) {
9361 myadaptnum = 1;
9362 if(!(cr32 & 0x10)) return 0xFFFF;
9367 temp = myadaptnum;
9368 if(myadaptnum == 1) {
9369 temp = 0;
9370 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9373 if(flag) temp = 0;
9376 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9377 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9379 SiS_SetupDDCN(SiS_Pr);
9381 return 0;
9384 static unsigned short
9385 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9387 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9388 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9389 return 0xFFFF;
9391 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9392 return 0xFFFF;
9394 return 0;
9397 static unsigned short
9398 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9400 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9401 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9402 return 0xFFFF;
9404 return 0;
9407 static unsigned short
9408 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9410 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9411 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9412 return 0;
9415 static void
9416 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9418 SiS_SetSCLKLow(SiS_Pr);
9419 if(yesno) {
9420 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9421 SiS_Pr->SiS_DDC_Index,
9422 SiS_Pr->SiS_DDC_NData,
9423 SiS_Pr->SiS_DDC_Data);
9424 } else {
9425 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9426 SiS_Pr->SiS_DDC_Index,
9427 SiS_Pr->SiS_DDC_NData,
9430 SiS_SetSCLKHigh(SiS_Pr);
9433 static unsigned short
9434 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9436 unsigned char mask, value;
9437 unsigned short temp, ret=0;
9438 bool failed = false;
9440 SiS_SetSwitchDDC2(SiS_Pr);
9441 if(SiS_PrepareDDC(SiS_Pr)) {
9442 SiS_SetStop(SiS_Pr);
9443 return 0xFFFF;
9445 mask = 0xf0;
9446 value = 0x20;
9447 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9448 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9449 SiS_SendACK(SiS_Pr, 0);
9450 if(temp == 0) {
9451 mask = 0xff;
9452 value = 0xff;
9453 } else {
9454 failed = true;
9455 ret = 0xFFFF;
9458 if(!failed) {
9459 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9460 SiS_SendACK(SiS_Pr, 1);
9461 temp &= mask;
9462 if(temp == value) ret = 0;
9463 else {
9464 ret = 0xFFFF;
9465 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9466 if(temp == 0x30) ret = 0;
9470 SiS_SetStop(SiS_Pr);
9471 return ret;
9474 static
9475 unsigned short
9476 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9478 unsigned short flag;
9480 flag = 0x180;
9481 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9482 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9483 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9484 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9485 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9486 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9487 if(!(flag & 0x1a)) flag = 0;
9488 return flag;
9491 static
9492 unsigned short
9493 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9495 unsigned short flag, length, i;
9496 unsigned char chksum,gotcha;
9498 if(DDCdatatype > 4) return 0xFFFF;
9500 flag = 0;
9501 SiS_SetSwitchDDC2(SiS_Pr);
9502 if(!(SiS_PrepareDDC(SiS_Pr))) {
9503 length = 127;
9504 if(DDCdatatype != 1) length = 255;
9505 chksum = 0;
9506 gotcha = 0;
9507 for(i=0; i<length; i++) {
9508 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9509 chksum += buffer[i];
9510 gotcha |= buffer[i];
9511 SiS_SendACK(SiS_Pr, 0);
9513 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9514 chksum += buffer[i];
9515 SiS_SendACK(SiS_Pr, 1);
9516 if(gotcha) flag = (unsigned short)chksum;
9517 else flag = 0xFFFF;
9518 } else {
9519 flag = 0xFFFF;
9521 SiS_SetStop(SiS_Pr);
9522 return flag;
9525 /* Our private DDC functions
9527 It complies somewhat with the corresponding VESA function
9528 in arguments and return values.
9530 Since this is probably called before the mode is changed,
9531 we use our pre-detected pSiS-values instead of SiS_Pr as
9532 regards chipset and video bridge type.
9534 Arguments:
9535 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9536 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9537 LCDA is CRT1, but DDC is read from CRT2 port.
9538 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9539 buffer: ptr to 256 data bytes which will be filled with read data.
9541 Returns 0xFFFF if error, otherwise
9542 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9543 if DDCdatatype = 0: Returns supported DDC modes
9546 unsigned short
9547 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9548 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9549 unsigned int VBFlags2)
9551 unsigned char sr1f, cr17=1;
9552 unsigned short result;
9554 if(adaptnum > 2)
9555 return 0xFFFF;
9557 if(DDCdatatype > 4)
9558 return 0xFFFF;
9560 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9561 return 0xFFFF;
9563 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9564 return 0xFFFF;
9566 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9567 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9568 if(VGAEngine == SIS_300_VGA) {
9569 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9570 if(!cr17) {
9571 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9572 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9573 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9576 if((sr1f) || (!cr17)) {
9577 SiS_WaitRetrace1(SiS_Pr);
9578 SiS_WaitRetrace1(SiS_Pr);
9579 SiS_WaitRetrace1(SiS_Pr);
9580 SiS_WaitRetrace1(SiS_Pr);
9583 if(DDCdatatype == 0) {
9584 result = SiS_ProbeDDC(SiS_Pr);
9585 } else {
9586 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9587 if((!result) && (DDCdatatype == 1)) {
9588 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9589 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9590 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9591 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9592 (buffer[0x12] == 1)) {
9593 if(!SiS_Pr->DDCPortMixup) {
9594 if(adaptnum == 1) {
9595 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9596 } else {
9597 if(buffer[0x14] & 0x80) result = 0xFFFE;
9603 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9604 if(VGAEngine == SIS_300_VGA) {
9605 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9607 return result;
9610 /* Generic I2C functions for Chrontel & DDC --------- */
9612 static void
9613 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9615 SiS_SetSCLKHigh(SiS_Pr);
9616 SiS_WaitRetrace1(SiS_Pr);
9618 SiS_SetSCLKLow(SiS_Pr);
9619 SiS_WaitRetrace1(SiS_Pr);
9622 unsigned short
9623 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9625 SiS_WaitRetrace1(SiS_Pr);
9626 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9629 /* Set I2C start condition */
9630 /* This is done by a SD high-to-low transition while SC is high */
9631 static unsigned short
9632 SiS_SetStart(struct SiS_Private *SiS_Pr)
9634 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9635 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9636 SiS_Pr->SiS_DDC_Index,
9637 SiS_Pr->SiS_DDC_NData,
9638 SiS_Pr->SiS_DDC_Data); /* SD->high */
9639 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9640 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9641 SiS_Pr->SiS_DDC_Index,
9642 SiS_Pr->SiS_DDC_NData,
9643 0x00); /* SD->low = start condition */
9644 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9645 return 0;
9648 /* Set I2C stop condition */
9649 /* This is done by a SD low-to-high transition while SC is high */
9650 static unsigned short
9651 SiS_SetStop(struct SiS_Private *SiS_Pr)
9653 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9654 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9655 SiS_Pr->SiS_DDC_Index,
9656 SiS_Pr->SiS_DDC_NData,
9657 0x00); /* SD->low */
9658 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9659 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9660 SiS_Pr->SiS_DDC_Index,
9661 SiS_Pr->SiS_DDC_NData,
9662 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9663 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9664 return 0;
9667 /* Write 8 bits of data */
9668 static unsigned short
9669 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9671 unsigned short i,flag,temp;
9673 flag = 0x80;
9674 for(i = 0; i < 8; i++) {
9675 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9676 if(tempax & flag) {
9677 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9678 SiS_Pr->SiS_DDC_Index,
9679 SiS_Pr->SiS_DDC_NData,
9680 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9681 } else {
9682 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9683 SiS_Pr->SiS_DDC_Index,
9684 SiS_Pr->SiS_DDC_NData,
9685 0x00); /* Write bit (0) to SD */
9687 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9688 flag >>= 1;
9690 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9691 return temp;
9694 static unsigned short
9695 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9697 unsigned short i, temp, getdata;
9699 getdata = 0;
9700 for(i = 0; i < 8; i++) {
9701 getdata <<= 1;
9702 SiS_SetSCLKLow(SiS_Pr);
9703 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9704 SiS_Pr->SiS_DDC_Index,
9705 SiS_Pr->SiS_DDC_NData,
9706 SiS_Pr->SiS_DDC_Data);
9707 SiS_SetSCLKHigh(SiS_Pr);
9708 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9709 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9711 return getdata;
9714 static unsigned short
9715 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9717 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9718 SiS_Pr->SiS_DDC_Index,
9719 SiS_Pr->SiS_DDC_NClk,
9720 0x00); /* SetSCLKLow() */
9721 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9722 return 0;
9725 static unsigned short
9726 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9728 unsigned short temp, watchdog=1000;
9730 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9731 SiS_Pr->SiS_DDC_Index,
9732 SiS_Pr->SiS_DDC_NClk,
9733 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9734 do {
9735 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9736 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9737 if (!watchdog) {
9738 return 0xFFFF;
9740 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9741 return 0;
9744 /* Check I2C acknowledge */
9745 /* Returns 0 if ack ok, non-0 if ack not ok */
9746 static unsigned short
9747 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9749 unsigned short tempah;
9751 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9752 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9753 SiS_Pr->SiS_DDC_Index,
9754 SiS_Pr->SiS_DDC_NData,
9755 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9756 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9757 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9758 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9759 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9760 return 0;
9763 /* End of I2C functions ----------------------- */
9766 /* =============== SiS 315/330 O.E.M. ================= */
9768 #ifdef CONFIG_FB_SIS_315
9770 static unsigned short
9771 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9773 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9774 unsigned short romptr;
9776 if(SiS_Pr->ChipType < SIS_330) {
9777 romptr = SISGETROMW(0x128);
9778 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9779 romptr = SISGETROMW(0x12a);
9780 } else {
9781 romptr = SISGETROMW(0x1a8);
9782 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9783 romptr = SISGETROMW(0x1aa);
9785 return romptr;
9788 static unsigned short
9789 GetLCDromptr(struct SiS_Private *SiS_Pr)
9791 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9792 unsigned short romptr;
9794 if(SiS_Pr->ChipType < SIS_330) {
9795 romptr = SISGETROMW(0x120);
9796 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9797 romptr = SISGETROMW(0x122);
9798 } else {
9799 romptr = SISGETROMW(0x1a0);
9800 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9801 romptr = SISGETROMW(0x1a2);
9803 return romptr;
9806 static unsigned short
9807 GetTVromptr(struct SiS_Private *SiS_Pr)
9809 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9810 unsigned short romptr;
9812 if(SiS_Pr->ChipType < SIS_330) {
9813 romptr = SISGETROMW(0x114);
9814 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9815 romptr = SISGETROMW(0x11a);
9816 } else {
9817 romptr = SISGETROMW(0x194);
9818 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9819 romptr = SISGETROMW(0x19a);
9821 return romptr;
9824 static unsigned short
9825 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9827 unsigned short index;
9829 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9830 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9831 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9832 index >>= 4;
9833 index *= 3;
9834 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9835 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9836 return index;
9841 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9843 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9844 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9845 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9846 } else {
9847 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9849 index--;
9850 index *= 3;
9851 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9852 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9853 return index;
9856 static unsigned short
9857 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9859 unsigned short index;
9861 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9862 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9863 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9864 return index;
9867 static unsigned short
9868 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9870 unsigned short index;
9872 index = 0;
9873 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9876 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9878 index <<= 1;
9880 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9881 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9882 index++;
9885 return index;
9888 static unsigned int
9889 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9891 unsigned short index = 0, temp = 0;
9893 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9894 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9895 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9896 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9897 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9898 index = 4;
9899 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9900 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9903 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9904 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9905 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9906 index += addme;
9907 temp++;
9909 temp += 0x0100;
9911 return (unsigned int)(index | (temp << 16));
9914 static unsigned int
9915 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9917 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9920 #if 0
9921 static unsigned int
9922 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9924 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9926 #endif
9928 static int
9929 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9931 int index = 0;
9933 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9934 if(SiS_Pr->SiS_ROMNew) {
9935 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9936 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9937 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9938 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9939 } else {
9940 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9941 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9942 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9943 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9946 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9948 return index;
9951 static void
9952 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9954 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9955 unsigned short delay=0,index,myindex,temp,romptr=0;
9956 bool dochiptest = true;
9958 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9959 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9960 } else {
9961 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9964 /* Find delay (from ROM, internal tables, PCI subsystem) */
9966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9968 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9969 romptr = GetRAMDACromptr(SiS_Pr);
9971 if(romptr) delay = ROMAddr[romptr];
9972 else {
9973 delay = 0x04;
9974 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9975 if(IS_SIS650) {
9976 delay = 0x0a;
9977 } else if(IS_SIS740) {
9978 delay = 0x00;
9979 } else {
9980 delay = 0x0c;
9982 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9983 delay = 0x00;
9987 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9989 bool gotitfrompci = false;
9991 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9994 if(SiS_Pr->PDC != -1) {
9995 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9996 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9997 return;
9999 } else {
10000 if(SiS_Pr->PDCA != -1) {
10001 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10002 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10003 return;
10007 /* Custom Panel? */
10009 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10010 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10011 delay = 0x00;
10012 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10013 delay = 0x20;
10015 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10016 } else {
10017 delay = 0x0c;
10018 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10019 delay = 0x03;
10020 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10021 delay = 0x00;
10023 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10024 if(IS_SIS740) delay = 0x01;
10025 else delay = 0x03;
10027 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10029 return;
10032 /* This is a piece of typical SiS crap: They code the OEM LCD
10033 * delay into the code, at no defined place in the BIOS.
10034 * We now have to start doing a PCI subsystem check here.
10037 switch(SiS_Pr->SiS_CustomT) {
10038 case CUT_COMPAQ1280:
10039 case CUT_COMPAQ12802:
10040 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10041 gotitfrompci = true;
10042 dochiptest = false;
10043 delay = 0x03;
10045 break;
10046 case CUT_CLEVO1400:
10047 case CUT_CLEVO14002:
10048 gotitfrompci = true;
10049 dochiptest = false;
10050 delay = 0x02;
10051 break;
10052 case CUT_CLEVO1024:
10053 case CUT_CLEVO10242:
10054 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10055 gotitfrompci = true;
10056 dochiptest = false;
10057 delay = 0x33;
10058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10059 delay &= 0x0f;
10061 break;
10064 /* Could we find it through the PCI ID? If no, use ROM or table */
10066 if(!gotitfrompci) {
10068 index = GetLCDPtrIndexBIOS(SiS_Pr);
10069 myindex = GetLCDPtrIndex(SiS_Pr);
10071 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10073 if(SiS_IsNotM650orLater(SiS_Pr)) {
10075 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10076 /* Always use the second pointer on 650; some BIOSes */
10077 /* still carry old 301 data at the first location */
10078 /* romptr = SISGETROMW(0x120); */
10079 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10080 romptr = SISGETROMW(0x122);
10081 if(!romptr) return;
10082 delay = ROMAddr[(romptr + index)];
10083 } else {
10084 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10087 } else {
10089 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10090 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10091 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10095 } else if(SiS_Pr->SiS_UseROM &&
10096 (!(SiS_Pr->SiS_ROMNew)) &&
10097 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10098 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10099 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
10100 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
10101 ((romptr = GetLCDromptr(SiS_Pr)))) {
10103 /* Data for 1280x1024 wrong in 301B BIOS */
10104 /* Data for 1600x1200 wrong in 301C BIOS */
10105 delay = ROMAddr[(romptr + index)];
10107 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10109 if(IS_SIS740) delay = 0x03;
10110 else delay = 0x00;
10112 } else {
10114 delay = SiS310_LCDDelayCompensation_301[myindex];
10115 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10116 if(IS_SIS740) delay = 0x01;
10117 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10118 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10119 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10120 if(IS_SIS740) delay = 0x01; /* ? */
10121 else delay = 0x03;
10122 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10123 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10124 if(IS_SIS740) delay = 0x01;
10125 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10130 } /* got it from PCI */
10132 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10133 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10134 dochiptest = false;
10137 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10139 index = GetTVPtrIndex(SiS_Pr);
10141 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10143 if(SiS_IsNotM650orLater(SiS_Pr)) {
10145 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10146 /* Always use the second pointer on 650; some BIOSes */
10147 /* still carry old 301 data at the first location */
10148 /* romptr = SISGETROMW(0x114); */
10149 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10150 romptr = SISGETROMW(0x11a);
10151 if(!romptr) return;
10152 delay = ROMAddr[romptr + index];
10154 } else {
10156 delay = SiS310_TVDelayCompensation_301B[index];
10160 } else {
10162 switch(SiS_Pr->SiS_CustomT) {
10163 case CUT_COMPAQ1280:
10164 case CUT_COMPAQ12802:
10165 case CUT_CLEVO1400:
10166 case CUT_CLEVO14002:
10167 delay = 0x02;
10168 dochiptest = false;
10169 break;
10170 case CUT_CLEVO1024:
10171 case CUT_CLEVO10242:
10172 delay = 0x03;
10173 dochiptest = false;
10174 break;
10175 default:
10176 delay = SiS310_TVDelayCompensation_651301LV[index];
10177 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10178 delay = SiS310_TVDelayCompensation_651302LV[index];
10183 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10185 romptr = GetTVromptr(SiS_Pr);
10186 if(!romptr) return;
10187 delay = ROMAddr[romptr + index];
10189 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10191 delay = SiS310_TVDelayCompensation_LVDS[index];
10193 } else {
10195 delay = SiS310_TVDelayCompensation_301[index];
10196 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10197 if(IS_SIS740) {
10198 delay = SiS310_TVDelayCompensation_740301B[index];
10199 /* LV: use 301 data? BIOS bug? */
10200 } else {
10201 delay = SiS310_TVDelayCompensation_301B[index];
10202 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10208 if(SiS_LCDAEnabled(SiS_Pr)) {
10209 delay &= 0x0f;
10210 dochiptest = false;
10213 } else return;
10215 /* Write delay */
10217 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10219 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10221 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10222 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10223 delay &= 0x0f;
10224 delay |= 0xb0;
10225 } else if(temp == 6) {
10226 delay &= 0x0f;
10227 delay |= 0xc0;
10228 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10229 delay = 0x35;
10231 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10233 } else {
10235 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10239 } else { /* LVDS */
10241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10242 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10243 } else {
10244 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10245 delay <<= 4;
10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10247 } else {
10248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10256 static void
10257 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10259 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10260 unsigned short index,temp,temp1,romptr=0;
10262 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10264 if(ModeNo<=0x13)
10265 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10266 else
10267 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10269 temp = GetTVPtrIndex(SiS_Pr);
10270 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10271 temp1 = temp;
10273 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10274 if(SiS_Pr->ChipType >= SIS_661) {
10275 temp1 = GetOEMTVPtr661(SiS_Pr);
10276 temp1 >>= 1;
10277 romptr = SISGETROMW(0x260);
10278 if(SiS_Pr->ChipType >= SIS_760) {
10279 romptr = SISGETROMW(0x360);
10281 } else if(SiS_Pr->ChipType >= SIS_330) {
10282 romptr = SISGETROMW(0x192);
10283 } else {
10284 romptr = SISGETROMW(0x112);
10288 if(romptr) {
10289 temp1 <<= 1;
10290 temp = ROMAddr[romptr + temp1 + index];
10291 } else {
10292 temp = SiS310_TVAntiFlick1[temp][index];
10294 temp <<= 4;
10296 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10299 static void
10300 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10302 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10303 unsigned short index,temp,temp1,romptr=0;
10305 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10307 if(ModeNo <= 0x13)
10308 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10309 else
10310 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10312 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10313 if(SiS_Pr->ChipType >= SIS_661) {
10314 romptr = SISGETROMW(0x26c);
10315 if(SiS_Pr->ChipType >= SIS_760) {
10316 romptr = SISGETROMW(0x36c);
10318 temp1 = GetOEMTVPtr661(SiS_Pr);
10319 temp1 >>= 1;
10320 } else if(SiS_Pr->ChipType >= SIS_330) {
10321 romptr = SISGETROMW(0x1a4);
10322 } else {
10323 romptr = SISGETROMW(0x124);
10327 if(romptr) {
10328 temp1 <<= 1;
10329 temp = ROMAddr[romptr + temp1 + index];
10330 } else {
10331 temp = SiS310_TVEdge1[temp][index];
10333 temp <<= 5;
10334 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10337 static void
10338 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10340 unsigned short index, temp, i, j;
10342 if(ModeNo <= 0x13) {
10343 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10344 } else {
10345 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10348 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10350 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10351 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10352 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10353 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10355 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10356 for(i=0x35, j=0; i<=0x38; i++, j++) {
10357 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10359 for(i=0x48; i<=0x4A; i++, j++) {
10360 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10362 } else {
10363 for(i=0x35, j=0; i<=0x38; i++, j++) {
10364 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10369 static void
10370 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10372 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10373 unsigned short index,temp,i,j,resinfo,romptr=0;
10374 unsigned int lindex;
10376 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10378 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10379 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10381 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10382 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10383 lindex <<= 2;
10384 for(j=0, i=0x31; i<=0x34; i++, j++) {
10385 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10387 return;
10390 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10391 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10393 if(ModeNo<=0x13) {
10394 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10395 } else {
10396 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10399 temp = GetTVPtrIndex(SiS_Pr);
10400 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10401 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10403 if(SiS_Pr->SiS_UseROM) {
10404 romptr = SISGETROMW(0x116);
10405 if(SiS_Pr->ChipType >= SIS_330) {
10406 romptr = SISGETROMW(0x196);
10408 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10409 romptr = SISGETROMW(0x11c);
10410 if(SiS_Pr->ChipType >= SIS_330) {
10411 romptr = SISGETROMW(0x19c);
10413 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10414 romptr = SISGETROMW(0x116);
10415 if(SiS_Pr->ChipType >= SIS_330) {
10416 romptr = SISGETROMW(0x196);
10421 if(romptr) {
10422 romptr += (temp << 2);
10423 for(j=0, i=0x31; i<=0x34; i++, j++) {
10424 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10426 } else {
10427 index = temp % 2;
10428 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10429 for(j=0, i=0x31; i<=0x34; i++, j++) {
10430 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10431 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10432 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10433 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10434 else
10435 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10439 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10440 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10441 if((resinfo == SIS_RI_640x480) ||
10442 (resinfo == SIS_RI_800x600)) {
10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10444 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10445 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10447 } else if(resinfo == SIS_RI_1024x768) {
10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10450 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10451 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10457 static void
10458 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10459 unsigned short ModeIdIndex, unsigned short RTI)
10461 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10462 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10464 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10465 return;
10467 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10468 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10470 if(SiS_Pr->SiS_ROMNew) {
10471 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10472 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10473 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10474 index = 25;
10475 if(SiS_Pr->UseCustomMode) {
10476 index = SiS_Pr->CSRClock;
10477 } else if(ModeNo > 0x13) {
10478 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10479 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10481 if(index < 25) index = 25;
10482 index = ((index / 25) - 1) << 1;
10483 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10484 index++;
10486 romptr = SISGETROMW(0x104);
10487 delay = ROMAddr[romptr + index];
10488 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10491 } else {
10492 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10493 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10495 return;
10499 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10501 if(SiS_Pr->UseCustomMode) delay = 0x04;
10502 else if(ModeNo <= 0x13) delay = 0x04;
10503 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10504 delay |= (delay << 8);
10506 if(SiS_Pr->ChipType >= XGI_20) {
10508 delay = 0x0606;
10509 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10511 delay = 0x0404;
10512 if(SiS_Pr->SiS_XGIROM) {
10513 index = GetTVPtrIndex(SiS_Pr);
10514 if((romptr = SISGETROMW(0x35e))) {
10515 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10516 delay |= (delay << 8);
10520 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10521 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10522 delay -= 0x0404;
10527 } else if(SiS_Pr->ChipType >= SIS_340) {
10529 delay = 0x0606;
10530 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10531 delay = 0x0404;
10533 /* TODO (eventually) */
10535 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10537 /* 3. TV */
10539 index = GetOEMTVPtr661(SiS_Pr);
10540 if(SiS_Pr->SiS_ROMNew) {
10541 romptr = SISGETROMW(0x106);
10542 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10543 delay = ROMAddr[romptr + index];
10544 } else {
10545 delay = 0x04;
10546 if(index > 3) delay = 0;
10549 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10551 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10553 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10554 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10556 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10558 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10559 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10560 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10562 } else {
10564 /* TMDS: Set our own, since BIOS has no idea */
10565 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10566 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10567 switch(SiS_Pr->SiS_LCDResInfo) {
10568 case Panel_1024x768: delay = 0x0008; break;
10569 case Panel_1280x720: delay = 0x0004; break;
10570 case Panel_1280x768:
10571 case Panel_1280x768_2:delay = 0x0004; break;
10572 case Panel_1280x800:
10573 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10574 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10575 case Panel_1280x1024: delay = 0x1e04; break;
10576 case Panel_1400x1050: delay = 0x0004; break;
10577 case Panel_1600x1200: delay = 0x0400; break;
10578 case Panel_1680x1050: delay = 0x0e04; break;
10579 default:
10580 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10581 delay = 0x0008;
10582 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10583 delay = 0x1e04;
10584 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10585 delay = 0x0004;
10586 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10587 delay = 0x0400;
10588 } else
10589 delay = 0x0e04;
10590 break;
10594 /* Override by detected or user-set values */
10595 /* (but only if, for some reason, we can't read value from BIOS) */
10596 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10597 delay = SiS_Pr->PDC & 0x1f;
10599 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10600 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10607 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10608 delay >>= 8;
10609 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10611 } else {
10612 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10613 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10617 static void
10618 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10620 unsigned short infoflag;
10621 unsigned char temp;
10623 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10625 if(ModeNo <= 0x13) {
10626 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10627 } else if(SiS_Pr->UseCustomMode) {
10628 infoflag = SiS_Pr->CInfoFlag;
10629 } else {
10630 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10633 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10634 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10637 infoflag &= 0xc0;
10639 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10640 temp = (infoflag >> 6) | 0x0c;
10641 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10642 temp ^= 0x04;
10643 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10645 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10646 } else {
10647 temp = 0x30;
10648 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10649 temp |= infoflag;
10650 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10651 temp = 0;
10652 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10653 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10655 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10661 static void
10662 SetPanelParms661(struct SiS_Private *SiS_Pr)
10664 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10665 unsigned short romptr, temp1, temp2;
10667 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10668 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10671 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10672 if(SiS_Pr->LVDSHL != -1) {
10673 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10677 if(SiS_Pr->SiS_ROMNew) {
10679 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10680 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10681 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10682 temp2 = 0xfc;
10683 if(SiS_Pr->LVDSHL != -1) {
10684 temp1 &= 0xfc;
10685 temp2 = 0xf3;
10687 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10689 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10690 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10691 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10698 static void
10699 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10701 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10702 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10703 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10704 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10705 SetPanelParms661(SiS_Pr);
10707 } else {
10708 SetDelayComp(SiS_Pr,ModeNo);
10711 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10712 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10713 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10714 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10715 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10716 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10721 static void
10722 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10723 unsigned short ModeIdIndex, unsigned short RRTI)
10725 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10727 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10729 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10730 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10731 SetPanelParms661(SiS_Pr);
10734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10735 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10736 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10737 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10738 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10739 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10745 /* FinalizeLCD
10746 * This finalizes some CRT2 registers for the very panel used.
10747 * If we have a backup if these registers, we use it; otherwise
10748 * we set the register according to most BIOSes. However, this
10749 * function looks quite different in every BIOS, so you better
10750 * pray that we have a backup...
10752 static void
10753 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10755 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10756 unsigned short resinfo,modeflag;
10758 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10759 if(SiS_Pr->SiS_ROMNew) return;
10761 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10762 if(SiS_Pr->LVDSHL != -1) {
10763 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10767 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10768 if(SiS_Pr->UseCustomMode) return;
10770 switch(SiS_Pr->SiS_CustomT) {
10771 case CUT_COMPAQ1280:
10772 case CUT_COMPAQ12802:
10773 case CUT_CLEVO1400:
10774 case CUT_CLEVO14002:
10775 return;
10778 if(ModeNo <= 0x13) {
10779 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10780 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10781 } else {
10782 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10783 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10786 if(IS_SIS650) {
10787 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10788 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10789 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10790 } else {
10791 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10796 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10797 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10798 /* Maybe all panels? */
10799 if(SiS_Pr->LVDSHL == -1) {
10800 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10802 return;
10806 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10807 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10808 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10809 if(SiS_Pr->LVDSHL == -1) {
10810 /* Maybe all panels? */
10811 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10813 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10814 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10815 if(tempch == 3) {
10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10822 return;
10827 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10828 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10829 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10831 #ifdef SET_EMI
10832 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10833 #endif
10834 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10836 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10837 if(SiS_Pr->LVDSHL == -1) {
10838 /* Maybe ACER only? */
10839 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10842 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10843 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10844 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10845 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10846 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10847 if(tempch == 0x03) {
10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10850 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10851 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10853 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10864 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10866 if(ModeNo <= 0x13) {
10867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10868 if((resinfo == 0) || (resinfo == 2)) return;
10869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10870 if((resinfo == 1) || (resinfo == 3)) return;
10872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10873 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10875 #if 0
10876 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10877 tempbx--;
10878 temp = tempbx & 0xff;
10879 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10880 temp = (tempbx >> 8) & 0x03;
10881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10882 #endif
10884 } else if(ModeNo <= 0x13) {
10885 if(ModeNo <= 1) {
10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10891 if(!(modeflag & HalfDCLK)) {
10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10898 if(ModeNo == 0x12) {
10899 switch(tempch) {
10900 case 0:
10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10907 break;
10908 case 2:
10909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10911 break;
10912 case 3:
10913 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10914 break;
10920 } else {
10921 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10922 tempcl &= 0x0f;
10923 tempbh &= 0x70;
10924 tempbh >>= 4;
10925 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10926 tempbx = (tempbh << 8) | tempbl;
10927 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10928 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10929 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10930 tempbx = 770;
10931 } else {
10932 if(tempbx > 770) tempbx = 770;
10933 if(SiS_Pr->SiS_VGAVDE < 600) {
10934 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10935 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10936 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10937 tempbx -= tempax;
10940 } else return;
10942 temp = tempbx & 0xff;
10943 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10944 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10945 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10950 #endif
10952 /* ================= SiS 300 O.E.M. ================== */
10954 #ifdef CONFIG_FB_SIS_300
10956 static void
10957 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10958 unsigned short RefTabIndex)
10960 unsigned short crt2crtc=0, modeflag, myindex=0;
10961 unsigned char temp;
10962 int i;
10964 if(ModeNo <= 0x13) {
10965 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10966 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10967 } else {
10968 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10969 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10972 crt2crtc &= 0x3f;
10974 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10975 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10978 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10979 if(modeflag & HalfDCLK) myindex = 1;
10981 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10982 for(i=0; i<7; i++) {
10983 if(barco_p1[myindex][crt2crtc][i][0]) {
10984 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10985 barco_p1[myindex][crt2crtc][i][0],
10986 barco_p1[myindex][crt2crtc][i][2],
10987 barco_p1[myindex][crt2crtc][i][1]);
10991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10992 if(temp & 0x80) {
10993 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10994 temp++;
10995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11000 static unsigned short
11001 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11003 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11004 unsigned short tempbx=0,romptr=0;
11005 static const unsigned char customtable300[] = {
11006 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11007 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11009 static const unsigned char customtable630[] = {
11010 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11011 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11014 if(SiS_Pr->ChipType == SIS_300) {
11016 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11017 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11018 tempbx -= 2;
11019 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11020 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11021 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11023 if(SiS_Pr->SiS_UseROM) {
11024 if(ROMAddr[0x235] & 0x80) {
11025 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11026 if(Flag) {
11027 romptr = SISGETROMW(0x255);
11028 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11029 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11030 if(tempbx == 0xFF) return 0xFFFF;
11032 tempbx <<= 1;
11033 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11037 } else {
11039 if(Flag) {
11040 if(SiS_Pr->SiS_UseROM) {
11041 romptr = SISGETROMW(0x255);
11042 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11043 else tempbx = 0xff;
11044 } else {
11045 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11047 if(tempbx == 0xFF) return 0xFFFF;
11048 tempbx <<= 2;
11049 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11050 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11051 return tempbx;
11053 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11054 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11055 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11059 return tempbx;
11062 static void
11063 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11065 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11066 unsigned short index,temp,romptr=0;
11068 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11070 if(SiS_Pr->SiS_UseROM) {
11071 if(!(ROMAddr[0x237] & 0x01)) return;
11072 if(!(ROMAddr[0x237] & 0x02)) return;
11073 romptr = SISGETROMW(0x24b);
11076 /* The Panel Compensation Delay should be set according to tables
11077 * here. Unfortunately, various BIOS versions don't care about
11078 * a uniform way using eg. ROM byte 0x220, but use different
11079 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11080 * Thus we don't set this if the user selected a custom pdc or if
11081 * we otherwise detected a valid pdc.
11083 if(SiS_Pr->PDC != -1) return;
11085 temp = GetOEMLCDPtr(SiS_Pr, 0);
11087 if(SiS_Pr->UseCustomMode)
11088 index = 0;
11089 else
11090 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11092 if(SiS_Pr->ChipType != SIS_300) {
11093 if(romptr) {
11094 romptr += (temp * 2);
11095 romptr = SISGETROMW(romptr);
11096 romptr += index;
11097 temp = ROMAddr[romptr];
11098 } else {
11099 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11100 temp = SiS300_OEMLCDDelay2[temp][index];
11101 } else {
11102 temp = SiS300_OEMLCDDelay3[temp][index];
11105 } else {
11106 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11107 if(romptr) {
11108 romptr += (temp * 2);
11109 romptr = SISGETROMW(romptr);
11110 romptr += index;
11111 temp = ROMAddr[romptr];
11112 } else {
11113 temp = SiS300_OEMLCDDelay5[temp][index];
11115 } else {
11116 if(SiS_Pr->SiS_UseROM) {
11117 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11118 if(romptr) {
11119 romptr += (temp * 2);
11120 romptr = SISGETROMW(romptr);
11121 romptr += index;
11122 temp = ROMAddr[romptr];
11123 } else {
11124 temp = SiS300_OEMLCDDelay4[temp][index];
11126 } else {
11127 temp = SiS300_OEMLCDDelay4[temp][index];
11131 temp &= 0x3c;
11132 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11135 static void
11136 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11138 #if 0 /* Unfinished; Data table missing */
11139 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11140 unsigned short index,temp;
11142 if((SiS_Pr->SiS_UseROM) {
11143 if(!(ROMAddr[0x237] & 0x01)) return;
11144 if(!(ROMAddr[0x237] & 0x04)) return;
11145 /* No rom pointer in BIOS header! */
11148 temp = GetOEMLCDPtr(SiS_Pr, 1);
11149 if(temp == 0xFFFF) return;
11151 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11152 for(i=0x14, j=0; i<=0x17; i++, j++) {
11153 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11155 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11157 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11158 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11159 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11160 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11161 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11162 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11164 #endif
11167 static unsigned short
11168 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11170 unsigned short index;
11172 index = 0;
11173 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11174 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11175 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11176 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11177 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11178 } else {
11179 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11180 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11182 return index;
11185 static void
11186 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11188 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11189 unsigned short index,temp,romptr=0;
11191 if(SiS_Pr->SiS_UseROM) {
11192 if(!(ROMAddr[0x238] & 0x01)) return;
11193 if(!(ROMAddr[0x238] & 0x02)) return;
11194 romptr = SISGETROMW(0x241);
11197 temp = GetOEMTVPtr(SiS_Pr);
11199 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11201 if(romptr) {
11202 romptr += (temp * 2);
11203 romptr = SISGETROMW(romptr);
11204 romptr += index;
11205 temp = ROMAddr[romptr];
11206 } else {
11207 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11208 temp = SiS300_OEMTVDelay301[temp][index];
11209 } else {
11210 temp = SiS300_OEMTVDelayLVDS[temp][index];
11213 temp &= 0x3c;
11214 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11217 static void
11218 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11220 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11221 unsigned short index,temp,romptr=0;
11223 if(SiS_Pr->SiS_UseROM) {
11224 if(!(ROMAddr[0x238] & 0x01)) return;
11225 if(!(ROMAddr[0x238] & 0x04)) return;
11226 romptr = SISGETROMW(0x243);
11229 temp = GetOEMTVPtr(SiS_Pr);
11231 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11233 if(romptr) {
11234 romptr += (temp * 2);
11235 romptr = SISGETROMW(romptr);
11236 romptr += index;
11237 temp = ROMAddr[romptr];
11238 } else {
11239 temp = SiS300_OEMTVFlicker[temp][index];
11241 temp &= 0x70;
11242 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11245 static void
11246 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11248 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11249 unsigned short index,i,j,temp,romptr=0;
11251 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11253 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11255 if(SiS_Pr->SiS_UseROM) {
11256 if(!(ROMAddr[0x238] & 0x01)) return;
11257 if(!(ROMAddr[0x238] & 0x08)) return;
11258 romptr = SISGETROMW(0x245);
11261 temp = GetOEMTVPtr(SiS_Pr);
11263 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11265 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11266 for(i=0x31, j=0; i<=0x34; i++, j++) {
11267 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11269 } else {
11270 if(romptr) {
11271 romptr += (temp * 2);
11272 romptr = SISGETROMW(romptr);
11273 romptr += (index * 4);
11274 for(i=0x31, j=0; i<=0x34; i++, j++) {
11275 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11277 } else {
11278 for(i=0x31, j=0; i<=0x34; i++, j++) {
11279 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11285 static void
11286 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11288 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11289 unsigned short index,temp,i,j,romptr=0;
11291 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11293 if(SiS_Pr->SiS_UseROM) {
11294 if(!(ROMAddr[0x238] & 0x01)) return;
11295 if(!(ROMAddr[0x238] & 0x10)) return;
11296 romptr = SISGETROMW(0x247);
11299 temp = GetOEMTVPtr(SiS_Pr);
11301 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11302 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11303 /* NTSCJ uses NTSC filters */
11305 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11307 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11308 for(i=0x35, j=0; i<=0x38; i++, j++) {
11309 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11311 for(i=0x48; i<=0x4A; i++, j++) {
11312 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11314 } else {
11315 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11316 romptr += (temp * 2);
11317 romptr = SISGETROMW(romptr);
11318 romptr += (index * 4);
11319 for(i=0x35, j=0; i<=0x38; i++, j++) {
11320 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11322 } else {
11323 for(i=0x35, j=0; i<=0x38; i++, j++) {
11324 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11330 static unsigned short
11331 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11333 unsigned short ModeIdIndex;
11334 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11336 if(*ModeNo <= 5) *ModeNo |= 1;
11338 for(ModeIdIndex=0; ; ModeIdIndex++) {
11339 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11340 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11343 if(*ModeNo != 0x07) {
11344 if(*ModeNo > 0x03) return ModeIdIndex;
11345 if(VGAINFO & 0x80) return ModeIdIndex;
11346 ModeIdIndex++;
11349 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11350 /* else 350 lines */
11351 return ModeIdIndex;
11354 static void
11355 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11356 unsigned short RefTableIndex)
11358 unsigned short OEMModeIdIndex = 0;
11360 if(!SiS_Pr->UseCustomMode) {
11361 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11362 if(!(OEMModeIdIndex)) return;
11365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11366 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11367 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11368 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11371 if(SiS_Pr->UseCustomMode) return;
11372 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11373 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11374 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11375 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11376 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11377 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11381 #endif