WIP FPC-III support
[linux/fpc-iii.git] / drivers / video / fbdev / sis / init301.c
bloba8fb41f1a2580e02574f9a40cbc5d1919ed34fdb
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) { /* 315 series, LVDS; Special */
853 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
854 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
855 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
856 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
858 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
859 DelayIndex = PanelID & 0x0f;
860 } else {
861 DelayIndex = PanelID >> 4;
863 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
864 Delay = 3;
865 } else {
866 if(DelayTime >= 2) DelayTime -= 2;
867 if(!(DelayTime & 0x01)) {
868 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
869 } else {
870 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
872 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
873 if(ROMAddr[0x13c] & 0x40) {
874 if(!(DelayTime & 0x01)) {
875 Delay = (unsigned short)ROMAddr[0x17e];
876 } else {
877 Delay = (unsigned short)ROMAddr[0x17f];
882 SiS_ShortDelay(SiS_Pr, Delay);
885 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
887 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
888 if(!(DelayTime & 0x01)) {
889 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
890 } else {
891 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
893 Delay <<= 8;
894 SiS_DDC2Delay(SiS_Pr, Delay);
898 #endif /* CONFIG_FB_SIS_315 */
903 #ifdef CONFIG_FB_SIS_315
904 static void
905 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
907 int i;
908 for(i = 0; i < DelayLoop; i++) {
909 SiS_PanelDelay(SiS_Pr, DelayTime);
912 #endif
914 /*********************************************/
915 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
916 /*********************************************/
918 void
919 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
921 unsigned short watchdog;
923 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
924 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
926 watchdog = 65535;
927 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
928 watchdog = 65535;
929 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
932 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
933 static void
934 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
936 unsigned short watchdog;
938 watchdog = 65535;
939 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
940 watchdog = 65535;
941 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
943 #endif
945 static void
946 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
948 if(SiS_Pr->ChipType < SIS_315H) {
949 #ifdef CONFIG_FB_SIS_300
950 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
951 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
953 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
954 SiS_WaitRetrace1(SiS_Pr);
955 } else {
956 SiS_WaitRetrace2(SiS_Pr, 0x25);
958 #endif
959 } else {
960 #ifdef CONFIG_FB_SIS_315
961 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
962 SiS_WaitRetrace1(SiS_Pr);
963 } else {
964 SiS_WaitRetrace2(SiS_Pr, 0x30);
966 #endif
970 static void
971 SiS_VBWait(struct SiS_Private *SiS_Pr)
973 unsigned short tempal,temp,i,j;
975 temp = 0;
976 for(i = 0; i < 3; i++) {
977 for(j = 0; j < 100; j++) {
978 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
979 if(temp & 0x01) {
980 if((tempal & 0x08)) continue;
981 else break;
982 } else {
983 if(!(tempal & 0x08)) continue;
984 else break;
987 temp ^= 0x01;
991 static void
992 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
995 SiS_VBWait(SiS_Pr);
996 } else {
997 SiS_WaitRetrace1(SiS_Pr);
1001 /*********************************************/
1002 /* HELPER: MISC */
1003 /*********************************************/
1005 #ifdef CONFIG_FB_SIS_300
1006 static bool
1007 SiS_Is301B(struct SiS_Private *SiS_Pr)
1009 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1010 return false;
1012 #endif
1014 static bool
1015 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1017 if(SiS_Pr->ChipType == SIS_730) {
1018 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1020 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1021 return false;
1024 bool
1025 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1027 #ifdef CONFIG_FB_SIS_315
1028 if(SiS_Pr->ChipType >= SIS_315H) {
1029 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1030 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1033 #endif
1034 return false;
1037 bool
1038 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1040 #ifdef CONFIG_FB_SIS_315
1041 unsigned short flag;
1043 if(SiS_Pr->ChipType >= SIS_315H) {
1044 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1045 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1047 #endif
1048 return false;
1051 #ifdef CONFIG_FB_SIS_315
1052 static bool
1053 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1055 if(SiS_IsVAMode(SiS_Pr)) return true;
1056 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1057 return false;
1059 #endif
1061 static bool
1062 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1064 #ifdef CONFIG_FB_SIS_315
1065 if(SiS_Pr->ChipType >= SIS_315H) {
1066 if((SiS_CRT2IsLCD(SiS_Pr)) ||
1067 (SiS_IsVAMode(SiS_Pr))) {
1068 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1071 #endif
1072 return false;
1075 #ifdef CONFIG_FB_SIS_315
1076 static bool
1077 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1079 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1080 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1081 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1083 return false;
1085 #endif
1087 #ifdef CONFIG_FB_SIS_315
1088 static bool
1089 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1091 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1092 return false;
1094 #endif
1096 #ifdef CONFIG_FB_SIS_315
1097 static bool
1098 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1100 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1101 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1103 return false;
1105 #endif
1107 #ifdef CONFIG_FB_SIS_315
1108 static bool
1109 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1111 unsigned short flag;
1113 if(SiS_Pr->ChipType == SIS_650) {
1114 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1115 /* Check for revision != A0 only */
1116 if((flag == 0xe0) || (flag == 0xc0) ||
1117 (flag == 0xb0) || (flag == 0x90)) return false;
1118 } else if(SiS_Pr->ChipType >= SIS_661) return false;
1119 return true;
1121 #endif
1123 #ifdef CONFIG_FB_SIS_315
1124 static bool
1125 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1127 if(SiS_Pr->ChipType >= SIS_315H) {
1128 /* YPrPb = 0x08 */
1129 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1131 return false;
1133 #endif
1135 #ifdef CONFIG_FB_SIS_315
1136 static bool
1137 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1139 if(SiS_Pr->ChipType >= SIS_315H) {
1140 /* Scart = 0x04 */
1141 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1143 return false;
1145 #endif
1147 #ifdef CONFIG_FB_SIS_315
1148 static bool
1149 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1151 unsigned short flag;
1153 if(SiS_Pr->ChipType >= SIS_315H) {
1154 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1155 if(flag & SetCRT2ToTV) return true;
1156 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1157 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
1158 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
1159 } else {
1160 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1161 if(flag & SetCRT2ToTV) return true;
1163 return false;
1165 #endif
1167 #ifdef CONFIG_FB_SIS_315
1168 static bool
1169 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1171 unsigned short flag;
1173 if(SiS_Pr->ChipType >= SIS_315H) {
1174 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1175 if(flag & SetCRT2ToLCD) return true;
1176 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1177 if(flag & SetToLCDA) return true;
1178 } else {
1179 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1180 if(flag & SetCRT2ToLCD) return true;
1182 return false;
1184 #endif
1186 static bool
1187 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1189 unsigned short flag;
1191 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1192 return true;
1193 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1194 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1195 if((flag == 1) || (flag == 2)) return true;
1197 return false;
1200 static bool
1201 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1203 unsigned short flag;
1205 if(SiS_HaveBridge(SiS_Pr)) {
1206 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1207 if(SiS_Pr->ChipType < SIS_315H) {
1208 flag &= 0xa0;
1209 if((flag == 0x80) || (flag == 0x20)) return true;
1210 } else {
1211 flag &= 0x50;
1212 if((flag == 0x40) || (flag == 0x10)) return true;
1215 return false;
1218 static bool
1219 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1221 unsigned short flag1;
1223 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1224 if(flag1 & (SetInSlaveMode >> 8)) return true;
1225 return false;
1228 /*********************************************/
1229 /* GET VIDEO BRIDGE CONFIG INFO */
1230 /*********************************************/
1232 /* Setup general purpose IO for Chrontel communication */
1233 #ifdef CONFIG_FB_SIS_300
1234 void
1235 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1237 unsigned int acpibase;
1238 unsigned short temp;
1240 if(!(SiS_Pr->SiS_ChSW)) return;
1242 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1243 acpibase &= 0xFFFF;
1244 if(!acpibase) return;
1245 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
1246 temp &= 0xFEFF;
1247 SiS_SetRegShort((acpibase + 0x3c), temp);
1248 temp = SiS_GetRegShort((acpibase + 0x3c));
1249 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
1250 temp &= 0xFEFF;
1251 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1252 SiS_SetRegShort((acpibase + 0x3a), temp);
1253 temp = SiS_GetRegShort((acpibase + 0x3a));
1255 #endif
1257 void
1258 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1259 unsigned short ModeIdIndex, int checkcrt2mode)
1261 unsigned short tempax, tempbx, temp;
1262 unsigned short modeflag, resinfo = 0;
1264 SiS_Pr->SiS_SetFlag = 0;
1266 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1268 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1270 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1271 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1274 tempbx = 0;
1276 if(SiS_HaveBridge(SiS_Pr)) {
1278 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1279 tempbx |= temp;
1280 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1281 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1282 tempbx |= tempax;
1284 #ifdef CONFIG_FB_SIS_315
1285 if(SiS_Pr->ChipType >= SIS_315H) {
1286 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1287 if(ModeNo == 0x03) {
1288 /* Mode 0x03 is never in driver mode */
1289 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1291 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1292 /* Reset LCDA setting if not driver mode */
1293 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1295 if(IS_SIS650) {
1296 if(SiS_Pr->SiS_UseLCDA) {
1297 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1298 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1299 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1304 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1305 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1306 tempbx |= SetCRT2ToLCDA;
1310 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1311 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1312 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1313 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1314 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1315 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1316 tempbx |= SetCRT2ToYPbPr525750;
1321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1322 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1323 if(temp & SetToLCDA) {
1324 tempbx |= SetCRT2ToLCDA;
1326 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1327 if(temp & EnableCHYPbPr) {
1328 tempbx |= SetCRT2ToCHYPbPr;
1334 #endif /* CONFIG_FB_SIS_315 */
1336 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1337 tempbx &= ~(SetCRT2ToRAMDAC);
1340 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1341 temp = SetCRT2ToSVIDEO |
1342 SetCRT2ToAVIDEO |
1343 SetCRT2ToSCART |
1344 SetCRT2ToLCDA |
1345 SetCRT2ToLCD |
1346 SetCRT2ToRAMDAC |
1347 SetCRT2ToHiVision |
1348 SetCRT2ToYPbPr525750;
1349 } else {
1350 if(SiS_Pr->ChipType >= SIS_315H) {
1351 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1352 temp = SetCRT2ToAVIDEO |
1353 SetCRT2ToSVIDEO |
1354 SetCRT2ToSCART |
1355 SetCRT2ToLCDA |
1356 SetCRT2ToLCD |
1357 SetCRT2ToCHYPbPr;
1358 } else {
1359 temp = SetCRT2ToLCDA |
1360 SetCRT2ToLCD;
1362 } else {
1363 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1364 temp = SetCRT2ToTV | SetCRT2ToLCD;
1365 } else {
1366 temp = SetCRT2ToLCD;
1371 if(!(tempbx & temp)) {
1372 tempax = DisableCRT2Display;
1373 tempbx = 0;
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1378 unsigned short clearmask = ( DriverMode |
1379 DisableCRT2Display |
1380 LoadDACFlag |
1381 SetNotSimuMode |
1382 SetInSlaveMode |
1383 SetPALTV |
1384 SwitchCRT2 |
1385 SetSimuScanMode );
1387 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1388 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1389 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1390 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1391 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1392 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1394 } else {
1396 if(SiS_Pr->ChipType >= SIS_315H) {
1397 if(tempbx & SetCRT2ToLCDA) {
1398 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1401 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1402 if(tempbx & SetCRT2ToTV) {
1403 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1406 if(tempbx & SetCRT2ToLCD) {
1407 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1409 if(SiS_Pr->ChipType >= SIS_315H) {
1410 if(tempbx & SetCRT2ToLCDA) {
1411 tempbx |= SetCRT2ToLCD;
1417 if(tempax & DisableCRT2Display) {
1418 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1419 tempbx = SetSimuScanMode | DisableCRT2Display;
1423 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1425 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1426 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1427 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1428 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1429 modeflag &= (~CRT2Mode);
1433 if(!(tempbx & SetSimuScanMode)) {
1434 if(tempbx & SwitchCRT2) {
1435 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1436 if(resinfo != SIS_RI_1600x1200) {
1437 tempbx |= SetSimuScanMode;
1440 } else {
1441 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1442 if(!(tempbx & DriverMode)) {
1443 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1444 tempbx |= SetSimuScanMode;
1451 if(!(tempbx & DisableCRT2Display)) {
1452 if(tempbx & DriverMode) {
1453 if(tempbx & SetSimuScanMode) {
1454 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1455 if(resinfo != SIS_RI_1600x1200) {
1456 tempbx |= SetInSlaveMode;
1460 } else {
1461 tempbx |= SetInSlaveMode;
1467 SiS_Pr->SiS_VBInfo = tempbx;
1469 #ifdef CONFIG_FB_SIS_300
1470 if(SiS_Pr->ChipType == SIS_630) {
1471 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1473 #endif
1475 #if 0
1476 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1477 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1478 #endif
1481 /*********************************************/
1482 /* DETERMINE YPbPr MODE */
1483 /*********************************************/
1485 void
1486 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1489 unsigned char temp;
1491 /* Note: This variable is only used on 30xLV systems.
1492 * CR38 has a different meaning on LVDS/CH7019 systems.
1493 * On 661 and later, these bits moved to CR35.
1495 * On 301, 301B, only HiVision 1080i is supported.
1496 * On 30xLV, 301C, only YPbPr 1080i is supported.
1499 SiS_Pr->SiS_YPbPr = 0;
1500 if(SiS_Pr->ChipType >= SIS_661) return;
1502 if(SiS_Pr->SiS_VBType) {
1503 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1504 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1508 if(SiS_Pr->ChipType >= SIS_315H) {
1509 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1510 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1511 if(temp & 0x08) {
1512 switch((temp >> 4)) {
1513 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1514 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1515 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1516 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1524 /*********************************************/
1525 /* DETERMINE TVMode flag */
1526 /*********************************************/
1528 void
1529 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1531 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1532 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1533 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1535 SiS_Pr->SiS_TVMode = 0;
1537 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1538 if(SiS_Pr->UseCustomMode) return;
1540 if(ModeNo > 0x13) {
1541 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1544 if(SiS_Pr->ChipType < SIS_661) {
1546 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1548 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1549 temp = 0;
1550 if((SiS_Pr->ChipType == SIS_630) ||
1551 (SiS_Pr->ChipType == SIS_730)) {
1552 temp = 0x35;
1553 romindex = 0xfe;
1554 } else if(SiS_Pr->ChipType >= SIS_315H) {
1555 temp = 0x38;
1556 if(SiS_Pr->ChipType < XGI_20) {
1557 romindex = 0xf3;
1558 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1561 if(temp) {
1562 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1563 OutputSelect = ROMAddr[romindex];
1564 if(!(OutputSelect & EnablePALMN)) {
1565 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1568 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1569 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1570 if(temp1 & EnablePALM) { /* 0x40 */
1571 SiS_Pr->SiS_TVMode |= TVSetPALM;
1572 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1573 } else if(temp1 & EnablePALN) { /* 0x80 */
1574 SiS_Pr->SiS_TVMode |= TVSetPALN;
1576 } else {
1577 if(temp1 & EnableNTSCJ) { /* 0x40 */
1578 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1582 /* Translate HiVision/YPbPr to our new flags */
1583 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1584 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1585 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1586 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1587 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1588 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1589 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1590 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1591 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1592 SiS_Pr->SiS_TVMode |= TVSetPAL;
1595 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1596 if(SiS_Pr->SiS_CHOverScan) {
1597 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1598 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1599 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1600 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1602 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1603 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1604 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1605 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1608 if(SiS_Pr->SiS_CHSOverScan) {
1609 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1612 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1613 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1614 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1615 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1616 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1617 } else {
1618 if(temp & EnableNTSCJ) {
1619 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1625 } else { /* 661 and later */
1627 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1628 if(temp1 & 0x01) {
1629 SiS_Pr->SiS_TVMode |= TVSetPAL;
1630 if(temp1 & 0x08) {
1631 SiS_Pr->SiS_TVMode |= TVSetPALN;
1632 } else if(temp1 & 0x04) {
1633 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1634 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1636 SiS_Pr->SiS_TVMode |= TVSetPALM;
1638 } else {
1639 if(temp1 & 0x02) {
1640 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1643 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1644 if(SiS_Pr->SiS_CHOverScan) {
1645 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1646 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1650 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1651 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1652 temp1 &= 0xe0;
1653 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1654 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1655 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1656 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1657 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1660 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1661 SiS_Pr->SiS_TVMode |= TVAspect169;
1662 } else {
1663 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1664 if(temp1 & 0x02) {
1665 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1666 SiS_Pr->SiS_TVMode |= TVAspect169;
1667 } else {
1668 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1670 } else {
1671 SiS_Pr->SiS_TVMode |= TVAspect43;
1678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1680 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1683 SiS_Pr->SiS_TVMode |= TVSetPAL;
1684 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1685 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1686 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1687 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1691 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1692 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1693 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1697 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1698 if(resinfo == SIS_RI_1024x768) {
1699 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1700 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1701 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1702 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1707 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1708 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1709 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1710 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1711 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1712 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1713 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1714 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1715 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1721 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1724 /*********************************************/
1725 /* GET LCD INFO */
1726 /*********************************************/
1728 static unsigned short
1729 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1731 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1732 /* Translate my LCDResInfo to BIOS value */
1733 switch(temp) {
1734 case Panel_1280x768_2: temp = Panel_1280x768; break;
1735 case Panel_1280x800_2: temp = Panel_1280x800; break;
1736 case Panel_1280x854: temp = Panel661_1280x854; break;
1738 return temp;
1741 static void
1742 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1744 #ifdef CONFIG_FB_SIS_315
1745 unsigned char *ROMAddr;
1746 unsigned short temp;
1748 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1749 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1750 SiS_Pr->SiS_NeedRomModeData = true;
1751 SiS_Pr->PanelHT = temp;
1753 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1754 SiS_Pr->SiS_NeedRomModeData = true;
1755 SiS_Pr->PanelVT = temp;
1757 SiS_Pr->PanelHRS = SISGETROMW(10);
1758 SiS_Pr->PanelHRE = SISGETROMW(12);
1759 SiS_Pr->PanelVRS = SISGETROMW(14);
1760 SiS_Pr->PanelVRE = SISGETROMW(16);
1761 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1762 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1763 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1764 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1765 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1766 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1767 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1770 #endif
1773 static void
1774 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1775 const unsigned char *nonscalingmodes)
1777 int i = 0;
1778 while(nonscalingmodes[i] != 0xff) {
1779 if(nonscalingmodes[i++] == resinfo) {
1780 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1781 (SiS_Pr->UsePanelScaler == -1)) {
1782 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1784 break;
1789 void
1790 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1792 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1793 bool panelcanscale = false;
1794 #ifdef CONFIG_FB_SIS_300
1795 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1796 static const unsigned char SiS300SeriesLCDRes[] =
1797 { 0, 1, 2, 3, 7, 4, 5, 8,
1798 0, 0, 10, 0, 0, 0, 0, 15 };
1799 #endif
1800 #ifdef CONFIG_FB_SIS_315
1801 unsigned char *myptr = NULL;
1802 #endif
1804 SiS_Pr->SiS_LCDResInfo = 0;
1805 SiS_Pr->SiS_LCDTypeInfo = 0;
1806 SiS_Pr->SiS_LCDInfo = 0;
1807 SiS_Pr->PanelHRS = 999; /* HSync start */
1808 SiS_Pr->PanelHRE = 999; /* HSync end */
1809 SiS_Pr->PanelVRS = 999; /* VSync start */
1810 SiS_Pr->PanelVRE = 999; /* VSync end */
1811 SiS_Pr->SiS_NeedRomModeData = false;
1813 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1814 SiS_Pr->Alternate1600x1200 = false;
1816 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1818 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1820 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1821 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1822 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1823 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1826 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1828 /* For broken BIOSes: Assume 1024x768 */
1829 if(temp == 0) temp = 0x02;
1831 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1832 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1833 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1834 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1835 } else {
1836 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1838 temp &= 0x0f;
1839 #ifdef CONFIG_FB_SIS_300
1840 if(SiS_Pr->ChipType < SIS_315H) {
1841 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1842 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1843 if(temp < 0x0f) temp &= 0x07;
1845 /* Translate 300 series LCDRes to 315 series for unified usage */
1846 temp = SiS300SeriesLCDRes[temp];
1848 #endif
1850 /* Translate to our internal types */
1851 #ifdef CONFIG_FB_SIS_315
1852 if(SiS_Pr->ChipType == SIS_550) {
1853 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1854 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1855 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1856 } else if(SiS_Pr->ChipType >= SIS_661) {
1857 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1859 #endif
1861 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1862 if(temp == Panel310_1280x768) {
1863 temp = Panel_1280x768_2;
1865 if(SiS_Pr->SiS_ROMNew) {
1866 if(temp == Panel661_1280x800) {
1867 temp = Panel_1280x800_2;
1872 SiS_Pr->SiS_LCDResInfo = temp;
1874 #ifdef CONFIG_FB_SIS_300
1875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1876 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1877 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1878 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1879 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1880 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1881 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1884 #endif
1886 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1887 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1888 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1889 } else {
1890 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1891 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1894 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1895 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1896 /* Need temp below! */
1898 /* These must/can't scale no matter what */
1899 switch(SiS_Pr->SiS_LCDResInfo) {
1900 case Panel_320x240_1:
1901 case Panel_320x240_2:
1902 case Panel_320x240_3:
1903 case Panel_1280x960:
1904 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1905 break;
1906 case Panel_640x480:
1907 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1910 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1912 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1913 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1915 /* Dual link, Pass 1:1 BIOS default, etc. */
1916 #ifdef CONFIG_FB_SIS_315
1917 if(SiS_Pr->ChipType >= SIS_661) {
1918 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1919 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1921 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1922 if(SiS_Pr->SiS_ROMNew) {
1923 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1924 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1925 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1928 } else if(SiS_Pr->ChipType >= SIS_315H) {
1929 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1930 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1932 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1933 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1934 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1935 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1936 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1937 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1939 } else if(!(SiS_Pr->SiS_ROMNew)) {
1940 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1941 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1942 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1943 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1945 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1946 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1947 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1948 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1949 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1954 #endif
1956 /* Pass 1:1 */
1957 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1958 /* Always center screen on LVDS (if scaling is disabled) */
1959 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1960 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1961 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1962 /* Always center screen on SiS LVDS (if scaling is disabled) */
1963 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1964 } else {
1965 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1966 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1967 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1971 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1972 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1974 switch(SiS_Pr->SiS_LCDResInfo) {
1975 case Panel_320x240_1:
1976 case Panel_320x240_2:
1977 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1978 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1979 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1980 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1981 break;
1982 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1983 SiS_Pr->PanelVRE = 3;
1984 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1985 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1986 break;
1987 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1988 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1989 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1990 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1991 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1992 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1993 break;
1994 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1995 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1996 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1997 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1998 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1999 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2000 break;
2001 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2002 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2003 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2004 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2005 if(SiS_Pr->ChipType < SIS_315H) {
2006 SiS_Pr->PanelHRS = 23;
2007 SiS_Pr->PanelVRE = 5;
2009 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2010 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2011 SiS_GetLCDInfoBIOS(SiS_Pr);
2012 break;
2013 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
2014 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2015 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2016 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2017 if(SiS_Pr->ChipType < SIS_315H) {
2018 SiS_Pr->PanelHRS = 23;
2019 SiS_Pr->PanelVRE = 5;
2021 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2022 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2023 break;
2024 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
2025 break;
2026 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
2027 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
2028 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
2029 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
2030 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2031 /* Data above for TMDS (projector); get from BIOS for LVDS */
2032 SiS_GetLCDInfoBIOS(SiS_Pr);
2033 break;
2034 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2036 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
2037 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2038 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2039 } else {
2040 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
2041 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2042 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2043 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2044 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2046 break;
2047 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2048 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
2049 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2050 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2051 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2052 SiS_GetLCDInfoBIOS(SiS_Pr);
2053 break;
2054 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2055 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
2056 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
2057 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2058 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2059 SiS_GetLCDInfoBIOS(SiS_Pr);
2060 break;
2061 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2062 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
2063 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2064 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2065 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2066 SiS_GetLCDInfoBIOS(SiS_Pr);
2067 break;
2068 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
2069 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
2070 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
2071 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2072 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2073 SiS_GetLCDInfoBIOS(SiS_Pr);
2074 break;
2075 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
2076 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
2077 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2078 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2079 if(resinfo == SIS_RI_1280x1024) {
2080 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2081 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2083 break;
2084 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2085 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2086 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2087 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2088 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2089 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2090 SiS_GetLCDInfoBIOS(SiS_Pr);
2091 break;
2092 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2093 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2094 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2095 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2096 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2097 SiS_GetLCDInfoBIOS(SiS_Pr);
2098 break;
2099 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2100 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
2101 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
2102 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2103 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2104 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2105 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2106 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
2107 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
2108 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
2109 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2110 SiS_Pr->Alternate1600x1200 = true;
2112 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2113 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
2114 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2115 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2117 SiS_GetLCDInfoBIOS(SiS_Pr);
2118 break;
2119 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2120 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
2121 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
2122 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2123 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2124 SiS_GetLCDInfoBIOS(SiS_Pr);
2125 break;
2126 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2127 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2128 break;
2129 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
2130 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2131 break;
2132 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
2133 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2134 break;
2135 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2136 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2137 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
2138 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
2139 if(SiS_Pr->CP_PreferredIndex != -1) {
2140 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2141 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2142 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2143 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2144 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2145 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2146 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2147 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2148 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2149 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2150 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2151 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2152 if(SiS_Pr->CP_PrefClock) {
2153 int idx;
2154 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2155 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2156 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2157 else idx = VCLK_CUSTOM_315;
2158 SiS_Pr->SiS_VCLKData[idx].CLOCK =
2159 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2160 SiS_Pr->SiS_VCLKData[idx].SR2B =
2161 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2162 SiS_Pr->SiS_VCLKData[idx].SR2C =
2163 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2166 break;
2167 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2168 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2169 break;
2172 /* Special cases */
2173 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
2174 (SiS_Pr->SiS_IF_DEF_DSTN) ||
2175 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2176 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2177 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2178 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2179 SiS_Pr->PanelHRS = 999;
2180 SiS_Pr->PanelHRE = 999;
2183 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2184 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2185 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2186 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2187 SiS_Pr->PanelVRS = 999;
2188 SiS_Pr->PanelVRE = 999;
2191 /* DontExpand overrule */
2192 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2194 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2195 /* No scaling for this mode on any panel (LCD=CRT2)*/
2196 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2199 switch(SiS_Pr->SiS_LCDResInfo) {
2201 case Panel_Custom:
2202 case Panel_1152x864:
2203 case Panel_1280x768: /* TMDS only */
2204 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2205 break;
2207 case Panel_800x600: {
2208 static const unsigned char nonscalingmodes[] = {
2209 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2211 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2212 break;
2214 case Panel_1024x768: {
2215 static const unsigned char nonscalingmodes[] = {
2216 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2217 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2218 0xff
2220 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2221 break;
2223 case Panel_1280x720: {
2224 static const unsigned char nonscalingmodes[] = {
2225 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2226 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2227 0xff
2229 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2230 if(SiS_Pr->PanelHT == 1650) {
2231 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2233 break;
2235 case Panel_1280x768_2: { /* LVDS only */
2236 static const unsigned char nonscalingmodes[] = {
2237 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2238 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2239 SIS_RI_1152x768,0xff
2241 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2242 switch(resinfo) {
2243 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2244 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2246 break;
2248 break;
2250 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
2251 static const unsigned char nonscalingmodes[] = {
2252 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2253 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2254 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2256 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2257 break;
2259 case Panel_1280x800_2: { /* SiS LVDS */
2260 static const unsigned char nonscalingmodes[] = {
2261 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2262 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2263 SIS_RI_1152x768,0xff
2265 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2266 switch(resinfo) {
2267 case SIS_RI_1280x720:
2268 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
2269 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2271 break;
2273 break;
2275 case Panel_1280x854: { /* SiS LVDS */
2276 static const unsigned char nonscalingmodes[] = {
2277 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2278 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2279 SIS_RI_1152x768,0xff
2281 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2282 switch(resinfo) {
2283 case SIS_RI_1280x720:
2284 case SIS_RI_1280x768:
2285 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2286 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2288 break;
2290 break;
2292 case Panel_1280x960: {
2293 static const unsigned char nonscalingmodes[] = {
2294 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2295 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2296 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2297 SIS_RI_1280x854,0xff
2299 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2300 break;
2302 case Panel_1280x1024: {
2303 static const unsigned char nonscalingmodes[] = {
2304 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2305 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2306 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2307 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2309 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2310 break;
2312 case Panel_1400x1050: {
2313 static const unsigned char nonscalingmodes[] = {
2314 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2315 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2316 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2317 SIS_RI_1280x960,0xff
2319 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2320 switch(resinfo) {
2321 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2322 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2324 break;
2325 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2326 break;
2328 break;
2330 case Panel_1600x1200: {
2331 static const unsigned char nonscalingmodes[] = {
2332 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2333 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2334 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2335 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2337 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2338 break;
2340 case Panel_1680x1050: {
2341 static const unsigned char nonscalingmodes[] = {
2342 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2343 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2344 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2345 SIS_RI_1360x1024,0xff
2347 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2348 break;
2353 #ifdef CONFIG_FB_SIS_300
2354 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2355 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2356 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2360 if(SiS_Pr->ChipType < SIS_315H) {
2361 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2362 if(SiS_Pr->SiS_UseROM) {
2363 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2364 if(!(ROMAddr[0x235] & 0x02)) {
2365 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2369 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2370 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2371 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2375 #endif
2377 /* Special cases */
2379 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2380 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2383 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2384 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2387 switch(SiS_Pr->SiS_LCDResInfo) {
2388 case Panel_640x480:
2389 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2390 break;
2391 case Panel_1280x800:
2392 /* Don't pass 1:1 by default (TMDS special) */
2393 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2394 break;
2395 case Panel_1280x960:
2396 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2397 break;
2398 case Panel_Custom:
2399 if((!SiS_Pr->CP_PrefClock) ||
2400 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2401 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2403 break;
2406 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2407 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2410 /* (In)validate LCDPass11 flag */
2411 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2412 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2415 /* LVDS DDA */
2416 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2418 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2419 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2420 if(ModeNo == 0x12) {
2421 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2422 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2424 } else if(ModeNo > 0x13) {
2425 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2426 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2427 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2428 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2436 if(modeflag & HalfDCLK) {
2437 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2438 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2439 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2440 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2441 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2442 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2443 } else if(ModeNo > 0x13) {
2444 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2445 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2446 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2447 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2454 /* VESA timing */
2455 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2456 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2457 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2459 } else {
2460 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2463 #if 0
2464 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2465 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2466 #endif
2469 /*********************************************/
2470 /* GET VCLK */
2471 /*********************************************/
2473 unsigned short
2474 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2475 unsigned short RefreshRateTableIndex)
2477 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2478 unsigned short resinfo, tempbx;
2479 const unsigned char *CHTVVCLKPtr = NULL;
2481 if(ModeNo <= 0x13) {
2482 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2483 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2484 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2485 VCLKIndexGENCRT = VCLKIndexGEN;
2486 } else {
2487 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2488 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2489 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2490 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2491 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2494 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2496 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2498 CRT2Index >>= 6;
2499 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2501 if(SiS_Pr->ChipType < SIS_315H) {
2502 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2503 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2504 VCLKIndex = VCLKIndexGEN;
2506 } else {
2507 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2508 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2509 switch(resinfo) {
2510 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2511 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2512 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2513 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2514 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2515 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2516 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2517 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2518 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2519 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2520 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2521 default: VCLKIndex = VCLKIndexGEN;
2524 if(ModeNo <= 0x13) {
2525 if(SiS_Pr->ChipType <= SIS_315PRO) {
2526 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2527 } else {
2528 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2531 if(SiS_Pr->ChipType <= SIS_315PRO) {
2532 if(VCLKIndex == 0) VCLKIndex = 0x41;
2533 if(VCLKIndex == 1) VCLKIndex = 0x43;
2534 if(VCLKIndex == 4) VCLKIndex = 0x44;
2539 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2541 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2542 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2543 else VCLKIndex = HiTVVCLK;
2544 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2545 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2546 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2547 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2548 else VCLKIndex = TVVCLK;
2550 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2551 else VCLKIndex += TVCLKBASE_315;
2553 } else { /* VGA2 */
2555 VCLKIndex = VCLKIndexGENCRT;
2556 if(SiS_Pr->ChipType < SIS_315H) {
2557 if(ModeNo > 0x13) {
2558 if( (SiS_Pr->ChipType == SIS_630) &&
2559 (SiS_Pr->ChipRevision >= 0x30)) {
2560 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2562 /* Better VGA2 clock for 1280x1024@75 */
2563 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2568 } else { /* If not programming CRT2 */
2570 VCLKIndex = VCLKIndexGENCRT;
2571 if(SiS_Pr->ChipType < SIS_315H) {
2572 if(ModeNo > 0x13) {
2573 if( (SiS_Pr->ChipType != SIS_630) &&
2574 (SiS_Pr->ChipType != SIS_300) ) {
2575 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2581 } else { /* LVDS */
2583 VCLKIndex = CRT2Index;
2585 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2587 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2589 VCLKIndex &= 0x1f;
2590 tempbx = 0;
2591 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2592 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2593 tempbx += 2;
2594 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2595 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2597 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2598 tempbx = 4;
2599 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2600 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2601 tempbx = 6;
2602 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2605 switch(tempbx) {
2606 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2607 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2608 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2609 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2610 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2611 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2612 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2613 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2614 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2615 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2617 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2619 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2621 if(SiS_Pr->ChipType < SIS_315H) {
2622 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2623 } else {
2624 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2627 #ifdef CONFIG_FB_SIS_300
2628 /* Special Timing: Barco iQ Pro R series */
2629 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2631 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2632 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2633 if(SiS_Pr->ChipType < SIS_315H) {
2634 VCLKIndex = VCLK34_300;
2635 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2636 } else {
2637 VCLKIndex = VCLK34_315;
2638 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2641 #endif
2643 } else {
2645 VCLKIndex = VCLKIndexGENCRT;
2646 if(SiS_Pr->ChipType < SIS_315H) {
2647 if(ModeNo > 0x13) {
2648 if( (SiS_Pr->ChipType == SIS_630) &&
2649 (SiS_Pr->ChipRevision >= 0x30) ) {
2650 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2656 } else { /* if not programming CRT2 */
2658 VCLKIndex = VCLKIndexGENCRT;
2659 if(SiS_Pr->ChipType < SIS_315H) {
2660 if(ModeNo > 0x13) {
2661 if( (SiS_Pr->ChipType != SIS_630) &&
2662 (SiS_Pr->ChipType != SIS_300) ) {
2663 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2665 #if 0
2666 if(SiS_Pr->ChipType == SIS_730) {
2667 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2668 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2670 #endif
2678 return VCLKIndex;
2681 /*********************************************/
2682 /* SET CRT2 MODE TYPE REGISTERS */
2683 /*********************************************/
2685 static void
2686 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2688 unsigned short i, j, modeflag, tempah=0;
2689 short tempcl;
2690 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2691 unsigned short tempbl;
2692 #endif
2693 #ifdef CONFIG_FB_SIS_315
2694 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2695 unsigned short tempah2, tempbl2;
2696 #endif
2698 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2703 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2705 } else {
2707 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2708 if(SiS_Pr->ChipType >= SIS_315H) {
2709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2712 tempcl = SiS_Pr->SiS_ModeType;
2714 if(SiS_Pr->ChipType < SIS_315H) {
2716 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2718 /* For 301BDH: (with LCD via LVDS) */
2719 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2720 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2721 tempbl &= 0xef;
2722 tempbl |= 0x02;
2723 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2724 tempbl |= 0x10;
2725 tempbl &= 0xfd;
2727 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2730 if(ModeNo > 0x13) {
2731 tempcl -= ModeVGA;
2732 if(tempcl >= 0) {
2733 tempah = ((0x10 >> tempcl) | 0x80);
2735 } else tempah = 0x80;
2737 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2739 #endif /* CONFIG_FB_SIS_300 */
2741 } else {
2743 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2745 if(ModeNo > 0x13) {
2746 tempcl -= ModeVGA;
2747 if(tempcl >= 0) {
2748 tempah = (0x08 >> tempcl);
2749 if (tempah == 0) tempah = 1;
2750 tempah |= 0x40;
2752 } else tempah = 0x40;
2754 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2756 #endif /* CONFIG_FB_SIS_315 */
2760 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2762 if(SiS_Pr->ChipType < SIS_315H) {
2763 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2764 } else {
2765 #ifdef CONFIG_FB_SIS_315
2766 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2767 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2768 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2769 if(IS_SIS740) {
2770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2771 } else {
2772 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2775 #endif
2778 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2780 tempah = 0x01;
2781 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2782 tempah |= 0x02;
2784 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2785 tempah ^= 0x05;
2786 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2787 tempah ^= 0x01;
2791 if(SiS_Pr->ChipType < SIS_315H) {
2793 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2795 tempah = (tempah << 5) & 0xFF;
2796 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2797 tempah = (tempah >> 5) & 0xFF;
2799 } else {
2801 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2802 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2803 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2804 tempah &= ~0x08;
2808 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2809 tempah |= 0x10;
2812 tempah |= 0x80;
2813 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2814 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2818 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2819 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2820 tempah |= 0x20;
2825 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2827 tempah = 0x80;
2828 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2829 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2832 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2835 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2836 tempah |= 0x40;
2840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2842 } else { /* LVDS */
2844 if(SiS_Pr->ChipType >= SIS_315H) {
2846 #ifdef CONFIG_FB_SIS_315
2847 /* LVDS can only be slave in 8bpp modes */
2848 tempah = 0x80;
2849 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2850 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2851 tempah |= 0x02;
2855 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2857 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2859 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2861 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2862 #endif
2864 } else {
2866 #ifdef CONFIG_FB_SIS_300
2867 tempah = 0;
2868 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2869 tempah |= 0x02;
2871 tempah <<= 5;
2873 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2876 #endif
2882 } /* LCDA */
2884 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2886 if(SiS_Pr->ChipType >= SIS_315H) {
2888 #ifdef CONFIG_FB_SIS_315
2889 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2891 /* The following is nearly unpreditable and varies from machine
2892 * to machine. Especially the 301DH seems to be a real trouble
2893 * maker. Some BIOSes simply set the registers (like in the
2894 * NoLCD-if-statements here), some set them according to the
2895 * LCDA stuff. It is very likely that some machines are not
2896 * treated correctly in the following, very case-orientated
2897 * code. What do I do then...?
2900 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2902 if(!(IS_SIS740)) {
2903 tempah = 0x04; /* For all bridges */
2904 tempbl = 0xfb;
2905 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2906 tempah = 0x00;
2907 if(SiS_IsDualEdge(SiS_Pr)) {
2908 tempbl = 0xff;
2911 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2914 /* The following two are responsible for eventually wrong colors
2915 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2916 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2917 * in a 650 box (Jake). What is the criteria?
2918 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2919 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2920 * chipset than the bridge revision.
2923 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2924 tempah = 0x30;
2925 tempbl = 0xc0;
2926 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2927 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2928 tempah = 0x00;
2929 tempbl = 0x00;
2931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2932 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2933 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2934 /* Fixes "TV-blue-bug" on 315+301 */
2935 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2936 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2937 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2938 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2939 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2940 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2941 tempah = 0x30; tempah2 = 0xc0;
2942 tempbl = 0xcf; tempbl2 = 0x3f;
2943 if(SiS_Pr->SiS_TVBlue == 0) {
2944 tempah = tempah2 = 0x00;
2945 } else if(SiS_Pr->SiS_TVBlue == -1) {
2946 /* Set on 651/M650, clear on 315/650 */
2947 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2948 tempah = tempah2 = 0x00;
2951 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2952 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2953 } else {
2954 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2955 tempbl = 0xcf; tempbl2 = 0x3f;
2956 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2957 tempah = tempah2 = 0x00;
2958 if(SiS_IsDualEdge(SiS_Pr)) {
2959 tempbl = tempbl2 = 0xff;
2962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2963 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2966 if(IS_SIS740) {
2967 tempah = 0x80;
2968 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2969 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2970 } else {
2971 tempah = 0x00;
2972 tempbl = 0x7f;
2973 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2974 tempbl = 0xff;
2975 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2977 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2980 #endif /* CONFIG_FB_SIS_315 */
2982 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2984 #ifdef CONFIG_FB_SIS_300
2985 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2987 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2988 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2989 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2991 } else {
2992 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2994 #endif
2998 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2999 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
3000 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3001 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3005 } else { /* LVDS */
3007 #ifdef CONFIG_FB_SIS_315
3008 if(SiS_Pr->ChipType >= SIS_315H) {
3010 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3012 tempah = 0x04;
3013 tempbl = 0xfb;
3014 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3015 tempah = 0x00;
3016 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3018 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3020 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3021 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3024 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3026 } else if(SiS_Pr->ChipType == SIS_550) {
3028 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3029 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3034 #endif
3040 /*********************************************/
3041 /* GET RESOLUTION DATA */
3042 /*********************************************/
3044 unsigned short
3045 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3047 if(ModeNo <= 0x13)
3048 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3049 else
3050 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3053 static void
3054 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3056 unsigned short xres, yres, modeflag=0, resindex;
3058 if(SiS_Pr->UseCustomMode) {
3059 xres = SiS_Pr->CHDisplay;
3060 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3061 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3062 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3063 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3064 return;
3067 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3069 if(ModeNo <= 0x13) {
3070 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3071 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3072 } else {
3073 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3074 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3075 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3078 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3080 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3081 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3082 if(yres == 350) yres = 400;
3084 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3085 if(ModeNo == 0x12) yres = 400;
3089 if(modeflag & HalfDCLK) xres <<= 1;
3090 if(modeflag & DoubleScanMode) yres <<= 1;
3094 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3096 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3097 switch(SiS_Pr->SiS_LCDResInfo) {
3098 case Panel_1024x768:
3099 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3100 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3101 if(yres == 350) yres = 357;
3102 if(yres == 400) yres = 420;
3103 if(yres == 480) yres = 525;
3106 break;
3107 case Panel_1280x1024:
3108 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3109 /* BIOS bug - does this regardless of scaling */
3110 if(yres == 400) yres = 405;
3112 if(yres == 350) yres = 360;
3113 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3114 if(yres == 360) yres = 375;
3116 break;
3117 case Panel_1600x1200:
3118 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3119 if(yres == 1024) yres = 1056;
3121 break;
3125 } else {
3127 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3128 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3129 if(xres == 720) xres = 640;
3131 } else if(xres == 720) xres = 640;
3133 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3134 yres = 400;
3135 if(SiS_Pr->ChipType >= SIS_315H) {
3136 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3137 } else {
3138 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3140 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3144 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3145 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3148 /*********************************************/
3149 /* GET CRT2 TIMING DATA */
3150 /*********************************************/
3152 static void
3153 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3154 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3155 unsigned short *ResIndex)
3157 unsigned short tempbx=0, tempal=0, resinfo=0;
3159 if(ModeNo <= 0x13) {
3160 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3161 } else {
3162 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3163 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3166 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
3170 tempbx = SiS_Pr->SiS_LCDResInfo;
3171 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3173 /* patch index */
3174 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3175 if (resinfo == SIS_RI_1280x800) tempal = 9;
3176 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3177 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3178 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3179 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3180 if (resinfo == SIS_RI_1280x768) tempal = 9;
3183 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3184 /* Pass 1:1 only (center-screen handled outside) */
3185 /* This is never called for the panel's native resolution */
3186 /* since Pass1:1 will not be set in this case */
3187 tempbx = 100;
3188 if(ModeNo >= 0x13) {
3189 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3193 #ifdef CONFIG_FB_SIS_315
3194 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3195 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3196 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3197 tempbx = 200;
3198 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3202 #endif
3204 } else { /* TV */
3206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3207 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3208 tempbx = 2;
3209 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3210 tempbx = 13;
3211 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3213 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3216 else tempbx = 5;
3217 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3218 } else {
3219 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3220 else tempbx = 4;
3221 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3226 tempal &= 0x3F;
3228 if(ModeNo > 0x13) {
3229 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3230 switch(resinfo) {
3231 case SIS_RI_720x480:
3232 tempal = 6;
3233 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
3234 break;
3235 case SIS_RI_720x576:
3236 case SIS_RI_768x576:
3237 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3238 tempal = 6;
3239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3240 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
3242 break;
3243 case SIS_RI_800x480:
3244 tempal = 4;
3245 break;
3246 case SIS_RI_512x384:
3247 case SIS_RI_1024x768:
3248 tempal = 7;
3249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3250 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
3252 break;
3253 case SIS_RI_1280x720:
3254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3255 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3257 break;
3262 *CRT2Index = tempbx;
3263 *ResIndex = tempal;
3265 } else { /* LVDS, 301B-DH (if running on LCD) */
3267 tempbx = 0;
3268 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3270 tempbx = 90;
3271 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3272 tempbx = 92;
3273 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3274 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3276 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3277 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3279 if(tempbx != 99) {
3280 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3283 } else {
3285 switch(SiS_Pr->SiS_LCDResInfo) {
3286 case Panel_640x480: tempbx = 12; break;
3287 case Panel_320x240_1: tempbx = 10; break;
3288 case Panel_320x240_2:
3289 case Panel_320x240_3: tempbx = 14; break;
3290 case Panel_800x600: tempbx = 16; break;
3291 case Panel_1024x600: tempbx = 18; break;
3292 case Panel_1152x768:
3293 case Panel_1024x768: tempbx = 20; break;
3294 case Panel_1280x768: tempbx = 22; break;
3295 case Panel_1280x1024: tempbx = 24; break;
3296 case Panel_1400x1050: tempbx = 26; break;
3297 case Panel_1600x1200: tempbx = 28; break;
3298 #ifdef CONFIG_FB_SIS_300
3299 case Panel_Barco1366: tempbx = 80; break;
3300 #endif
3303 switch(SiS_Pr->SiS_LCDResInfo) {
3304 case Panel_320x240_1:
3305 case Panel_320x240_2:
3306 case Panel_320x240_3:
3307 case Panel_640x480:
3308 break;
3309 default:
3310 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3313 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3315 #ifdef CONFIG_FB_SIS_300
3316 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3317 tempbx = 82;
3318 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3319 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3320 tempbx = 84;
3321 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3323 #endif
3327 (*CRT2Index) = tempbx;
3328 (*ResIndex) = tempal & 0x1F;
3332 static void
3333 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3334 unsigned short RefreshRateTableIndex)
3336 unsigned short tempax=0, tempbx=0, index, dotclock;
3337 unsigned short temp1=0, modeflag=0, tempcx=0;
3339 SiS_Pr->SiS_RVBHCMAX = 1;
3340 SiS_Pr->SiS_RVBHCFACT = 1;
3342 if(ModeNo <= 0x13) {
3344 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3345 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3347 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3348 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3349 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3351 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3353 } else {
3355 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3356 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3358 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3359 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3360 tempax &= 0x03FF;
3361 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3362 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3363 tempcx &= 0x0100;
3364 tempcx <<= 2;
3365 tempbx |= tempcx;
3366 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3368 dotclock = 8;
3372 if(temp1 & 0x01) tempbx |= 0x0100;
3373 if(temp1 & 0x20) tempbx |= 0x0200;
3375 tempax += 5;
3376 tempax *= dotclock;
3377 if(modeflag & HalfDCLK) tempax <<= 1;
3379 tempbx++;
3381 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3382 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3385 static void
3386 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3387 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3389 unsigned short ResIndex;
3391 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3392 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3393 if(SiS_Pr->UseCustomMode) {
3394 ResIndex = SiS_Pr->CHTotal;
3395 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3396 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3397 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3398 } else {
3399 if(ModeNo < 0x13) {
3400 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3401 } else {
3402 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3404 if(ResIndex == 0x09) {
3405 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3406 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3408 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3409 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3410 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3411 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3413 } else {
3414 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3415 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3417 } else {
3418 /* This handles custom modes and custom panels */
3419 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3420 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3421 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3422 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3423 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3424 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3428 static void
3429 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3430 unsigned short RefreshRateTableIndex)
3432 unsigned short CRT2Index, ResIndex, backup;
3433 const struct SiS_LVDSData *LVDSData = NULL;
3435 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3437 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3438 SiS_Pr->SiS_RVBHCMAX = 1;
3439 SiS_Pr->SiS_RVBHCFACT = 1;
3440 SiS_Pr->SiS_NewFlickerMode = 0;
3441 SiS_Pr->SiS_RVBHRS = 50;
3442 SiS_Pr->SiS_RY1COE = 0;
3443 SiS_Pr->SiS_RY2COE = 0;
3444 SiS_Pr->SiS_RY3COE = 0;
3445 SiS_Pr->SiS_RY4COE = 0;
3446 SiS_Pr->SiS_RVBHRS2 = 0;
3449 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3451 #ifdef CONFIG_FB_SIS_315
3452 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3453 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3454 #endif
3456 } else {
3458 /* 301BDH needs LVDS Data */
3459 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3460 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3461 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3464 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3465 &CRT2Index, &ResIndex);
3467 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3469 switch(CRT2Index) {
3470 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3471 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3472 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3473 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3474 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3475 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3476 #ifdef CONFIG_FB_SIS_300
3477 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3478 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3479 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3480 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3481 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3482 #endif
3483 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3484 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3485 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3486 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3487 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3488 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3489 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3490 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3491 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3494 if(LVDSData) {
3495 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3496 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3497 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3498 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3499 } else {
3500 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3503 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3504 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3505 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3506 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3507 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3508 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3509 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3510 #ifdef CONFIG_FB_SIS_300
3511 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3512 if(ResIndex < 0x08) {
3513 SiS_Pr->SiS_HDE = 1280;
3514 SiS_Pr->SiS_VDE = 1024;
3517 #endif
3523 static void
3524 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3525 unsigned short RefreshRateTableIndex)
3527 unsigned char *ROMAddr = NULL;
3528 unsigned short tempax, tempbx, modeflag, romptr=0;
3529 unsigned short resinfo, CRT2Index, ResIndex;
3530 const struct SiS_LCDData *LCDPtr = NULL;
3531 const struct SiS_TVData *TVPtr = NULL;
3532 #ifdef CONFIG_FB_SIS_315
3533 short resinfo661;
3534 #endif
3536 if(ModeNo <= 0x13) {
3537 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3538 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3539 } else if(SiS_Pr->UseCustomMode) {
3540 modeflag = SiS_Pr->CModeFlag;
3541 resinfo = 0;
3542 } else {
3543 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3544 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3545 #ifdef CONFIG_FB_SIS_315
3546 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3547 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3548 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3549 (resinfo661 >= 0) &&
3550 (SiS_Pr->SiS_NeedRomModeData) ) {
3551 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3552 if((romptr = (SISGETROMW(21)))) {
3553 romptr += (resinfo661 * 10);
3554 ROMAddr = SiS_Pr->VirtualRomBase;
3558 #endif
3561 SiS_Pr->SiS_NewFlickerMode = 0;
3562 SiS_Pr->SiS_RVBHRS = 50;
3563 SiS_Pr->SiS_RY1COE = 0;
3564 SiS_Pr->SiS_RY2COE = 0;
3565 SiS_Pr->SiS_RY3COE = 0;
3566 SiS_Pr->SiS_RY4COE = 0;
3567 SiS_Pr->SiS_RVBHRS2 = 0;
3569 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3571 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3573 if(SiS_Pr->UseCustomMode) {
3575 SiS_Pr->SiS_RVBHCMAX = 1;
3576 SiS_Pr->SiS_RVBHCFACT = 1;
3577 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3578 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3580 tempax = SiS_Pr->CHTotal;
3581 if(modeflag & HalfDCLK) tempax <<= 1;
3582 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3583 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3585 } else {
3587 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3591 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3593 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3594 &CRT2Index,&ResIndex);
3596 switch(CRT2Index) {
3597 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3598 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3599 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3600 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3601 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3602 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3603 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3604 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3605 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3606 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3607 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3608 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3609 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3610 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3613 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3614 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3615 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3616 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3617 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3618 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3619 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3620 if(modeflag & HalfDCLK) {
3621 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3622 if(SiS_Pr->SiS_RVBHRS2) {
3623 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3624 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3625 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3626 else SiS_Pr->SiS_RVBHRS2 += tempax;
3628 } else {
3629 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3631 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3635 if((resinfo == SIS_RI_960x600) ||
3636 (resinfo == SIS_RI_1024x768) ||
3637 (resinfo == SIS_RI_1280x1024) ||
3638 (resinfo == SIS_RI_1280x720)) {
3639 SiS_Pr->SiS_NewFlickerMode = 0x40;
3642 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3644 SiS_Pr->SiS_HT = ExtHiTVHT;
3645 SiS_Pr->SiS_VT = ExtHiTVVT;
3646 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3647 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3648 SiS_Pr->SiS_HT = StHiTVHT;
3649 SiS_Pr->SiS_VT = StHiTVVT;
3653 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3656 SiS_Pr->SiS_HT = 1650;
3657 SiS_Pr->SiS_VT = 750;
3658 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3659 SiS_Pr->SiS_HT = NTSCHT;
3660 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3661 SiS_Pr->SiS_VT = NTSCVT;
3662 } else {
3663 SiS_Pr->SiS_HT = NTSCHT;
3664 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3665 SiS_Pr->SiS_VT = NTSCVT;
3668 } else {
3670 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3671 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3672 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3673 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3675 if(modeflag & HalfDCLK) {
3676 SiS_Pr->SiS_RY1COE = 0x00;
3677 SiS_Pr->SiS_RY2COE = 0xf4;
3678 SiS_Pr->SiS_RY3COE = 0x10;
3679 SiS_Pr->SiS_RY4COE = 0x38;
3682 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3683 SiS_Pr->SiS_HT = NTSCHT;
3684 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3685 SiS_Pr->SiS_VT = NTSCVT;
3686 } else {
3687 SiS_Pr->SiS_HT = PALHT;
3688 SiS_Pr->SiS_VT = PALVT;
3693 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3695 SiS_Pr->SiS_RVBHCMAX = 1;
3696 SiS_Pr->SiS_RVBHCFACT = 1;
3698 if(SiS_Pr->UseCustomMode) {
3700 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3701 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3703 tempax = SiS_Pr->CHTotal;
3704 if(modeflag & HalfDCLK) tempax <<= 1;
3705 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3706 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3708 } else {
3710 bool gotit = false;
3712 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3714 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3715 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3716 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3717 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3718 gotit = true;
3720 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3722 #ifdef CONFIG_FB_SIS_315
3723 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3724 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3725 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3726 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3727 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3728 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3729 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3730 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3731 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3732 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3733 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3734 else SiS_Pr->SiS_RVBHRS2 += tempax;
3736 if(SiS_Pr->SiS_VGAHT) gotit = true;
3737 else {
3738 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3739 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3740 SiS_Pr->SiS_RVBHCMAX = 1;
3741 SiS_Pr->SiS_RVBHCFACT = 1;
3742 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3743 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3744 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3745 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3746 SiS_Pr->SiS_RVBHRS2 = 0;
3747 gotit = true;
3749 #endif
3753 if(!gotit) {
3755 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3756 &CRT2Index,&ResIndex);
3758 switch(CRT2Index) {
3759 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3760 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3761 case Panel_1280x720 :
3762 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3763 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3764 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3765 case Panel_1280x800 :
3766 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3767 case Panel_1280x800_2 :
3768 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3769 case Panel_1280x854 :
3770 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3771 case Panel_1280x960 :
3772 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3773 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3774 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3775 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3776 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3777 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3778 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3779 case Panel_1680x1050 :
3780 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3781 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3782 #ifdef CONFIG_FB_SIS_315
3783 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3784 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3785 #endif
3786 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3789 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3790 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3791 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3792 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3793 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3794 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3798 tempax = SiS_Pr->PanelXRes;
3799 tempbx = SiS_Pr->PanelYRes;
3801 switch(SiS_Pr->SiS_LCDResInfo) {
3802 case Panel_1024x768:
3803 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3804 if(SiS_Pr->ChipType < SIS_315H) {
3805 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3806 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3808 } else {
3809 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3810 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3811 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3812 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3813 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3814 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3816 break;
3817 case Panel_1280x960:
3818 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3819 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3820 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3821 break;
3822 case Panel_1280x1024:
3823 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3824 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3825 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3826 break;
3827 case Panel_1600x1200:
3828 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3829 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3830 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3832 break;
3835 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3836 tempax = SiS_Pr->SiS_VGAHDE;
3837 tempbx = SiS_Pr->SiS_VGAVDE;
3840 SiS_Pr->SiS_HDE = tempax;
3841 SiS_Pr->SiS_VDE = tempbx;
3846 static void
3847 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3848 unsigned short RefreshRateTableIndex)
3851 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3853 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3854 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3855 } else {
3856 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3857 /* Need LVDS Data for LCD on 301B-DH */
3858 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3859 } else {
3860 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3864 } else {
3866 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3871 /*********************************************/
3872 /* GET LVDS DES (SKEW) DATA */
3873 /*********************************************/
3875 static const struct SiS_LVDSDes *
3876 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3878 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3880 #ifdef CONFIG_FB_SIS_300
3881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3883 if(SiS_Pr->ChipType < SIS_315H) {
3884 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3885 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3886 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3887 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3888 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3890 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3891 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3892 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3893 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3899 #endif
3900 return PanelDesPtr;
3903 static void
3904 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3905 unsigned short RefreshRateTableIndex)
3907 unsigned short modeflag, ResIndex;
3908 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3910 SiS_Pr->SiS_LCDHDES = 0;
3911 SiS_Pr->SiS_LCDVDES = 0;
3913 /* Some special cases */
3914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3916 /* Trumpion */
3917 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3918 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3919 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3920 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3923 return;
3926 /* 640x480 on LVDS */
3927 if(SiS_Pr->ChipType < SIS_315H) {
3928 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3929 SiS_Pr->SiS_LCDHDES = 8;
3930 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3931 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3932 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3933 return;
3937 } /* LCD */
3939 if( (SiS_Pr->UseCustomMode) ||
3940 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3941 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3942 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3943 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3944 return;
3947 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3948 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3950 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3952 #ifdef CONFIG_FB_SIS_315
3953 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3954 /* non-pass 1:1 only, see above */
3955 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3956 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3958 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3959 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3962 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3963 switch(SiS_Pr->SiS_CustomT) {
3964 case CUT_UNIWILL1024:
3965 case CUT_UNIWILL10242:
3966 case CUT_CLEVO1400:
3967 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3968 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3970 break;
3972 switch(SiS_Pr->SiS_LCDResInfo) {
3973 case Panel_1280x1024:
3974 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3975 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3977 break;
3978 case Panel_1280x800: /* Verified for Averatec 6240 */
3979 case Panel_1280x800_2: /* Verified for Asus A4L */
3980 case Panel_1280x854: /* Not verified yet FIXME */
3981 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3982 break;
3985 #endif
3987 } else {
3989 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3991 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3992 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3995 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3997 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3998 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
4000 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4002 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4003 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4005 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4006 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4007 } else {
4008 if(SiS_Pr->ChipType < SIS_315H) {
4009 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4010 } else {
4011 switch(SiS_Pr->SiS_LCDResInfo) {
4012 case Panel_800x600:
4013 case Panel_1024x768:
4014 case Panel_1280x1024:
4015 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4016 break;
4017 case Panel_1400x1050:
4018 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4019 break;
4024 } else {
4026 if(SiS_Pr->ChipType < SIS_315H) {
4027 #ifdef CONFIG_FB_SIS_300
4028 switch(SiS_Pr->SiS_LCDResInfo) {
4029 case Panel_800x600:
4030 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4031 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4032 } else {
4033 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4034 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4035 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4036 else SiS_Pr->SiS_LCDVDES -= 4;
4038 break;
4039 case Panel_1024x768:
4040 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4041 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4042 } else {
4043 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4044 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4045 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4047 break;
4048 case Panel_1024x600:
4049 default:
4050 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4051 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4052 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4053 } else {
4054 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4056 break;
4059 switch(SiS_Pr->SiS_LCDTypeInfo) {
4060 case 1:
4061 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4062 break;
4063 case 3: /* 640x480 only? */
4064 SiS_Pr->SiS_LCDHDES = 8;
4065 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4066 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4067 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4068 break;
4070 #endif
4071 } else {
4072 #ifdef CONFIG_FB_SIS_315
4073 switch(SiS_Pr->SiS_LCDResInfo) {
4074 case Panel_1024x768:
4075 case Panel_1280x1024:
4076 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4077 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4079 break;
4080 case Panel_320x240_1:
4081 case Panel_320x240_2:
4082 case Panel_320x240_3:
4083 SiS_Pr->SiS_LCDVDES = 524;
4084 break;
4086 #endif
4090 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4091 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4092 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4093 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4094 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4095 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4096 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4097 if(SiS_Pr->ChipType < SIS_315H) {
4098 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4099 } else {
4100 #ifdef CONFIG_FB_SIS_315
4101 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
4102 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4103 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4104 if(!(modeflag & HalfDCLK)) {
4105 SiS_Pr->SiS_LCDHDES = 320;
4106 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4107 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4109 #endif
4118 /*********************************************/
4119 /* DISABLE VIDEO BRIDGE */
4120 /*********************************************/
4122 #ifdef CONFIG_FB_SIS_315
4123 static int
4124 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4126 int ret = 0;
4127 #ifdef SET_PWD
4128 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4129 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4130 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4131 unsigned short temp;
4133 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4134 (romptr) &&
4135 (SiS_Pr->SiS_PWDOffset) ) {
4136 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4137 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4140 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4141 temp = 0x00;
4142 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4143 temp = 0x80;
4144 ret = 1;
4146 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4148 #endif
4149 return ret;
4151 #endif
4153 /* NEVER use any variables (VBInfo), this will be called
4154 * from outside the context of modeswitch!
4155 * MUST call getVBType before calling this
4157 void
4158 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4160 #ifdef CONFIG_FB_SIS_315
4161 unsigned short tempah, pushax=0, modenum;
4162 #endif
4163 unsigned short temp=0;
4165 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4167 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
4169 if(SiS_Pr->ChipType < SIS_315H) {
4171 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4173 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4174 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4175 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4176 } else {
4177 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4179 SiS_PanelDelay(SiS_Pr, 3);
4181 if(SiS_Is301B(SiS_Pr)) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4183 SiS_ShortDelay(SiS_Pr,1);
4185 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4186 SiS_DisplayOff(SiS_Pr);
4187 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4188 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4189 SiS_UnLockCRT2(SiS_Pr);
4190 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4191 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4192 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4194 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4195 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4196 SiS_PanelDelay(SiS_Pr, 2);
4197 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4198 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4199 } else {
4200 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4204 #endif /* CONFIG_FB_SIS_300 */
4206 } else {
4208 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4210 int didpwd = 0;
4211 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4212 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4214 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4216 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4218 #ifdef SET_EMI
4219 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4220 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4221 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4224 #endif
4226 didpwd = SiS_HandlePWD(SiS_Pr);
4228 if( (modenum <= 0x13) ||
4229 (SiS_IsVAMode(SiS_Pr)) ||
4230 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4231 if(!didpwd) {
4232 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4233 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4234 } else {
4235 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4239 if(!custom1) {
4240 SiS_DDC2Delay(SiS_Pr,0xff00);
4241 SiS_DDC2Delay(SiS_Pr,0xe000);
4242 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4243 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4244 if(IS_SIS740) {
4245 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4247 SiS_PanelDelay(SiS_Pr, 3);
4252 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4253 /* if(SiS_Pr->ChipType < SIS_340) {*/
4254 tempah = 0xef;
4255 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4256 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4257 /*}*/
4260 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4261 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4264 tempah = 0x3f;
4265 if(SiS_IsDualEdge(SiS_Pr)) {
4266 tempah = 0x7f;
4267 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4269 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4271 if((SiS_IsVAMode(SiS_Pr)) ||
4272 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4274 SiS_DisplayOff(SiS_Pr);
4275 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4276 SiS_PanelDelay(SiS_Pr, 2);
4278 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4279 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4283 if((!(SiS_IsVAMode(SiS_Pr))) ||
4284 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4286 if(!(SiS_IsDualEdge(SiS_Pr))) {
4287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4288 SiS_DisplayOff(SiS_Pr);
4290 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4292 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4293 SiS_PanelDelay(SiS_Pr, 2);
4296 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4297 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4298 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4299 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4300 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4304 if(SiS_IsNotM650orLater(SiS_Pr)) {
4305 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4308 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4310 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4311 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4312 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4314 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4315 if(!didpwd) {
4316 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4318 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4321 if(!custom1) {
4322 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4323 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4324 if(SiS_IsVAorLCD(SiS_Pr)) {
4325 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4332 #endif /* CONFIG_FB_SIS_315 */
4336 } else { /* ============ For 301 ================ */
4338 if(SiS_Pr->ChipType < SIS_315H) {
4339 #ifdef CONFIG_FB_SIS_300
4340 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4341 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4342 SiS_PanelDelay(SiS_Pr, 3);
4344 #endif
4347 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4348 SiS_DisplayOff(SiS_Pr);
4350 if(SiS_Pr->ChipType >= SIS_315H) {
4351 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4356 if(SiS_Pr->ChipType >= SIS_315H) {
4357 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4358 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4359 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4360 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4361 } else {
4362 #ifdef CONFIG_FB_SIS_300
4363 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4364 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4365 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4366 SiS_PanelDelay(SiS_Pr, 2);
4367 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4369 #endif
4374 } else { /* ============ For LVDS =============*/
4376 if(SiS_Pr->ChipType < SIS_315H) {
4378 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4380 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4381 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4384 if(SiS_Pr->ChipType == SIS_730) {
4385 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4386 SiS_WaitVBRetrace(SiS_Pr);
4388 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4389 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4390 SiS_PanelDelay(SiS_Pr, 3);
4392 } else {
4393 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4394 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4395 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4396 SiS_WaitVBRetrace(SiS_Pr);
4397 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4398 SiS_DisplayOff(SiS_Pr);
4400 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4401 SiS_PanelDelay(SiS_Pr, 3);
4407 SiS_DisplayOff(SiS_Pr);
4409 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4411 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4412 SiS_UnLockCRT2(SiS_Pr);
4413 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4414 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4416 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4417 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4418 SiS_PanelDelay(SiS_Pr, 2);
4419 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4422 #endif /* CONFIG_FB_SIS_300 */
4424 } else {
4426 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4428 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4429 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4430 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4431 /* } */
4434 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4436 if(SiS_Pr->ChipType == SIS_740) {
4437 temp = SiS_GetCH701x(SiS_Pr,0x61);
4438 if(temp < 1) {
4439 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4440 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4443 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4444 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4445 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4449 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4450 (SiS_IsVAMode(SiS_Pr)) ) {
4451 SiS_Chrontel701xBLOff(SiS_Pr);
4452 SiS_Chrontel701xOff(SiS_Pr);
4455 if(SiS_Pr->ChipType != SIS_740) {
4456 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4457 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4458 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4464 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4465 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4466 SiS_PanelDelay(SiS_Pr, 3);
4469 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4470 (!(SiS_IsDualEdge(SiS_Pr))) ||
4471 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4472 SiS_DisplayOff(SiS_Pr);
4475 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4476 (!(SiS_IsDualEdge(SiS_Pr))) ||
4477 (!(SiS_IsVAMode(SiS_Pr))) ) {
4478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4481 if(SiS_Pr->ChipType == SIS_740) {
4482 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4485 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4487 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4488 (!(SiS_IsDualEdge(SiS_Pr))) ||
4489 (!(SiS_IsVAMode(SiS_Pr))) ) {
4490 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4493 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4494 if(SiS_CRT2IsLCD(SiS_Pr)) {
4495 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4496 if(SiS_Pr->ChipType == SIS_550) {
4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4498 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4501 } else {
4502 if(SiS_Pr->ChipType == SIS_740) {
4503 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4504 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4506 } else if(SiS_IsVAMode(SiS_Pr)) {
4507 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4511 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4512 if(SiS_IsDualEdge(SiS_Pr)) {
4513 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4514 } else {
4515 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4519 SiS_UnLockCRT2(SiS_Pr);
4521 if(SiS_Pr->ChipType == SIS_550) {
4522 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4523 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4524 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4525 (!(SiS_IsDualEdge(SiS_Pr))) ||
4526 (!(SiS_IsVAMode(SiS_Pr))) ) {
4527 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4530 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4531 if(SiS_CRT2IsLCD(SiS_Pr)) {
4532 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4533 SiS_PanelDelay(SiS_Pr, 2);
4534 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4539 #endif /* CONFIG_FB_SIS_315 */
4541 } /* 315 series */
4543 } /* LVDS */
4547 /*********************************************/
4548 /* ENABLE VIDEO BRIDGE */
4549 /*********************************************/
4551 /* NEVER use any variables (VBInfo), this will be called
4552 * from outside the context of a mode switch!
4553 * MUST call getVBType before calling this
4555 static
4556 void
4557 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4559 unsigned short temp=0, tempah;
4560 #ifdef CONFIG_FB_SIS_315
4561 unsigned short temp1, pushax=0;
4562 bool delaylong = false;
4563 #endif
4565 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4567 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4569 if(SiS_Pr->ChipType < SIS_315H) {
4571 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4573 if(SiS_CRT2IsLCD(SiS_Pr)) {
4574 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4575 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4576 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4577 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4579 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4580 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4581 SiS_PanelDelay(SiS_Pr, 0);
4586 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4587 (SiS_CRT2IsLCD(SiS_Pr))) {
4589 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4590 SiS_DisplayOn(SiS_Pr);
4591 SiS_UnLockCRT2(SiS_Pr);
4592 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4593 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4594 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4595 } else {
4596 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4598 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4599 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4600 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4601 SiS_PanelDelay(SiS_Pr, 1);
4603 SiS_WaitVBRetrace(SiS_Pr);
4604 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4608 } else {
4610 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4611 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4612 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4613 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4615 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4616 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4617 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4618 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4619 SiS_DisplayOn(SiS_Pr);
4620 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4621 if(SiS_CRT2IsLCD(SiS_Pr)) {
4622 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4623 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4624 SiS_PanelDelay(SiS_Pr, 1);
4626 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4634 #endif /* CONFIG_FB_SIS_300 */
4636 } else {
4638 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4640 #ifdef SET_EMI
4641 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4642 int didpwd = 0;
4643 /* unsigned short emidelay=0; */
4644 #endif
4646 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4647 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4648 #ifdef SET_EMI
4649 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4650 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4652 #endif
4655 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4656 /*if(SiS_Pr->ChipType < SIS_340) { */
4657 tempah = 0x10;
4658 if(SiS_LCDAEnabled(SiS_Pr)) {
4659 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4660 else tempah = 0x08;
4662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4663 /*}*/
4666 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4668 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4669 SiS_DisplayOff(SiS_Pr);
4670 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4671 if(IS_SIS740) {
4672 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4675 didpwd = SiS_HandlePWD(SiS_Pr);
4677 if(SiS_IsVAorLCD(SiS_Pr)) {
4678 if(!didpwd) {
4679 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4680 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4681 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4682 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4683 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4684 SiS_GenericDelay(SiS_Pr, 17664);
4687 } else {
4688 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4689 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4690 SiS_GenericDelay(SiS_Pr, 17664);
4695 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4696 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4697 delaylong = true;
4702 if(!(SiS_IsVAMode(SiS_Pr))) {
4704 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4705 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707 if(!(tempah & SetCRT2ToRAMDAC)) {
4708 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4711 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4713 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4715 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4716 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4718 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4719 SiS_PanelDelay(SiS_Pr, 2);
4722 } else {
4724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4728 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4729 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4731 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4732 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4733 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4734 /* Enable "LVDS PLL power on" (even on 301C) */
4735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4736 /* Enable "LVDS Driver Power on" (even on 301C) */
4737 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4741 tempah = 0xc0;
4742 if(SiS_IsDualEdge(SiS_Pr)) {
4743 tempah = 0x80;
4744 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4746 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4748 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4750 SiS_PanelDelay(SiS_Pr, 2);
4752 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4753 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4755 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4756 #ifdef SET_EMI
4757 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4758 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4759 SiS_GenericDelay(SiS_Pr, 2048);
4761 #endif
4762 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4764 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4765 #ifdef SET_EMI
4766 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4768 if(SiS_Pr->SiS_ROMNew) {
4769 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4770 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4771 if(romptr) {
4772 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4773 SiS_Pr->EMI_30 = 0;
4774 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4775 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4776 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4777 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4778 /* emidelay = SISGETROMW((romptr + 0x22)); */
4779 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4783 /* (P4_30|0x40) */
4784 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4785 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4786 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4787 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4788 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4789 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4790 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4791 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4792 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4794 if(SiS_Pr->HaveEMI) {
4795 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4796 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4797 } else {
4798 r30 = 0;
4801 /* EMI_30 is read at driver start; however, the BIOS sets this
4802 * (if it is used) only if the LCD is in use. In case we caught
4803 * the machine while on TV output, this bit is not set and we
4804 * don't know if it should be set - hence our detection is wrong.
4805 * Work-around this here:
4808 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4809 switch((cr36 & 0x0f)) {
4810 case 2:
4811 r30 |= 0x40;
4812 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4813 if(!SiS_Pr->HaveEMI) {
4814 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4815 if((cr36 & 0xf0) == 0x30) {
4816 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4819 break;
4820 case 3: /* 1280x1024 */
4821 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4822 if(!SiS_Pr->HaveEMI) {
4823 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4824 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4825 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4828 break;
4829 case 9: /* 1400x1050 */
4830 r30 |= 0x40;
4831 if(!SiS_Pr->HaveEMI) {
4832 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4833 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4834 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4837 break;
4838 case 11: /* 1600x1200 - unknown */
4839 r30 |= 0x40;
4840 if(!SiS_Pr->HaveEMI) {
4841 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4846 /* BIOS values don't work so well sometimes */
4847 if(!SiS_Pr->OverruleEMI) {
4848 #ifdef COMPAL_HACK
4849 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4850 if((cr36 & 0x0f) == 0x09) {
4851 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4854 #endif
4855 #ifdef COMPAQ_HACK
4856 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4857 if((cr36 & 0x0f) == 0x03) {
4858 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4861 #endif
4862 #ifdef ASUS_HACK
4863 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4864 if((cr36 & 0x0f) == 0x02) {
4865 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4866 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4867 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4868 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4871 #endif
4874 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4875 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4876 SiS_GenericDelay(SiS_Pr, 2048);
4878 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4879 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4880 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4881 #endif /* SET_EMI */
4883 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4885 #ifdef SET_EMI
4886 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4887 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4888 if(r30 & 0x40) {
4889 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4890 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4891 if(delaylong) {
4892 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4893 delaylong = false;
4895 SiS_WaitVBRetrace(SiS_Pr);
4896 SiS_WaitVBRetrace(SiS_Pr);
4897 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4898 SiS_GenericDelay(SiS_Pr, 1280);
4900 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4901 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4904 #endif
4908 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4909 if(SiS_IsVAorLCD(SiS_Pr)) {
4910 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4911 if(delaylong) {
4912 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4914 SiS_WaitVBRetrace(SiS_Pr);
4915 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4916 SiS_GenericDelay(SiS_Pr, 2048);
4917 SiS_WaitVBRetrace(SiS_Pr);
4919 if(!didpwd) {
4920 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4921 } else {
4922 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4927 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4928 SiS_DisplayOn(SiS_Pr);
4929 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4933 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4934 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4937 #endif /* CONFIG_FB_SIS_315 */
4941 } else { /* ============ For 301 ================ */
4943 if(SiS_Pr->ChipType < SIS_315H) {
4944 if(SiS_CRT2IsLCD(SiS_Pr)) {
4945 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4946 SiS_PanelDelay(SiS_Pr, 0);
4950 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4951 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4952 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4953 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4955 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4957 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4959 if(SiS_Pr->ChipType >= SIS_315H) {
4960 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4961 if(!(temp & 0x80)) {
4962 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4966 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4968 SiS_VBLongWait(SiS_Pr);
4969 SiS_DisplayOn(SiS_Pr);
4970 if(SiS_Pr->ChipType >= SIS_315H) {
4971 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4973 SiS_VBLongWait(SiS_Pr);
4975 if(SiS_Pr->ChipType < SIS_315H) {
4976 if(SiS_CRT2IsLCD(SiS_Pr)) {
4977 SiS_PanelDelay(SiS_Pr, 1);
4978 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4984 } else { /* =================== For LVDS ================== */
4986 if(SiS_Pr->ChipType < SIS_315H) {
4988 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4990 if(SiS_CRT2IsLCD(SiS_Pr)) {
4991 if(SiS_Pr->ChipType == SIS_730) {
4992 SiS_PanelDelay(SiS_Pr, 1);
4993 SiS_PanelDelay(SiS_Pr, 1);
4994 SiS_PanelDelay(SiS_Pr, 1);
4996 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4997 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4998 SiS_PanelDelay(SiS_Pr, 0);
5002 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5003 SiS_DisplayOn(SiS_Pr);
5004 SiS_UnLockCRT2(SiS_Pr);
5005 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5006 if(SiS_BridgeInSlavemode(SiS_Pr)) {
5007 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5008 } else {
5009 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5012 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5013 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5014 SiS_WaitVBRetrace(SiS_Pr);
5015 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5019 if(SiS_CRT2IsLCD(SiS_Pr)) {
5020 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5021 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5022 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5023 SiS_PanelDelay(SiS_Pr, 1);
5024 SiS_PanelDelay(SiS_Pr, 1);
5026 SiS_WaitVBRetrace(SiS_Pr);
5027 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5032 #endif /* CONFIG_FB_SIS_300 */
5034 } else {
5036 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5038 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5039 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
5040 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5041 /*}*/
5044 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5045 if(SiS_CRT2IsLCD(SiS_Pr)) {
5046 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5047 SiS_PanelDelay(SiS_Pr, 0);
5051 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5052 SiS_UnLockCRT2(SiS_Pr);
5054 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5056 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5057 temp = SiS_GetCH701x(SiS_Pr,0x66);
5058 temp &= 0x20;
5059 SiS_Chrontel701xBLOff(SiS_Pr);
5062 if(SiS_Pr->ChipType != SIS_550) {
5063 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5066 if(SiS_Pr->ChipType == SIS_740) {
5067 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5068 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5069 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5074 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5075 if(!(temp1 & 0x80)) {
5076 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5079 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5080 if(temp) {
5081 SiS_Chrontel701xBLOn(SiS_Pr);
5085 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5086 if(SiS_CRT2IsLCD(SiS_Pr)) {
5087 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5088 if(SiS_Pr->ChipType == SIS_550) {
5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5090 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5093 } else if(SiS_IsVAMode(SiS_Pr)) {
5094 if(SiS_Pr->ChipType != SIS_740) {
5095 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5099 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5100 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5103 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5104 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5105 SiS_Chrontel701xOn(SiS_Pr);
5107 if( (SiS_IsVAMode(SiS_Pr)) ||
5108 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5109 SiS_ChrontelDoSomething1(SiS_Pr);
5113 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5114 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5115 if( (SiS_IsVAMode(SiS_Pr)) ||
5116 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5117 SiS_Chrontel701xBLOn(SiS_Pr);
5118 SiS_ChrontelInitTVVSync(SiS_Pr);
5121 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5122 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5123 if(SiS_CRT2IsLCD(SiS_Pr)) {
5124 SiS_PanelDelay(SiS_Pr, 1);
5125 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5130 #endif /* CONFIG_FB_SIS_315 */
5132 } /* 310 series */
5134 } /* LVDS */
5138 /*********************************************/
5139 /* SET PART 1 REGISTER GROUP */
5140 /*********************************************/
5142 /* Set CRT2 OFFSET / PITCH */
5143 static void
5144 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5145 unsigned short RRTI)
5147 unsigned short offset;
5148 unsigned char temp;
5150 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5152 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5157 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5158 if(offset & 0x07) temp++;
5159 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5162 /* Set CRT2 sync and PanelLink mode */
5163 static void
5164 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5166 unsigned short tempah=0, tempbl, infoflag;
5168 tempbl = 0xC0;
5170 if(SiS_Pr->UseCustomMode) {
5171 infoflag = SiS_Pr->CInfoFlag;
5172 } else {
5173 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5176 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
5178 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5179 tempah = 0;
5180 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5181 tempah = SiS_Pr->SiS_LCDInfo;
5182 } else tempah = infoflag >> 8;
5183 tempah &= 0xC0;
5184 tempah |= 0x20;
5185 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5186 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5187 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5188 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5189 tempah |= 0xf0;
5191 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5192 (SiS_Pr->SiS_IF_DEF_DSTN) ||
5193 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5194 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5195 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5196 tempah |= 0x30;
5198 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5199 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5200 tempah &= ~0xc0;
5203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5204 if(SiS_Pr->ChipType >= SIS_315H) {
5205 tempah >>= 3;
5206 tempah &= 0x18;
5207 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5208 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5209 } else {
5210 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5212 } else {
5213 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5216 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5218 if(SiS_Pr->ChipType < SIS_315H) {
5220 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
5222 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
5224 tempah = infoflag >> 8;
5225 tempbl = 0;
5226 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5227 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5228 tempah = SiS_Pr->SiS_LCDInfo;
5229 tempbl = (tempah >> 6) & 0x03;
5232 tempah &= 0xC0;
5233 tempah |= 0x20;
5234 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5235 tempah |= 0xc0;
5236 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5237 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5238 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5241 } else { /* 630 - 301 */
5243 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5244 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5245 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5249 #endif /* CONFIG_FB_SIS_300 */
5251 } else {
5253 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
5255 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5257 tempbl = 0;
5258 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5259 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5260 tempah = infoflag >> 8;
5261 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5262 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5264 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5265 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5266 tempah = infoflag >> 8;
5267 tempbl = 0x03;
5268 } else {
5269 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5270 tempbl = (tempah >> 6) & 0x03;
5271 tempbl |= 0x08;
5272 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5274 tempah &= 0xC0;
5275 tempah |= 0x20;
5276 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5277 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5278 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5279 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5285 } else { /* 315 - TMDS */
5287 tempah = tempbl = infoflag >> 8;
5288 if(!SiS_Pr->UseCustomMode) {
5289 tempbl = 0;
5290 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5291 if(ModeNo <= 0x13) {
5292 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5295 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5296 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5297 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5298 tempah = SiS_Pr->SiS_LCDInfo;
5299 tempbl = (tempah >> 6) & 0x03;
5304 tempah &= 0xC0;
5305 tempah |= 0x20;
5306 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5307 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5308 /* Imitate BIOS bug */
5309 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5311 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5312 tempah >>= 3;
5313 tempah &= 0x18;
5314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5315 } else {
5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5317 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5318 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5319 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5325 #endif /* CONFIG_FB_SIS_315 */
5330 /* Set CRT2 FIFO on 300/540/630/730 */
5331 #ifdef CONFIG_FB_SIS_300
5332 static void
5333 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5335 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5336 unsigned short temp, index, modeidindex, refreshratetableindex;
5337 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5338 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5339 unsigned int data, pci50, pciA0;
5340 static const unsigned char colortharray[] = {
5341 1, 1, 2, 2, 3, 4
5344 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5346 if(!SiS_Pr->CRT1UsesCustomMode) {
5348 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5349 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5350 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5351 SiS_Pr->SiS_SelectCRT2Rate = 0;
5352 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5354 if(CRT1ModeNo >= 0x13) {
5355 /* Get VCLK */
5356 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5357 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5359 /* Get colordepth */
5360 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5361 if(!colorth) colorth++;
5364 } else {
5366 CRT1ModeNo = 0xfe;
5368 /* Get VCLK */
5369 VCLK = SiS_Pr->CSRClock_CRT1;
5371 /* Get color depth */
5372 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5376 if(CRT1ModeNo >= 0x13) {
5377 /* Get MCLK */
5378 if(SiS_Pr->ChipType == SIS_300) {
5379 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5380 } else {
5381 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5383 index &= 0x07;
5384 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5386 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5387 if(!temp) temp++;
5388 temp <<= 2;
5390 data2 = temp - ((colorth * VCLK) / MCLK);
5392 temp = (28 * 16) % data2;
5393 data2 = (28 * 16) / data2;
5394 if(temp) data2++;
5396 if(SiS_Pr->ChipType == SIS_300) {
5398 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5399 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5401 } else {
5403 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5404 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5406 if(SiS_Pr->ChipType == SIS_730) {
5408 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5409 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5411 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5412 index = 0; /* -- do it like the BIOS anyway... */
5414 } else {
5416 pci50 >>= 24;
5417 pciA0 >>= 24;
5419 index = (pci50 >> 1) & 0x07;
5421 if(pci50 & 0x01) index += 6;
5422 if(!(pciA0 & 0x01)) index += 24;
5424 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5428 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5429 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5433 data += data2; /* CRT1 Request Period */
5435 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5436 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5438 if(!SiS_Pr->UseCustomMode) {
5440 CRT2ModeNo = ModeNo;
5441 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5443 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5445 /* Get VCLK */
5446 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5447 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5449 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5450 if(SiS_Pr->SiS_UseROM) {
5451 if(ROMAddr[0x220] & 0x01) {
5452 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5457 } else {
5459 /* Get VCLK */
5460 CRT2ModeNo = 0xfe;
5461 VCLK = SiS_Pr->CSRClock;
5465 /* Get colordepth */
5466 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5467 if(!colorth) colorth++;
5469 data = data * VCLK * colorth;
5470 temp = data % (MCLK << 4);
5471 data = data / (MCLK << 4);
5472 if(temp) data++;
5474 if(data < 6) data = 6;
5475 else if(data > 0x14) data = 0x14;
5477 if(SiS_Pr->ChipType == SIS_300) {
5478 temp = 0x16;
5479 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5480 temp = 0x13;
5481 } else {
5482 temp = 0x16;
5483 if(( (SiS_Pr->ChipType == SIS_630) ||
5484 (SiS_Pr->ChipType == SIS_730) ) &&
5485 (SiS_Pr->ChipRevision >= 0x30))
5486 temp = 0x1b;
5488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5490 if((SiS_Pr->ChipType == SIS_630) &&
5491 (SiS_Pr->ChipRevision >= 0x30)) {
5492 if(data > 0x13) data = 0x13;
5494 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5496 } else { /* If mode <= 0x13, we just restore everything */
5498 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5499 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5503 #endif
5505 /* Set CRT2 FIFO on 315/330 series */
5506 #ifdef CONFIG_FB_SIS_315
5507 static void
5508 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5511 if( (SiS_Pr->ChipType == SIS_760) &&
5512 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5513 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5514 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5515 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5522 } else {
5523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5527 #endif
5529 static unsigned short
5530 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5532 unsigned int tempax,tempbx;
5534 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5535 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5536 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5537 return (unsigned short)tempax;
5540 /* Set Part 1 / SiS bridge slave mode */
5541 static void
5542 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5543 unsigned short RefreshRateTableIndex)
5545 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5546 static const unsigned short CRTranslation[] = {
5547 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5548 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5549 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5550 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5551 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5552 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5555 if(ModeNo <= 0x13) {
5556 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5557 } else if(SiS_Pr->UseCustomMode) {
5558 modeflag = SiS_Pr->CModeFlag;
5559 xres = SiS_Pr->CHDisplay;
5560 } else {
5561 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5562 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5565 /* The following is only done if bridge is in slave mode: */
5567 if(SiS_Pr->ChipType >= SIS_315H) {
5568 if(xres >= 1600) { /* BIOS: == 1600 */
5569 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5573 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5575 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5576 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5578 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5580 SiS_Pr->CHBlankStart += 16;
5583 SiS_Pr->CHBlankEnd = 32;
5584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5585 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5588 temp = SiS_Pr->SiS_VGAHT - 96;
5589 if(!(modeflag & HalfDCLK)) temp -= 32;
5590 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5591 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5592 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5593 temp -= 3;
5594 temp <<= 3;
5595 } else {
5596 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5598 SiS_Pr->CHSyncStart = temp;
5600 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5602 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5604 VGAVDE = SiS_Pr->SiS_VGAVDE;
5605 if (VGAVDE == 357) VGAVDE = 350;
5606 else if(VGAVDE == 360) VGAVDE = 350;
5607 else if(VGAVDE == 375) VGAVDE = 350;
5608 else if(VGAVDE == 405) VGAVDE = 400;
5609 else if(VGAVDE == 420) VGAVDE = 400;
5610 else if(VGAVDE == 525) VGAVDE = 480;
5611 else if(VGAVDE == 1056) VGAVDE = 1024;
5612 SiS_Pr->CVDisplay = VGAVDE;
5614 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5616 SiS_Pr->CVBlankEnd = 1;
5617 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5619 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5620 SiS_Pr->CVSyncStart = VGAVDE + temp;
5622 temp >>= 3;
5623 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5625 SiS_CalcCRRegisters(SiS_Pr, 0);
5626 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5628 for(i = 0; i <= 7; i++) {
5629 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5631 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5632 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5634 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5635 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5637 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5638 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5641 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5642 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5644 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5645 if(modeflag & DoubleScanMode) temp |= 0x80;
5646 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5648 temp = 0;
5649 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5650 if(modeflag & HalfDCLK) temp |= 0x08;
5651 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5656 temp = 0;
5657 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5658 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5660 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5662 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5663 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5666 /* Setup panel link
5667 * This is used for LVDS, LCDA and Chrontel TV output
5668 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5670 static void
5671 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5672 unsigned short RefreshRateTableIndex)
5674 unsigned short modeflag, resinfo = 0;
5675 unsigned short push2, tempax, tempbx, tempcx, temp;
5676 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5677 bool islvds = false, issis = false, chkdclkfirst = false;
5678 #ifdef CONFIG_FB_SIS_300
5679 unsigned short crt2crtc = 0;
5680 #endif
5681 #ifdef CONFIG_FB_SIS_315
5682 unsigned short pushcx;
5683 #endif
5685 if(ModeNo <= 0x13) {
5686 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5687 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5688 #ifdef CONFIG_FB_SIS_300
5689 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5690 #endif
5691 } else if(SiS_Pr->UseCustomMode) {
5692 modeflag = SiS_Pr->CModeFlag;
5693 } else {
5694 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5695 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5696 #ifdef CONFIG_FB_SIS_300
5697 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5698 #endif
5701 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5702 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5703 islvds = true;
5706 /* is really sis if sis bridge, but not 301B-DH */
5707 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5708 issis = true;
5711 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5712 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5713 chkdclkfirst = true;
5717 #ifdef CONFIG_FB_SIS_315
5718 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5719 if(IS_SIS330) {
5720 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5721 } else if(IS_SIS740) {
5722 if(islvds) {
5723 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5725 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5728 } else {
5729 if(islvds) {
5730 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5732 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5733 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5734 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5735 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5736 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5737 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5743 #endif
5745 /* Horizontal */
5747 tempax = SiS_Pr->SiS_LCDHDES;
5748 if(islvds) {
5749 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5750 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5751 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5752 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5753 tempax -= 8;
5759 temp = (tempax & 0x0007);
5760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5761 temp = (tempax >> 3) & 0x00FF;
5762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5764 tempbx = SiS_Pr->SiS_HDE;
5765 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5766 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5767 tempbx = SiS_Pr->PanelXRes;
5769 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5770 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5771 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5772 tempbx >>= 1;
5776 tempax += tempbx;
5777 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5779 temp = tempax;
5780 if(temp & 0x07) temp += 8;
5781 temp >>= 3;
5782 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5784 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5786 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5787 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5788 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5792 tempcx += tempax;
5793 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5795 temp = (tempcx >> 3) & 0x00FF;
5796 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5797 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5798 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5799 switch(ModeNo) {
5800 case 0x04:
5801 case 0x05:
5802 case 0x0d: temp = 0x56; break;
5803 case 0x10: temp = 0x60; break;
5804 case 0x13: temp = 0x5f; break;
5805 case 0x40:
5806 case 0x41:
5807 case 0x4f:
5808 case 0x43:
5809 case 0x44:
5810 case 0x62:
5811 case 0x56:
5812 case 0x53:
5813 case 0x5d:
5814 case 0x5e: temp = 0x54; break;
5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5821 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5822 temp += 2;
5823 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5824 temp += 8;
5825 if(SiS_Pr->PanelHRE != 999) {
5826 temp = tempcx + SiS_Pr->PanelHRE;
5827 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5828 temp >>= 3;
5831 } else {
5832 temp += 10;
5835 temp &= 0x1F;
5836 temp |= ((tempcx & 0x07) << 5);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5839 /* Vertical */
5841 tempax = SiS_Pr->SiS_VGAVDE;
5842 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5843 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5844 tempax = SiS_Pr->PanelYRes;
5848 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5849 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5851 push2 = tempbx;
5853 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5854 if(SiS_Pr->ChipType < SIS_315H) {
5855 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5856 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5857 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5861 if(islvds) tempcx >>= 1;
5862 else tempcx >>= 2;
5864 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5865 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5866 (SiS_Pr->PanelVRS != 999) ) {
5867 tempcx = SiS_Pr->PanelVRS;
5868 tempbx += tempcx;
5869 if(issis) tempbx++;
5870 } else {
5871 tempbx += tempcx;
5872 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5873 else if(issis) tempbx++;
5876 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5878 temp = tempbx & 0x00FF;
5879 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5880 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5881 if(ModeNo == 0x10) temp = 0xa9;
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5886 tempcx >>= 3;
5887 tempcx++;
5889 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5890 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5891 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5895 tempcx += tempbx;
5896 temp = tempcx & 0x000F;
5897 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5899 temp = ((tempbx >> 8) & 0x07) << 3;
5900 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5901 if(SiS_Pr->SiS_HDE != 640) {
5902 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5904 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5905 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5906 tempbx = 0x87;
5907 if((SiS_Pr->ChipType >= SIS_315H) ||
5908 (SiS_Pr->ChipRevision >= 0x30)) {
5909 tempbx = 0x07;
5910 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5911 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5913 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5914 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5916 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5917 } else {
5918 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5922 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5924 tempbx = push2; /* BPLVDEE */
5926 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5928 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5929 switch(SiS_Pr->SiS_LCDResInfo) {
5930 case Panel_640x480:
5931 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5932 tempcx = SiS_Pr->SiS_VGAVDE;
5933 break;
5934 case Panel_800x600:
5935 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5936 if(resinfo == SIS_RI_800x600) tempcx++;
5938 break;
5939 case Panel_1024x600:
5940 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5941 if(resinfo == SIS_RI_1024x600) tempcx++;
5942 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5943 if(resinfo == SIS_RI_800x600) tempcx++;
5946 break;
5947 case Panel_1024x768:
5948 if(SiS_Pr->ChipType < SIS_315H) {
5949 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5950 if(resinfo == SIS_RI_1024x768) tempcx++;
5953 break;
5957 temp = ((tempbx >> 8) & 0x07) << 3;
5958 temp |= ((tempcx >> 8) & 0x07);
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5963 /* Vertical scaling */
5965 if(SiS_Pr->ChipType < SIS_315H) {
5967 #ifdef CONFIG_FB_SIS_300 /* 300 series */
5968 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5969 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5970 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5971 if(temp) tempeax++;
5973 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5975 temp = (unsigned short)(tempeax & 0x00FF);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5977 tempvcfact = temp;
5978 #endif /* CONFIG_FB_SIS_300 */
5980 } else {
5982 #ifdef CONFIG_FB_SIS_315 /* 315 series */
5983 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5984 tempebx = SiS_Pr->SiS_VDE;
5985 temp = (tempeax % tempebx);
5986 tempeax = tempeax / tempebx;
5987 if(temp) tempeax++;
5988 tempvcfact = tempeax;
5990 temp = (unsigned short)(tempeax & 0x00FF);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5992 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5994 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5995 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5998 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5999 temp = (unsigned short)(tempeax & 0x00FF);
6000 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6001 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6002 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6003 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6004 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6005 temp = 0;
6006 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6007 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6009 #endif
6013 /* Horizontal scaling */
6015 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6016 if(chkdclkfirst) {
6017 if(modeflag & HalfDCLK) tempeax >>= 1;
6019 tempebx = tempeax << 16;
6020 if(SiS_Pr->SiS_HDE == tempeax) {
6021 tempecx = 0xFFFF;
6022 } else {
6023 tempecx = tempebx / SiS_Pr->SiS_HDE;
6024 if(SiS_Pr->ChipType >= SIS_315H) {
6025 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6029 if(SiS_Pr->ChipType >= SIS_315H) {
6030 tempeax = (tempebx / tempecx) - 1;
6031 } else {
6032 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6034 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6035 temp = (unsigned short)(tempecx & 0x00FF);
6036 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6038 if(SiS_Pr->ChipType >= SIS_315H) {
6039 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6040 tempbx = (unsigned short)(tempeax & 0xFFFF);
6041 } else {
6042 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6043 tempbx = tempvcfact & 0x3f;
6044 if(tempbx == 0) tempbx = 64;
6045 tempeax /= tempbx;
6046 tempbx = (unsigned short)(tempeax & 0xFFFF);
6048 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6049 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6050 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6051 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6054 temp = ((tempbx >> 8) & 0x07) << 3;
6055 temp = temp | ((tempecx >> 8) & 0x07);
6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6059 tempecx >>= 16; /* BPLHCFACT */
6060 if(!chkdclkfirst) {
6061 if(modeflag & HalfDCLK) tempecx >>= 1;
6063 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6064 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6065 temp = (unsigned short)(tempecx & 0x00FF);
6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6068 #ifdef CONFIG_FB_SIS_315
6069 if(SiS_Pr->ChipType >= SIS_315H) {
6070 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6071 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6072 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6074 } else {
6075 if(islvds) {
6076 if(SiS_Pr->ChipType == SIS_740) {
6077 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6078 } else {
6079 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6084 #endif
6086 #ifdef CONFIG_FB_SIS_300
6087 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6088 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6089 unsigned char *trumpdata;
6090 int i, j = crt2crtc;
6091 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6092 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6093 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6095 if(SiS_Pr->SiS_UseROM) {
6096 trumpdata = &ROMAddr[0x8001 + (j * 80)];
6097 } else {
6098 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6099 trumpdata = &SiS300_TrumpionData[j][0];
6102 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6103 for(i=0; i<5; i++) {
6104 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6106 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6107 if(ModeNo == 0x13) {
6108 for(i=0; i<4; i++) {
6109 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6111 } else if(ModeNo == 0x10) {
6112 for(i=0; i<4; i++) {
6113 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6114 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6118 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6120 #endif
6122 #ifdef CONFIG_FB_SIS_315
6123 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6125 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6131 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6132 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6133 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6134 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6135 tempax += 64;
6136 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6137 temp = (tempax >> 8) << 3;
6138 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6139 tempax += 32; /* Blpe = lBlps+32 */
6140 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6141 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
6142 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6144 tempax = SiS_Pr->SiS_VDE;
6145 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6146 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6147 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6148 tempax >>= 1;
6149 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6150 temp = (tempax >> 8) << 3;
6151 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6153 tempeax = SiS_Pr->SiS_HDE;
6154 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6155 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6156 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6157 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6158 temp = tempeax & 0x7f;
6159 tempeax >>= 7;
6160 if(temp) tempeax++;
6161 temp = tempeax & 0x3f;
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6166 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6168 tempax = SiS_Pr->SiS_HDE;
6169 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6170 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6171 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6172 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6173 pushcx = tempax;
6174 temp = tempax & 0x00FF;
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6176 temp = ((tempax & 0xFF00) >> 8) << 3;
6177 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6179 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6180 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6181 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6182 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6183 tempeax = tempax * pushcx;
6184 temp = tempeax & 0xFF;
6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6186 temp = (tempeax & 0xFF00) >> 8;
6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6188 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6189 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6190 temp = ((tempeax & 0x01000000) >> 24) << 7;
6191 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6199 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6200 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6222 #endif /* CONFIG_FB_SIS_315 */
6225 /* Set Part 1 */
6226 static void
6227 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6228 unsigned short RefreshRateTableIndex)
6230 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6231 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6232 #endif
6233 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6234 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6235 #ifdef CONFIG_FB_SIS_315
6236 unsigned short tempbl=0;
6237 #endif
6239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6240 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6241 return;
6244 if(ModeNo <= 0x13) {
6245 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6246 } else if(SiS_Pr->UseCustomMode) {
6247 modeflag = SiS_Pr->CModeFlag;
6248 } else {
6249 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6250 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6251 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6254 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6256 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6257 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6258 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6260 if(SiS_Pr->ChipType < SIS_315H ) {
6261 #ifdef CONFIG_FB_SIS_300
6262 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6263 #endif
6264 } else {
6265 #ifdef CONFIG_FB_SIS_315
6266 SiS_SetCRT2FIFO_310(SiS_Pr);
6267 #endif
6270 /* 1. Horizontal setup */
6272 if(SiS_Pr->ChipType < SIS_315H ) {
6274 #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
6276 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6279 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6282 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6285 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6286 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6287 tempbx = pushbx + tempcx;
6288 tempcx <<= 1;
6289 tempcx += tempbx;
6291 bridgeadd = 12;
6293 #endif /* CONFIG_FB_SIS_300 */
6295 } else {
6297 #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
6299 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6300 if(modeflag & HalfDCLK) {
6301 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6302 tempcx >>= 1;
6303 } else {
6304 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6305 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6306 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6307 tempcx = SiS_Pr->SiS_HT - tempax;
6311 tempcx--;
6312 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6313 temp = (tempcx >> 4) & 0xF0;
6314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6316 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6317 tempbx = SiS_Pr->SiS_VGAHDE;
6318 tempcx -= tempbx;
6319 tempcx >>= 2;
6320 if(modeflag & HalfDCLK) {
6321 tempbx >>= 1;
6322 tempcx >>= 1;
6324 tempbx += 16;
6326 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6328 pushbx = tempbx;
6329 tempcx >>= 1;
6330 tempbx += tempcx;
6331 tempcx += tempbx;
6333 bridgeadd = 16;
6335 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6336 if(SiS_Pr->ChipType >= SIS_661) {
6337 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6338 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6339 if(resinfo == SIS_RI_1280x1024) {
6340 tempcx = (tempcx & 0xff00) | 0x30;
6341 } else if(resinfo == SIS_RI_1600x1200) {
6342 tempcx = (tempcx & 0xff00) | 0xff;
6348 #endif /* CONFIG_FB_SIS_315 */
6350 } /* 315/330 series */
6352 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6354 if(SiS_Pr->UseCustomMode) {
6355 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6356 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6357 tempax = SiS_Pr->SiS_VGAHT;
6358 if(modeflag & HalfDCLK) tempax >>= 1;
6359 tempax--;
6360 if(tempcx > tempax) tempcx = tempax;
6363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6364 unsigned char cr4, cr14, cr5, cr15;
6365 if(SiS_Pr->UseCustomMode) {
6366 cr4 = SiS_Pr->CCRT1CRTC[4];
6367 cr14 = SiS_Pr->CCRT1CRTC[14];
6368 cr5 = SiS_Pr->CCRT1CRTC[5];
6369 cr15 = SiS_Pr->CCRT1CRTC[15];
6370 } else {
6371 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6372 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6373 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6374 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6376 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6377 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6378 tempcx &= 0x00FF;
6379 tempcx |= (tempbx & 0xFF00);
6380 tempbx += bridgeadd;
6381 tempcx += bridgeadd;
6382 tempax = SiS_Pr->SiS_VGAHT;
6383 if(modeflag & HalfDCLK) tempax >>= 1;
6384 tempax--;
6385 if(tempcx > tempax) tempcx = tempax;
6388 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6389 tempbx = 1040;
6390 tempcx = 1044; /* HWCursor bug! */
6395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6399 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6400 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6402 /* 2. Vertical setup */
6404 tempcx = SiS_Pr->SiS_VGAVT - 1;
6405 temp = tempcx & 0x00FF;
6407 if(SiS_Pr->ChipType < SIS_661) {
6408 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6409 if(SiS_Pr->ChipType < SIS_315H) {
6410 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6411 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6412 temp--;
6415 } else {
6416 temp--;
6418 } else if(SiS_Pr->ChipType >= SIS_315H) {
6419 temp--;
6422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6424 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6427 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6430 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6431 tempbx++;
6432 tempax = tempbx;
6433 tempcx++;
6434 tempcx -= tempax;
6435 tempcx >>= 2;
6436 tempbx += tempcx;
6437 if(tempcx < 4) tempcx = 4;
6438 tempcx >>= 2;
6439 tempcx += tempbx;
6440 tempcx++;
6441 } else {
6442 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6443 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6446 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6447 if(SiS_Pr->UseCustomMode) {
6448 tempbx = SiS_Pr->CVSyncStart;
6449 tempcx = SiS_Pr->CVSyncEnd;
6451 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6452 unsigned char cr8, cr7, cr13;
6453 if(SiS_Pr->UseCustomMode) {
6454 cr8 = SiS_Pr->CCRT1CRTC[8];
6455 cr7 = SiS_Pr->CCRT1CRTC[7];
6456 cr13 = SiS_Pr->CCRT1CRTC[13];
6457 tempcx = SiS_Pr->CCRT1CRTC[9];
6458 } else {
6459 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6460 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6461 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6462 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6464 tempbx = cr8;
6465 if(cr7 & 0x04) tempbx |= 0x0100;
6466 if(cr7 & 0x80) tempbx |= 0x0200;
6467 if(cr13 & 0x08) tempbx |= 0x0400;
6470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6472 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6473 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6475 /* 3. Panel delay compensation */
6477 if(SiS_Pr->ChipType < SIS_315H) {
6479 #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6481 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6482 temp = 0x20;
6483 if(SiS_Pr->ChipType == SIS_300) {
6484 temp = 0x10;
6485 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6488 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6489 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6491 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6492 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6494 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6495 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6496 else temp = 0x20;
6498 if(SiS_Pr->SiS_UseROM) {
6499 if(ROMAddr[0x220] & 0x80) {
6500 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6501 temp = ROMAddr[0x221];
6502 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6503 temp = ROMAddr[0x222];
6504 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6505 temp = ROMAddr[0x223];
6506 else
6507 temp = ROMAddr[0x224];
6510 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6511 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6514 } else {
6515 temp = 0x20;
6516 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6517 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6519 if(SiS_Pr->SiS_UseROM) {
6520 if(ROMAddr[0x220] & 0x80) {
6521 temp = ROMAddr[0x220];
6524 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6525 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6529 temp &= 0x3c;
6531 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6533 #endif /* CONFIG_FB_SIS_300 */
6535 } else {
6537 #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6539 if(SiS_Pr->ChipType < SIS_661) {
6541 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6543 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6544 else temp = 0x00;
6546 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6547 tempbl = 0xF0;
6548 if(SiS_Pr->ChipType == SIS_650) {
6549 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6550 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6554 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6555 temp = 0x08;
6556 tempbl = 0;
6557 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6558 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6562 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6565 } /* < 661 */
6567 tempax = 0;
6568 if(modeflag & DoubleScanMode) tempax |= 0x80;
6569 if(modeflag & HalfDCLK) tempax |= 0x40;
6570 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6572 #endif /* CONFIG_FB_SIS_315 */
6576 } /* Slavemode */
6578 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6579 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6580 /* For 301BDH with LCD, we set up the Panel Link */
6581 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6582 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6583 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6585 } else {
6586 if(SiS_Pr->ChipType < SIS_315H) {
6587 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6588 } else {
6589 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6590 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6591 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6593 } else {
6594 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6600 /*********************************************/
6601 /* SET PART 2 REGISTER GROUP */
6602 /*********************************************/
6604 #ifdef CONFIG_FB_SIS_315
6605 static unsigned char *
6606 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6608 const unsigned char *tableptr = NULL;
6609 unsigned short a, b, p = 0;
6611 a = SiS_Pr->SiS_VGAHDE;
6612 b = SiS_Pr->SiS_HDE;
6613 if(tabletype) {
6614 a = SiS_Pr->SiS_VGAVDE;
6615 b = SiS_Pr->SiS_VDE;
6618 if(a < b) {
6619 tableptr = SiS_Part2CLVX_1;
6620 } else if(a == b) {
6621 tableptr = SiS_Part2CLVX_2;
6622 } else {
6623 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6624 tableptr = SiS_Part2CLVX_4;
6625 } else {
6626 tableptr = SiS_Part2CLVX_3;
6628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6629 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6630 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6631 else tableptr = SiS_Part2CLVX_5;
6632 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6633 tableptr = SiS_Part2CLVX_6;
6635 do {
6636 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6637 p += 0x42;
6638 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6639 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6641 p += 2;
6642 return ((unsigned char *)&tableptr[p]);
6645 static void
6646 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6647 unsigned short RefreshRateTableIndex)
6649 unsigned char *tableptr;
6650 unsigned char temp;
6651 int i, j;
6653 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6655 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6656 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6657 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6660 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6661 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6662 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6665 temp = 0x10;
6666 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6667 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6670 static bool
6671 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6672 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6673 unsigned short *ResIndex)
6676 if(SiS_Pr->ChipType < SIS_315H) return false;
6678 if(ModeNo <= 0x13)
6679 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6680 else
6681 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6683 (*ResIndex) &= 0x3f;
6684 (*CRT2Index) = 0;
6686 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6687 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6688 (*CRT2Index) = 200;
6692 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6693 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6694 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6697 return (((*CRT2Index) != 0));
6699 #endif
6701 #ifdef CONFIG_FB_SIS_300
6702 static void
6703 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6705 unsigned short tempcx;
6706 static const unsigned char atable[] = {
6707 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6708 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6711 if(!SiS_Pr->UseCustomMode) {
6712 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6713 (SiS_Pr->ChipType == SIS_730) ) &&
6714 (SiS_Pr->ChipRevision > 2) ) &&
6715 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6716 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6717 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6718 if(ModeNo == 0x13) {
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6722 } else if((crt2crtc & 0x3F) == 4) {
6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6731 if(SiS_Pr->ChipType < SIS_315H) {
6732 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6733 crt2crtc &= 0x1f;
6734 tempcx = 0;
6735 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6736 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6737 tempcx += 7;
6740 tempcx += crt2crtc;
6741 if(crt2crtc >= 4) {
6742 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6745 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6746 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6747 if(crt2crtc == 4) {
6748 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6752 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6753 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6759 /* For ECS A907. Highly preliminary. */
6760 static void
6761 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6762 unsigned short ModeNo)
6764 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6765 unsigned short crt2crtc, resindex;
6766 int i, j;
6768 if(SiS_Pr->ChipType != SIS_300) return;
6769 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6770 if(SiS_Pr->UseCustomMode) return;
6772 if(ModeNo <= 0x13) {
6773 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6774 } else {
6775 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6778 resindex = crt2crtc & 0x3F;
6779 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6780 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6782 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6783 if(ModeNo > 0x13) {
6784 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6785 resindex = 4;
6788 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6789 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6790 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6791 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6793 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6796 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6800 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6802 #endif
6804 static void
6805 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6807 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6808 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6809 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6811 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6812 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6813 static const unsigned char specialtv[] = {
6814 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6815 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6816 0x58,0xe4,0x73,0xda,0x13
6818 int i, j;
6819 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6820 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6823 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6824 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6827 } else {
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6833 } else {
6834 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6835 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6837 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6838 } else {
6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6840 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6845 static void
6846 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6848 unsigned short temp;
6850 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6851 if(SiS_Pr->SiS_VGAVDE == 525) {
6852 temp = 0xc3;
6853 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6854 temp++;
6855 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6858 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6859 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6860 temp = 0x4d;
6861 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6862 temp++;
6863 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6865 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6870 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6871 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6872 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6873 /* Not always for LV, see SetGrp2 */
6875 temp = 1;
6876 if(ModeNo <= 0x13) temp = 3;
6877 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6879 #if 0
6880 /* 651+301C, for 1280x768 - do I really need that? */
6881 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6882 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6883 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6884 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6885 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6886 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6887 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6888 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6889 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6890 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6891 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6892 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6893 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6894 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6895 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6896 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6900 #endif
6904 static void
6905 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6906 unsigned short RefreshRateTableIndex)
6908 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6909 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6910 unsigned int longtemp, PhaseIndex;
6911 bool newtvphase;
6912 const unsigned char *TimingPoint;
6913 #ifdef CONFIG_FB_SIS_315
6914 unsigned short resindex, CRT2Index;
6915 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6918 #endif
6920 if(ModeNo <= 0x13) {
6921 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6922 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6923 } else if(SiS_Pr->UseCustomMode) {
6924 modeflag = SiS_Pr->CModeFlag;
6925 crt2crtc = 0;
6926 } else {
6927 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6928 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6931 temp = 0;
6932 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6933 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6937 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6939 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6941 PhaseIndex = 0x01; /* SiS_PALPhase */
6942 TimingPoint = SiS_Pr->SiS_PALTiming;
6944 newtvphase = false;
6945 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6946 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6947 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6948 newtvphase = true;
6951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6953 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6954 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6955 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6956 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6957 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6961 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6963 i = 0;
6964 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6965 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6967 TimingPoint = &SiS_YPbPrTable[i][0];
6969 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6971 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6973 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6975 } else {
6977 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6978 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6979 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6983 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6984 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6985 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6988 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6989 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6990 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6991 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6992 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6993 } else {
6994 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6998 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
7002 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7003 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7005 for(i = 0x39; i <= 0x45; i++, j++) {
7006 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7009 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7010 if(SiS_Pr->SiS_ModeType != ModeText) {
7011 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7015 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7018 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7023 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
7024 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7025 else tempax = 440; /* NTSC, YPbPr 525 */
7027 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7028 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7029 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7031 tempax -= SiS_Pr->SiS_VDE;
7032 tempax >>= 1;
7033 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7034 tempax >>= 1;
7036 tempax &= 0x00ff;
7038 temp = tempax + (unsigned short)TimingPoint[0];
7039 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7041 temp = tempax + (unsigned short)TimingPoint[1];
7042 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7044 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7045 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7048 } else {
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7050 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7056 tempcx = SiS_Pr->SiS_HT;
7057 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7058 tempcx--;
7059 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7061 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7063 tempcx = SiS_Pr->SiS_HT >> 1;
7064 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7065 tempcx += 7;
7066 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7067 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7069 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7070 tempbx += tempcx;
7071 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7072 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7074 tempbx += 8;
7075 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7076 tempbx -= 4;
7077 tempcx = tempbx;
7079 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7081 j += 2;
7082 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7083 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7086 tempcx += 8;
7087 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7088 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7090 tempcx = SiS_Pr->SiS_HT >> 1;
7091 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7092 j += 2;
7093 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7094 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7096 tempcx -= 11;
7097 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7098 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7100 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7102 tempbx = SiS_Pr->SiS_VDE;
7103 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7104 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7105 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7106 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7107 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7108 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7109 tempbx >>= 1;
7110 if(SiS_Pr->ChipType >= SIS_315H) {
7111 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7112 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7113 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7114 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7115 if(crt2crtc == 4) tempbx++;
7119 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7120 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7121 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7123 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7124 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7128 tempbx -= 2;
7129 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7131 temp = (tempcx >> 8) & 0x0F;
7132 temp |= ((tempbx >> 2) & 0xC0);
7133 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7134 temp |= 0x10;
7135 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7139 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7140 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7143 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7144 tempbx = SiS_Pr->SiS_VDE;
7145 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7146 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7147 tempbx >>= 1;
7149 tempbx -= 3;
7150 temp = ((tempbx >> 3) & 0x60) | 0x18;
7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7152 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7154 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7155 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7159 tempbx = 0;
7160 if(!(modeflag & HalfDCLK)) {
7161 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7162 tempax = 0;
7163 tempbx |= 0x20;
7167 tempch = tempcl = 0x01;
7168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7169 if(SiS_Pr->SiS_VGAHDE >= 960) {
7170 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7171 tempcl = 0x20;
7172 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7173 tempch = 20;
7174 tempbx &= ~0x20;
7175 } else {
7176 tempch = 25; /* OK */
7182 if(!(tempbx & 0x20)) {
7183 if(modeflag & HalfDCLK) tempcl <<= 1;
7184 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7185 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7186 tempax = longtemp / SiS_Pr->SiS_HDE;
7187 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7188 tempbx |= ((tempax >> 8) & 0x1F);
7189 tempcx = tempax >> 13;
7192 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7193 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7195 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7197 tempcx &= 0x07;
7198 if(tempbx & 0x20) tempcx = 0;
7199 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7201 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7202 tempbx = 0x0382;
7203 tempcx = 0x007e;
7204 } else {
7205 tempbx = 0x0369;
7206 tempcx = 0x0061;
7208 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7209 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7210 temp = (tempcx & 0x0300) >> 6;
7211 temp |= ((tempbx >> 8) & 0x03);
7212 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7213 temp |= 0x10;
7214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7217 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7219 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7220 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7222 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7224 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7225 temp = 0;
7226 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7227 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7232 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7233 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7234 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7235 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7237 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7240 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7241 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7242 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7248 /* From here: Part2 LCD setup */
7250 tempbx = SiS_Pr->SiS_HDE;
7251 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7252 tempbx--; /* RHACTE = HDE - 1 */
7253 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7254 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7256 temp = 0x01;
7257 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7258 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7259 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7260 temp = 0x02;
7261 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7262 temp = 0x01;
7267 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7269 tempbx = SiS_Pr->SiS_VDE - 1;
7270 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7271 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7273 tempcx = SiS_Pr->SiS_VT - 1;
7274 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7275 temp = (tempcx >> 3) & 0xE0;
7276 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7277 /* Enable dithering; only do this for 32bpp mode */
7278 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7279 temp |= 0x10;
7282 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7285 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7288 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7290 #ifdef CONFIG_FB_SIS_315
7291 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7292 &CRT2Index, &resindex)) {
7293 switch(CRT2Index) {
7294 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7295 default:
7296 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7301 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7302 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7304 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7305 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7307 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7308 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7311 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7313 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7315 } else {
7316 #endif
7318 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7319 /* Clevo dual-link 1024x768 */
7320 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7321 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7324 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7325 tempbx = SiS_Pr->SiS_VDE - 1;
7326 tempcx = SiS_Pr->SiS_VT - 1;
7327 } else {
7328 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7331 } else {
7332 tempbx = SiS_Pr->PanelYRes;
7333 tempcx = SiS_Pr->SiS_VT;
7334 tempax = 1;
7335 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7336 tempax = SiS_Pr->PanelYRes;
7337 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7338 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7339 tempax = tempcx = 0;
7340 } else {
7341 tempax -= SiS_Pr->SiS_VDE;
7343 tempax >>= 1;
7345 tempcx -= tempax; /* lcdvdes */
7346 tempbx -= tempax; /* lcdvdee */
7349 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7351 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7352 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7354 temp = (tempbx >> 5) & 0x38;
7355 temp |= ((tempcx >> 8) & 0x07);
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7358 tempax = SiS_Pr->SiS_VDE;
7359 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7360 tempax = SiS_Pr->PanelYRes;
7362 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7363 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7364 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7365 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7369 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7370 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7371 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7372 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7373 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7374 if(tempax % 4) { tempax >>= 2; tempax++; }
7375 else { tempax >>= 2; }
7376 tempbx -= (tempax - 1);
7377 } else {
7378 tempbx -= 10;
7379 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7383 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7384 tempbx++;
7385 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7386 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7387 tempbx = 770;
7388 tempcx = 3;
7393 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7395 if(SiS_Pr->UseCustomMode) {
7396 tempbx = SiS_Pr->CVSyncStart;
7399 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7401 temp = (tempbx >> 4) & 0xF0;
7402 tempbx += (tempcx + 1);
7403 temp |= (tempbx & 0x0F);
7405 if(SiS_Pr->UseCustomMode) {
7406 temp &= 0xf0;
7407 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7410 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7412 #ifdef CONFIG_FB_SIS_300
7413 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7414 #endif
7416 bridgeoffset = 7;
7417 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7418 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7419 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7420 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7421 /* Higher bridgeoffset shifts to the LEFT */
7423 temp = 0;
7424 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7425 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7426 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7427 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7430 temp += bridgeoffset;
7431 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7432 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7434 tempcx = SiS_Pr->SiS_HT;
7435 tempax = tempbx = SiS_Pr->SiS_HDE;
7436 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7437 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7438 tempax = SiS_Pr->PanelXRes;
7439 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7442 if(SiS_IsDualLink(SiS_Pr)) {
7443 tempcx >>= 1;
7444 tempbx >>= 1;
7445 tempax >>= 1;
7448 tempbx += bridgeoffset;
7450 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7451 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7453 tempcx = (tempcx - tempax) >> 2;
7455 tempbx += tempcx;
7456 push2 = tempbx;
7458 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7459 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7460 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7461 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7466 if(SiS_Pr->UseCustomMode) {
7467 tempbx = SiS_Pr->CHSyncStart;
7468 if(modeflag & HalfDCLK) tempbx <<= 1;
7469 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7470 tempbx += bridgeoffset;
7473 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7474 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7476 tempbx = push2;
7478 tempcx <<= 1;
7479 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7480 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7482 tempbx += tempcx;
7484 if(SiS_Pr->UseCustomMode) {
7485 tempbx = SiS_Pr->CHSyncEnd;
7486 if(modeflag & HalfDCLK) tempbx <<= 1;
7487 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7488 tempbx += bridgeoffset;
7491 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7493 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7495 #ifdef CONFIG_FB_SIS_300
7496 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7497 #endif
7498 #ifdef CONFIG_FB_SIS_315
7499 } /* CRT2-LCD from table */
7500 #endif
7503 /*********************************************/
7504 /* SET PART 3 REGISTER GROUP */
7505 /*********************************************/
7507 static void
7508 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7510 unsigned short i;
7511 const unsigned char *tempdi;
7513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7515 #ifndef SIS_CP
7516 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7517 #else
7518 SIS_CP_INIT301_CP
7519 #endif
7521 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7522 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7523 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7524 } else {
7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7526 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7529 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7530 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7531 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7532 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7535 tempdi = NULL;
7536 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7537 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7538 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7539 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7541 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7542 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7543 tempdi = SiS_HiTVGroup3_1;
7544 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7547 if(tempdi) {
7548 for(i=0; i<=0x3E; i++) {
7549 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7551 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7552 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7558 #ifdef SIS_CP
7559 SIS_CP_INIT301_CP2
7560 #endif
7563 /*********************************************/
7564 /* SET PART 4 REGISTER GROUP */
7565 /*********************************************/
7567 #ifdef CONFIG_FB_SIS_315
7568 #if 0
7569 static void
7570 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7572 unsigned short temp, temp1, temp2;
7574 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7575 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7576 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7577 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7578 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7579 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7580 temp = (unsigned short)((int)(temp) + shift);
7581 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7582 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7583 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7584 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7585 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7586 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7588 #endif
7590 static void
7591 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7593 unsigned short temp, temp1;
7594 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7596 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7597 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7599 if(SiS_Pr->ChipType >= XGI_20) return;
7601 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7602 if(!(ROMAddr[0x61] & 0x04)) return;
7605 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7606 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7607 if(!(temp & 0x01)) {
7608 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7609 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7610 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7611 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7613 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7614 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7615 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7616 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7617 else temp = 0x0402;
7618 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7619 temp1 = 0;
7620 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7621 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7622 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7624 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7625 if(ModeNo > 0x13) {
7626 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7628 } else {
7629 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7630 if(temp1 == 0x01) temp |= 0x01;
7631 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7632 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7633 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7634 if(ModeNo > 0x13) {
7635 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7639 #if 0
7640 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7641 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7642 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7643 if(resinfo == SIS_RI_1024x768) {
7644 SiS_ShiftXPos(SiS_Pr, 97);
7645 } else {
7646 SiS_ShiftXPos(SiS_Pr, 111);
7648 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7649 SiS_ShiftXPos(SiS_Pr, 136);
7653 #endif
7658 #endif
7660 static void
7661 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7662 unsigned short RefreshRateTableIndex)
7664 unsigned short vclkindex, temp, reg1, reg2;
7666 if(SiS_Pr->UseCustomMode) {
7667 reg1 = SiS_Pr->CSR2B;
7668 reg2 = SiS_Pr->CSR2C;
7669 } else {
7670 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7671 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7672 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7675 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7676 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7680 } else {
7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7684 } else {
7685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7686 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7690 temp = 0x08;
7691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7692 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7695 static void
7696 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7698 if(SiS_Pr->ChipType >= SIS_315H) {
7699 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7700 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7701 (SiS_IsVAMode(SiS_Pr))) {
7702 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7703 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7704 } else {
7705 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7710 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7711 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7712 #ifdef SET_EMI
7713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7714 #endif
7715 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7719 static void
7720 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7721 unsigned short RefreshRateTableIndex)
7723 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7724 unsigned int tempebx, tempeax, templong;
7726 if(ModeNo <= 0x13) {
7727 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7728 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7729 } else if(SiS_Pr->UseCustomMode) {
7730 modeflag = SiS_Pr->CModeFlag;
7731 resinfo = 0;
7732 } else {
7733 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7734 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7737 if(SiS_Pr->ChipType >= SIS_315H) {
7738 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7740 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7745 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7747 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7751 if(SiS_Pr->ChipType >= SIS_315H) {
7752 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7753 SiS_SetDualLinkEtc(SiS_Pr);
7754 return;
7758 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7760 tempbx = SiS_Pr->SiS_RVBHCMAX;
7761 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7763 temp = (tempbx >> 1) & 0x80;
7765 tempcx = SiS_Pr->SiS_VGAHT - 1;
7766 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7768 temp |= ((tempcx >> 5) & 0x78);
7770 tempcx = SiS_Pr->SiS_VGAVT - 1;
7771 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7772 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7774 temp |= ((tempcx >> 8) & 0x07);
7775 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7777 tempbx = SiS_Pr->SiS_VGAHDE;
7778 if(modeflag & HalfDCLK) tempbx >>= 1;
7779 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7782 temp = 0;
7783 if(tempbx > 800) temp = 0x60;
7784 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7785 temp = 0;
7786 if(tempbx > 1024) temp = 0xC0;
7787 else if(tempbx >= 960) temp = 0xA0;
7788 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7789 temp = 0;
7790 if(tempbx >= 1280) temp = 0x40;
7791 else if(tempbx >= 1024) temp = 0x20;
7792 } else {
7793 temp = 0x80;
7794 if(tempbx >= 1024) temp = 0xA0;
7797 temp |= SiS_Pr->Init_P4_0E;
7799 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7801 temp &= 0xf0;
7802 temp |= 0x0A;
7806 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7808 tempeax = SiS_Pr->SiS_VGAVDE;
7809 tempebx = SiS_Pr->SiS_VDE;
7810 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7811 if(!(temp & 0xE0)) tempebx >>=1;
7814 tempcx = SiS_Pr->SiS_RVBHRS;
7815 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7816 tempcx >>= 8;
7817 tempcx |= 0x40;
7819 if(tempeax <= tempebx) {
7820 tempcx ^= 0x40;
7821 } else {
7822 tempeax -= tempebx;
7825 tempeax *= (256 * 1024);
7826 templong = tempeax % tempebx;
7827 tempeax /= tempebx;
7828 if(templong) tempeax++;
7830 temp = (unsigned short)(tempeax & 0x000000FF);
7831 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7832 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7834 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7835 temp |= (tempcx & 0x4F);
7836 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7838 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7842 /* Calc Linebuffer max address and set/clear decimode */
7843 tempbx = 0;
7844 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7845 tempax = SiS_Pr->SiS_VGAHDE;
7846 if(modeflag & HalfDCLK) tempax >>= 1;
7847 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7848 if(tempax > 800) {
7849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7850 tempax -= 800;
7851 } else {
7852 tempbx = 0x08;
7853 if(tempax == 960) tempax *= 25; /* Correct */
7854 else if(tempax == 1024) tempax *= 25;
7855 else tempax *= 20;
7856 temp = tempax % 32;
7857 tempax /= 32;
7858 if(temp) tempax++;
7859 tempax++;
7860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7861 if(resinfo == SIS_RI_1024x768 ||
7862 resinfo == SIS_RI_1024x576 ||
7863 resinfo == SIS_RI_1280x1024 ||
7864 resinfo == SIS_RI_1280x720) {
7865 /* Otherwise white line or garbage at right edge */
7866 tempax = (tempax & 0xff00) | 0x20;
7871 tempax--;
7872 temp = ((tempax >> 4) & 0x30) | tempbx;
7873 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7874 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7876 temp = 0x0036; tempbx = 0xD0;
7877 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7878 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7881 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7882 temp |= 0x01;
7883 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7884 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7885 temp &= ~0x01;
7890 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7892 tempbx = SiS_Pr->SiS_HT >> 1;
7893 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7894 tempbx -= 2;
7895 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7896 temp = (tempbx >> 5) & 0x38;
7897 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7899 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7901 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7902 /* LCD-too-dark-error-source, see FinalizeLCD() */
7906 SiS_SetDualLinkEtc(SiS_Pr);
7908 } /* 301B */
7910 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7913 /*********************************************/
7914 /* SET PART 5 REGISTER GROUP */
7915 /*********************************************/
7917 static void
7918 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7921 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7923 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7924 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7925 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7926 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7931 /*********************************************/
7932 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7933 /*********************************************/
7935 static bool
7936 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7937 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7938 unsigned short *DisplayType)
7940 unsigned short modeflag = 0;
7941 bool checkhd = true;
7943 /* Pass 1:1 not supported here */
7945 if(ModeNo <= 0x13) {
7946 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7947 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7948 } else {
7949 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7950 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7953 (*ResIndex) &= 0x3F;
7955 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7957 (*DisplayType) = 80;
7958 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7959 (*DisplayType) = 82;
7960 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7961 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7964 if((*DisplayType) != 84) {
7965 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7968 } else {
7970 (*DisplayType = 0);
7971 switch(SiS_Pr->SiS_LCDResInfo) {
7972 case Panel_320x240_1: (*DisplayType) = 50;
7973 checkhd = false;
7974 break;
7975 case Panel_320x240_2: (*DisplayType) = 14;
7976 break;
7977 case Panel_320x240_3: (*DisplayType) = 18;
7978 break;
7979 case Panel_640x480: (*DisplayType) = 10;
7980 break;
7981 case Panel_1024x600: (*DisplayType) = 26;
7982 break;
7983 default: return true;
7986 if(checkhd) {
7987 if(modeflag & HalfDCLK) (*DisplayType)++;
7990 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7991 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7996 return true;
7999 static void
8000 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8001 unsigned short RefreshRateTableIndex)
8003 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8004 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8005 static const unsigned short CRIdx[] = {
8006 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8007 0x07, 0x10, 0x11, 0x15, 0x16
8010 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8011 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8012 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
8013 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8014 return;
8016 if(SiS_Pr->SiS_IF_DEF_LVDS) {
8017 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8018 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8020 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8021 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8022 } else return;
8024 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8026 if(SiS_Pr->ChipType < SIS_315H) {
8027 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8030 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8031 &ResIndex, &DisplayType))) {
8032 return;
8035 switch(DisplayType) {
8036 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
8037 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
8038 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
8039 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
8040 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
8041 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8042 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8043 #if 0 /* Works better with calculated numbers */
8044 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
8045 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
8046 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
8047 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
8048 #endif
8049 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
8050 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
8051 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
8052 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
8053 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8056 if(LVDSCRT1Ptr) {
8058 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8060 for(i = 0; i <= 10; i++) {
8061 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8062 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8065 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8066 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8067 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8070 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8071 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8073 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8074 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8076 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8077 if(modeflag & DoubleScanMode) tempah |= 0x80;
8078 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8080 } else {
8082 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8087 /*********************************************/
8088 /* SET CRT2 ECLK */
8089 /*********************************************/
8091 static void
8092 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8093 unsigned short RefreshRateTableIndex)
8095 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8096 unsigned short clkbase, vclkindex = 0;
8097 unsigned char sr2b, sr2c;
8099 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8100 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8101 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8102 RefreshRateTableIndex--;
8104 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8105 RefreshRateTableIndex);
8106 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8107 } else {
8108 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8109 RefreshRateTableIndex);
8112 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8113 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8115 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8116 if(SiS_Pr->SiS_UseROM) {
8117 if(ROMAddr[0x220] & 0x01) {
8118 sr2b = ROMAddr[0x227];
8119 sr2c = ROMAddr[0x228];
8124 clkbase = 0x02B;
8125 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8126 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8127 clkbase += 3;
8131 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8132 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8133 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8134 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8135 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8136 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8137 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8139 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8142 /*********************************************/
8143 /* SET UP CHRONTEL CHIPS */
8144 /*********************************************/
8146 static void
8147 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8148 unsigned short RefreshRateTableIndex)
8150 unsigned short TVType, resindex;
8151 const struct SiS_CHTVRegData *CHTVRegData = NULL;
8153 if(ModeNo <= 0x13)
8154 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8155 else
8156 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8158 resindex &= 0x3F;
8160 TVType = 0;
8161 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8162 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8163 TVType += 2;
8164 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8165 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8167 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8168 TVType = 4;
8169 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8170 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8171 TVType = 6;
8172 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8176 switch(TVType) {
8177 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8178 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8179 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8180 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8181 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8182 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8183 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8184 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8185 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8186 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8190 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8192 #ifdef CONFIG_FB_SIS_300
8194 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8196 /* We don't support modes >800x600 */
8197 if (resindex > 5) return;
8199 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8200 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8201 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8202 } else {
8203 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8204 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8207 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8208 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8209 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8210 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8211 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8213 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8214 minimum text enhancement (S3-2=10),
8215 maximum flicker filter for Chroma channel (S5-4=10)
8216 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8218 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8220 /* Set video bandwidth
8221 High bandwidth Luma composite video filter(S0=1)
8222 low bandwidth Luma S-video filter (S2-1=00)
8223 disable peak filter in S-video channel (S3=0)
8224 high bandwidth Chroma Filter (S5-4=11)
8225 =00110001=0x31
8227 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8229 /* Register 0x3D does not exist in non-macrovision register map
8230 (Maybe this is a macrovision register?)
8232 #ifndef SIS_CP
8233 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8234 #endif
8236 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8237 all other bits a read-only. Macrovision?
8239 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8241 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8242 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8244 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8246 /* Clear DSEN
8248 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8250 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8251 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8252 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8254 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8255 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8261 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8264 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8265 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8267 } else {
8268 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8270 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8271 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8272 #if 0
8273 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8274 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8275 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8276 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8280 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8281 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8282 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8283 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8284 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8285 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8288 } else { /* ---- PAL ---- */
8289 /* We don't play around with FSCI in PAL mode */
8290 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */
8291 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */
8294 #endif /* 300 */
8296 } else {
8298 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8300 #ifdef CONFIG_FB_SIS_315
8302 unsigned short temp;
8304 /* We don't support modes >1024x768 */
8305 if (resindex > 6) return;
8307 temp = CHTVRegData[resindex].Reg[0];
8308 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8309 SiS_SetCH701x(SiS_Pr,0x00,temp);
8311 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8312 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8313 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8314 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8315 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8316 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8318 temp = CHTVRegData[resindex].Reg[7];
8319 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8320 SiS_SetCH701x(SiS_Pr,0x07,temp);
8322 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8323 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8324 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8325 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8326 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8327 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8328 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8329 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8331 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8332 /* D1 should be set for PAL, PAL-N and NTSC-J,
8333 but I won't do that for PAL unless somebody
8334 tells me to do so. Since the BIOS uses
8335 non-default CIV values and blacklevels,
8336 this might be compensated anyway.
8338 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8339 SiS_SetCH701x(SiS_Pr,0x21,temp);
8341 #endif /* 315 */
8345 #ifdef SIS_CP
8346 SIS_CP_INIT301_CP3
8347 #endif
8351 #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8353 void
8354 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8356 unsigned short temp;
8358 /* Enable Chrontel 7019 LCD panel backlight */
8359 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8360 if(SiS_Pr->ChipType == SIS_740) {
8361 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8362 } else {
8363 temp = SiS_GetCH701x(SiS_Pr,0x66);
8364 temp |= 0x20;
8365 SiS_SetCH701x(SiS_Pr,0x66,temp);
8370 void
8371 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8373 unsigned short temp;
8375 /* Disable Chrontel 7019 LCD panel backlight */
8376 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8377 temp = SiS_GetCH701x(SiS_Pr,0x66);
8378 temp &= 0xDF;
8379 SiS_SetCH701x(SiS_Pr,0x66,temp);
8383 static void
8384 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8386 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8387 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8388 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8389 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8391 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8393 const unsigned char *tableptr = NULL;
8394 int i;
8396 /* Set up Power up/down timing */
8398 if(SiS_Pr->ChipType == SIS_740) {
8399 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8400 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8401 else tableptr = table1024_740;
8402 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8403 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8404 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8405 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8406 else tableptr = table1400_740;
8407 } else return;
8408 } else {
8409 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8410 tableptr = table1024_650;
8411 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8412 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8413 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8414 tableptr = table1400_650;
8415 } else return;
8418 for(i=0; i<5; i++) {
8419 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8423 static void
8424 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8426 const unsigned char *tableptr = NULL;
8427 unsigned short tempbh;
8428 int i;
8429 static const unsigned char regtable[] = {
8430 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8431 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8433 static const unsigned char table1024_740[] = {
8434 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8435 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8437 static const unsigned char table1280_740[] = {
8438 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8439 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8441 static const unsigned char table1400_740[] = {
8442 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8443 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8445 static const unsigned char table1600_740[] = {
8446 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8447 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8449 static const unsigned char table1024_650[] = {
8450 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8451 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8453 static const unsigned char table1280_650[] = {
8454 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8455 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8457 static const unsigned char table1400_650[] = {
8458 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8459 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8461 static const unsigned char table1600_650[] = {
8462 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8463 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8466 if(SiS_Pr->ChipType == SIS_740) {
8467 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8468 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8470 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8471 else return;
8472 } else {
8473 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8474 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8475 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8477 else return;
8480 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8481 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8482 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8483 if(tempbh == 0xc8) {
8484 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8485 } else if(tempbh == 0xdb) {
8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8487 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8488 } else if(tempbh == 0xde) {
8489 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8493 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8494 else tempbh = 0x0c;
8496 for(i = 0; i < tempbh; i++) {
8497 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8499 SiS_ChrontelPowerSequencing(SiS_Pr);
8500 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8501 tempbh |= 0xc0;
8502 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8504 if(SiS_Pr->ChipType == SIS_740) {
8505 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8506 tempbh &= 0xfb;
8507 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8508 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8509 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8510 tempbh |= 0x40;
8511 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8512 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8513 tempbh &= 0x3f;
8514 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8518 static void
8519 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8521 unsigned char temp, temp1;
8523 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8524 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8525 temp = SiS_GetCH701x(SiS_Pr,0x47);
8526 temp &= 0x7f; /* Use external VSYNC */
8527 SiS_SetCH701x(SiS_Pr,0x47,temp);
8528 SiS_LongDelay(SiS_Pr, 3);
8529 temp = SiS_GetCH701x(SiS_Pr,0x47);
8530 temp |= 0x80; /* Use internal VSYNC */
8531 SiS_SetCH701x(SiS_Pr,0x47,temp);
8532 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8535 static void
8536 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8538 unsigned short temp;
8540 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8541 if(SiS_Pr->ChipType == SIS_740) {
8542 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8543 temp |= 0x04; /* Invert XCLK phase */
8544 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8546 if(SiS_IsYPbPr(SiS_Pr)) {
8547 temp = SiS_GetCH701x(SiS_Pr,0x01);
8548 temp &= 0x3f;
8549 temp |= 0x80; /* Enable YPrPb (HDTV) */
8550 SiS_SetCH701x(SiS_Pr,0x01,temp);
8552 if(SiS_IsChScart(SiS_Pr)) {
8553 temp = SiS_GetCH701x(SiS_Pr,0x01);
8554 temp &= 0x3f;
8555 temp |= 0xc0; /* Enable SCART + CVBS */
8556 SiS_SetCH701x(SiS_Pr,0x01,temp);
8558 if(SiS_Pr->ChipType == SIS_740) {
8559 SiS_ChrontelResetVSync(SiS_Pr);
8560 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8561 } else {
8562 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8563 temp = SiS_GetCH701x(SiS_Pr,0x49);
8564 if(SiS_IsYPbPr(SiS_Pr)) {
8565 temp = SiS_GetCH701x(SiS_Pr,0x73);
8566 temp |= 0x60;
8567 SiS_SetCH701x(SiS_Pr,0x73,temp);
8569 temp = SiS_GetCH701x(SiS_Pr,0x47);
8570 temp &= 0x7f;
8571 SiS_SetCH701x(SiS_Pr,0x47,temp);
8572 SiS_LongDelay(SiS_Pr, 2);
8573 temp = SiS_GetCH701x(SiS_Pr,0x47);
8574 temp |= 0x80;
8575 SiS_SetCH701x(SiS_Pr,0x47,temp);
8580 static void
8581 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8583 unsigned short temp;
8585 /* Complete power down of LVDS */
8586 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8587 if(SiS_Pr->ChipType == SIS_740) {
8588 SiS_LongDelay(SiS_Pr, 1);
8589 SiS_GenericDelay(SiS_Pr, 5887);
8590 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8591 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8592 } else {
8593 SiS_LongDelay(SiS_Pr, 2);
8594 temp = SiS_GetCH701x(SiS_Pr,0x76);
8595 temp &= 0xfc;
8596 SiS_SetCH701x(SiS_Pr,0x76,temp);
8597 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8602 static void
8603 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8605 unsigned short temp;
8607 if(SiS_Pr->ChipType == SIS_740) {
8609 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8610 temp &= 0x01;
8611 if(!temp) {
8613 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8614 temp = SiS_GetCH701x(SiS_Pr,0x49);
8615 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8618 /* Reset Chrontel 7019 datapath */
8619 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8620 SiS_LongDelay(SiS_Pr, 1);
8621 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8623 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8624 SiS_ChrontelResetVSync(SiS_Pr);
8625 SiS_SetCH701x(SiS_Pr,0x49,temp);
8628 } else {
8630 /* Clear/set/clear GPIO */
8631 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8632 temp &= 0xef;
8633 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8634 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8635 temp |= 0x10;
8636 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8637 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8638 temp &= 0xef;
8639 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8640 temp = SiS_GetCH701x(SiS_Pr,0x61);
8641 if(!temp) {
8642 SiS_SetCH701xForLCD(SiS_Pr);
8646 } else { /* 650 */
8647 /* Reset Chrontel 7019 datapath */
8648 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8649 SiS_LongDelay(SiS_Pr, 1);
8650 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8654 static void
8655 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8657 unsigned short temp;
8659 if(SiS_Pr->ChipType == SIS_740) {
8661 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8662 SiS_ChrontelResetVSync(SiS_Pr);
8665 } else {
8667 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8668 temp = SiS_GetCH701x(SiS_Pr,0x49);
8669 temp &= 1;
8670 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8671 temp = SiS_GetCH701x(SiS_Pr,0x47);
8672 temp &= 0x70;
8673 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8674 SiS_LongDelay(SiS_Pr, 3);
8675 temp = SiS_GetCH701x(SiS_Pr,0x47);
8676 temp |= 0x80;
8677 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8683 static void
8684 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8686 unsigned short temp,temp1;
8688 if(SiS_Pr->ChipType == SIS_740) {
8690 temp = SiS_GetCH701x(SiS_Pr,0x61);
8691 if(temp < 1) {
8692 temp++;
8693 SiS_SetCH701x(SiS_Pr,0x61,temp);
8695 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8696 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8697 SiS_LongDelay(SiS_Pr, 1);
8698 SiS_GenericDelay(SiS_Pr, 5887);
8700 } else { /* 650 */
8702 temp1 = 0;
8703 temp = SiS_GetCH701x(SiS_Pr,0x61);
8704 if(temp < 2) {
8705 temp++;
8706 SiS_SetCH701x(SiS_Pr,0x61,temp);
8707 temp1 = 1;
8709 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8710 temp = SiS_GetCH701x(SiS_Pr,0x66);
8711 temp |= 0x5f;
8712 SiS_SetCH701x(SiS_Pr,0x66,temp);
8713 if(ModeNo > 0x13) {
8714 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8715 SiS_GenericDelay(SiS_Pr, 1023);
8716 } else {
8717 SiS_GenericDelay(SiS_Pr, 767);
8719 } else {
8720 if(!temp1)
8721 SiS_GenericDelay(SiS_Pr, 767);
8723 temp = SiS_GetCH701x(SiS_Pr,0x76);
8724 temp |= 0x03;
8725 SiS_SetCH701x(SiS_Pr,0x76,temp);
8726 temp = SiS_GetCH701x(SiS_Pr,0x66);
8727 temp &= 0x7f;
8728 SiS_SetCH701x(SiS_Pr,0x66,temp);
8729 SiS_LongDelay(SiS_Pr, 1);
8734 static void
8735 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8737 unsigned short temp;
8739 SiS_LongDelay(SiS_Pr, 1);
8741 do {
8742 temp = SiS_GetCH701x(SiS_Pr,0x66);
8743 temp &= 0x04; /* PLL stable? -> bail out */
8744 if(temp == 0x04) break;
8746 if(SiS_Pr->ChipType == SIS_740) {
8747 /* Power down LVDS output, PLL normal operation */
8748 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8751 SiS_SetCH701xForLCD(SiS_Pr);
8753 temp = SiS_GetCH701x(SiS_Pr,0x76);
8754 temp &= 0xfb; /* Reset PLL */
8755 SiS_SetCH701x(SiS_Pr,0x76,temp);
8756 SiS_LongDelay(SiS_Pr, 2);
8757 temp = SiS_GetCH701x(SiS_Pr,0x76);
8758 temp |= 0x04; /* PLL normal operation */
8759 SiS_SetCH701x(SiS_Pr,0x76,temp);
8760 if(SiS_Pr->ChipType == SIS_740) {
8761 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8762 } else {
8763 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8765 SiS_LongDelay(SiS_Pr, 2);
8766 } while(0);
8768 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8771 static void
8772 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8774 unsigned short temp;
8776 temp = SiS_GetCH701x(SiS_Pr,0x03);
8777 temp |= 0x80; /* Set datapath 1 to TV */
8778 temp &= 0xbf; /* Set datapath 2 to LVDS */
8779 SiS_SetCH701x(SiS_Pr,0x03,temp);
8781 if(SiS_Pr->ChipType == SIS_740) {
8783 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8784 temp &= 0xfb; /* Normal XCLK phase */
8785 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8787 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8789 temp = SiS_GetCH701x(SiS_Pr,0x64);
8790 temp |= 0x40; /* ? Bit not defined */
8791 SiS_SetCH701x(SiS_Pr,0x64,temp);
8793 temp = SiS_GetCH701x(SiS_Pr,0x03);
8794 temp &= 0x3f; /* D1 input to both LVDS and TV */
8795 SiS_SetCH701x(SiS_Pr,0x03,temp);
8797 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8798 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8799 SiS_LongDelay(SiS_Pr, 1);
8800 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8801 SiS_ChrontelResetDB(SiS_Pr);
8802 SiS_ChrontelDoSomething2(SiS_Pr);
8803 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8804 } else {
8805 temp = SiS_GetCH701x(SiS_Pr,0x66);
8806 if(temp != 0x45) {
8807 SiS_ChrontelResetDB(SiS_Pr);
8808 SiS_ChrontelDoSomething2(SiS_Pr);
8809 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8813 } else { /* 650 */
8815 SiS_ChrontelResetDB(SiS_Pr);
8816 SiS_ChrontelDoSomething2(SiS_Pr);
8817 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8818 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8819 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8824 #endif /* 315 series */
8826 /*********************************************/
8827 /* MAIN: SET CRT2 REGISTER GROUP */
8828 /*********************************************/
8830 bool
8831 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8833 #ifdef CONFIG_FB_SIS_300
8834 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8835 #endif
8836 unsigned short ModeIdIndex, RefreshRateTableIndex;
8838 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8840 if(!SiS_Pr->UseCustomMode) {
8841 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8842 } else {
8843 ModeIdIndex = 0;
8846 /* Used for shifting CR33 */
8847 SiS_Pr->SiS_SelectCRT2Rate = 4;
8849 SiS_UnLockCRT2(SiS_Pr);
8851 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8853 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8855 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8856 SiS_DisableBridge(SiS_Pr);
8857 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8860 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8863 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8864 SiS_LockCRT2(SiS_Pr);
8865 SiS_DisplayOn(SiS_Pr);
8866 return true;
8869 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8871 /* Set up Panel Link for LVDS and LCDA */
8872 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8873 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8874 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8875 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8876 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8879 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8880 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8883 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8885 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8887 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8888 #ifdef CONFIG_FB_SIS_315
8889 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890 #endif
8891 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8892 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8893 #ifdef CONFIG_FB_SIS_315
8894 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8895 #endif
8896 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8898 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8900 /* For 301BDH (Panel link initialization): */
8901 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8903 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8904 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8905 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8908 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8912 } else {
8914 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8916 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8918 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8920 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8921 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8922 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8923 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8924 #ifdef CONFIG_FB_SIS_315
8925 SiS_SetCH701xForLCD(SiS_Pr);
8926 #endif
8929 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8930 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8937 #ifdef CONFIG_FB_SIS_300
8938 if(SiS_Pr->ChipType < SIS_315H) {
8939 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8940 if(SiS_Pr->SiS_UseOEM) {
8941 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8942 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8943 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8945 } else {
8946 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8949 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8950 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8951 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8952 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8954 SiS_DisplayOn(SiS_Pr);
8958 #endif
8960 #ifdef CONFIG_FB_SIS_315
8961 if(SiS_Pr->ChipType >= SIS_315H) {
8962 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8963 if(SiS_Pr->ChipType < SIS_661) {
8964 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8965 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8966 } else {
8967 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8969 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8972 #endif
8974 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8975 SiS_EnableBridge(SiS_Pr);
8978 SiS_DisplayOn(SiS_Pr);
8980 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8981 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8982 /* Disable LCD panel when using TV */
8983 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8984 } else {
8985 /* Disable TV when using LCD */
8986 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8990 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8991 SiS_LockCRT2(SiS_Pr);
8994 return true;
8998 /*********************************************/
8999 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9000 /*********************************************/
9002 void
9003 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9005 /* Switch on LCD backlight on SiS30xLV */
9006 SiS_DDC2Delay(SiS_Pr,0xff00);
9007 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9008 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9009 SiS_WaitVBRetrace(SiS_Pr);
9011 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9012 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9016 void
9017 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9019 /* Switch off LCD backlight on SiS30xLV */
9020 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9021 SiS_DDC2Delay(SiS_Pr,0xff00);
9024 /*********************************************/
9025 /* DDC RELATED FUNCTIONS */
9026 /*********************************************/
9028 static void
9029 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9031 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9032 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9033 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9034 SiS_Pr->SiS_DDC_NData &= 0x0f;
9035 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9039 #ifdef CONFIG_FB_SIS_300
9040 static unsigned char *
9041 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9043 int i, j, num;
9044 unsigned short tempah,temp;
9045 unsigned char *mydataptr;
9047 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9048 mydataptr = dataptr;
9049 num = *mydataptr++;
9050 if(!num) return mydataptr;
9051 if(i) {
9052 SiS_SetStop(SiS_Pr);
9053 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9055 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9056 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9057 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9058 if(temp) continue; /* (ERROR: no ack) */
9059 tempah = *mydataptr++;
9060 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9061 if(temp) continue; /* (ERROR: no ack) */
9062 for(j=0; j<num; j++) {
9063 tempah = *mydataptr++;
9064 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9065 if(temp) break;
9067 if(temp) continue;
9068 if(SiS_SetStop(SiS_Pr)) continue;
9069 return mydataptr;
9071 return NULL;
9074 static bool
9075 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9077 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9078 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9079 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9080 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9081 SiS_SetupDDCN(SiS_Pr);
9083 SiS_SetSwitchDDC2(SiS_Pr);
9085 while(*dataptr) {
9086 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9087 if(!dataptr) return false;
9089 return true;
9091 #endif
9093 /* The Chrontel 700x is connected to the 630/730 via
9094 * the 630/730's DDC/I2C port.
9096 * On 630(S)T chipset, the index changed from 0x11 to
9097 * 0x0a, possibly for working around the DDC problems
9100 static bool
9101 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9103 unsigned short temp, i;
9105 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9106 if(i) {
9107 SiS_SetStop(SiS_Pr);
9108 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9110 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9111 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9112 if(temp) continue; /* (ERROR: no ack) */
9113 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
9114 if(temp) continue; /* (ERROR: no ack) */
9115 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
9116 if(temp) continue; /* (ERROR: no ack) */
9117 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9118 SiS_Pr->SiS_ChrontelInit = 1;
9119 return true;
9121 return false;
9124 /* Write to Chrontel 700x */
9125 void
9126 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9128 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9130 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9132 if(!(SiS_Pr->SiS_ChrontelInit)) {
9133 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9134 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9135 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9136 SiS_SetupDDCN(SiS_Pr);
9139 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9140 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9141 SiS_Pr->SiS_DDC_Index = 0x0a;
9142 SiS_Pr->SiS_DDC_Data = 0x80;
9143 SiS_Pr->SiS_DDC_Clk = 0x40;
9144 SiS_SetupDDCN(SiS_Pr);
9146 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9150 /* Write to Chrontel 701x */
9151 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9152 void
9153 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9155 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9156 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9157 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9158 SiS_SetupDDCN(SiS_Pr);
9159 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9160 SiS_SetChReg(SiS_Pr, reg, val, 0);
9163 static
9164 void
9165 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9167 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9168 SiS_SetCH700x(SiS_Pr, reg, val);
9169 else
9170 SiS_SetCH701x(SiS_Pr, reg, val);
9173 static unsigned short
9174 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9176 unsigned short tempah, temp, i;
9178 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9179 if(i) {
9180 SiS_SetStop(SiS_Pr);
9181 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9183 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9184 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9185 if(temp) continue; /* (ERROR: no ack) */
9186 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9187 if(temp) continue; /* (ERROR: no ack) */
9188 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9189 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9190 if(temp) continue; /* (ERROR: no ack) */
9191 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9192 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9193 SiS_Pr->SiS_ChrontelInit = 1;
9194 return tempah;
9196 return 0xFFFF;
9199 /* Read from Chrontel 700x */
9200 /* Parameter is [Register no (S7-S0)] */
9201 unsigned short
9202 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9204 unsigned short result;
9206 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9208 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9210 if(!(SiS_Pr->SiS_ChrontelInit)) {
9211 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9212 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9213 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9214 SiS_SetupDDCN(SiS_Pr);
9217 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9219 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9220 (!SiS_Pr->SiS_ChrontelInit) ) {
9222 SiS_Pr->SiS_DDC_Index = 0x0a;
9223 SiS_Pr->SiS_DDC_Data = 0x80;
9224 SiS_Pr->SiS_DDC_Clk = 0x40;
9225 SiS_SetupDDCN(SiS_Pr);
9227 result = SiS_GetChReg(SiS_Pr,0x80);
9229 return result;
9232 /* Read from Chrontel 701x */
9233 /* Parameter is [Register no (S7-S0)] */
9234 unsigned short
9235 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9237 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9238 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9239 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9240 SiS_SetupDDCN(SiS_Pr);
9241 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9243 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9245 return SiS_GetChReg(SiS_Pr,0);
9248 /* Read from Chrontel 70xx */
9249 /* Parameter is [Register no (S7-S0)] */
9250 static
9251 unsigned short
9252 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9254 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9255 return SiS_GetCH700x(SiS_Pr, tempbx);
9256 else
9257 return SiS_GetCH701x(SiS_Pr, tempbx);
9260 void
9261 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9262 unsigned char myor, unsigned short myand)
9264 unsigned short tempbl;
9266 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9267 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9270 /* Our own DDC functions */
9271 static
9272 unsigned short
9273 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9274 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9275 unsigned int VBFlags2)
9277 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9278 unsigned char flag, cr32;
9279 unsigned short temp = 0, myadaptnum = adaptnum;
9281 if(adaptnum != 0) {
9282 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9283 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9286 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9288 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9290 SiS_Pr->SiS_DDC_SecAddr = 0;
9291 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9292 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9293 SiS_Pr->SiS_DDC_Index = 0x11;
9294 flag = 0xff;
9296 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9298 #if 0
9299 if(VBFlags2 & VB2_SISBRIDGE) {
9300 if(myadaptnum == 0) {
9301 if(!(cr32 & 0x20)) {
9302 myadaptnum = 2;
9303 if(!(cr32 & 0x10)) {
9304 myadaptnum = 1;
9305 if(!(cr32 & 0x08)) {
9306 myadaptnum = 0;
9312 #endif
9314 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9316 if(myadaptnum != 0) {
9317 flag = 0;
9318 if(VBFlags2 & VB2_SISBRIDGE) {
9319 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9320 SiS_Pr->SiS_DDC_Index = 0x0f;
9324 if(!(VBFlags2 & VB2_301)) {
9325 if((cr32 & 0x80) && (checkcr32)) {
9326 if(myadaptnum >= 1) {
9327 if(!(cr32 & 0x08)) {
9328 myadaptnum = 1;
9329 if(!(cr32 & 0x10)) return 0xFFFF;
9335 temp = 4 - (myadaptnum * 2);
9336 if(flag) temp = 0;
9338 } else { /* 315/330 series */
9340 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9342 if(VBFlags2 & VB2_SISBRIDGE) {
9343 if(myadaptnum == 2) {
9344 myadaptnum = 1;
9348 if(myadaptnum == 1) {
9349 flag = 0;
9350 if(VBFlags2 & VB2_SISBRIDGE) {
9351 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9352 SiS_Pr->SiS_DDC_Index = 0x0f;
9356 if((cr32 & 0x80) && (checkcr32)) {
9357 if(myadaptnum >= 1) {
9358 if(!(cr32 & 0x08)) {
9359 myadaptnum = 1;
9360 if(!(cr32 & 0x10)) return 0xFFFF;
9365 temp = myadaptnum;
9366 if(myadaptnum == 1) {
9367 temp = 0;
9368 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9371 if(flag) temp = 0;
9374 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9375 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9377 SiS_SetupDDCN(SiS_Pr);
9379 return 0;
9382 static unsigned short
9383 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9385 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9386 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9387 return 0xFFFF;
9389 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9390 return 0xFFFF;
9392 return 0;
9395 static unsigned short
9396 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9398 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9399 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9400 return 0xFFFF;
9402 return 0;
9405 static unsigned short
9406 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9408 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9409 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9410 return 0;
9413 static void
9414 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9416 SiS_SetSCLKLow(SiS_Pr);
9417 if(yesno) {
9418 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9419 SiS_Pr->SiS_DDC_Index,
9420 SiS_Pr->SiS_DDC_NData,
9421 SiS_Pr->SiS_DDC_Data);
9422 } else {
9423 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9424 SiS_Pr->SiS_DDC_Index,
9425 SiS_Pr->SiS_DDC_NData,
9428 SiS_SetSCLKHigh(SiS_Pr);
9431 static unsigned short
9432 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9434 unsigned char mask, value;
9435 unsigned short temp, ret=0;
9436 bool failed = false;
9438 SiS_SetSwitchDDC2(SiS_Pr);
9439 if(SiS_PrepareDDC(SiS_Pr)) {
9440 SiS_SetStop(SiS_Pr);
9441 return 0xFFFF;
9443 mask = 0xf0;
9444 value = 0x20;
9445 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9446 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9447 SiS_SendACK(SiS_Pr, 0);
9448 if(temp == 0) {
9449 mask = 0xff;
9450 value = 0xff;
9451 } else {
9452 failed = true;
9453 ret = 0xFFFF;
9456 if(!failed) {
9457 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9458 SiS_SendACK(SiS_Pr, 1);
9459 temp &= mask;
9460 if(temp == value) ret = 0;
9461 else {
9462 ret = 0xFFFF;
9463 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9464 if(temp == 0x30) ret = 0;
9468 SiS_SetStop(SiS_Pr);
9469 return ret;
9472 static
9473 unsigned short
9474 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9476 unsigned short flag;
9478 flag = 0x180;
9479 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9480 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9481 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9482 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9483 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9484 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9485 if(!(flag & 0x1a)) flag = 0;
9486 return flag;
9489 static
9490 unsigned short
9491 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9493 unsigned short flag, length, i;
9494 unsigned char chksum,gotcha;
9496 if(DDCdatatype > 4) return 0xFFFF;
9498 flag = 0;
9499 SiS_SetSwitchDDC2(SiS_Pr);
9500 if(!(SiS_PrepareDDC(SiS_Pr))) {
9501 length = 127;
9502 if(DDCdatatype != 1) length = 255;
9503 chksum = 0;
9504 gotcha = 0;
9505 for(i=0; i<length; i++) {
9506 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9507 chksum += buffer[i];
9508 gotcha |= buffer[i];
9509 SiS_SendACK(SiS_Pr, 0);
9511 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9512 chksum += buffer[i];
9513 SiS_SendACK(SiS_Pr, 1);
9514 if(gotcha) flag = (unsigned short)chksum;
9515 else flag = 0xFFFF;
9516 } else {
9517 flag = 0xFFFF;
9519 SiS_SetStop(SiS_Pr);
9520 return flag;
9523 /* Our private DDC functions
9525 It complies somewhat with the corresponding VESA function
9526 in arguments and return values.
9528 Since this is probably called before the mode is changed,
9529 we use our pre-detected pSiS-values instead of SiS_Pr as
9530 regards chipset and video bridge type.
9532 Arguments:
9533 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9534 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9535 LCDA is CRT1, but DDC is read from CRT2 port.
9536 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9537 buffer: ptr to 256 data bytes which will be filled with read data.
9539 Returns 0xFFFF if error, otherwise
9540 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9541 if DDCdatatype = 0: Returns supported DDC modes
9544 unsigned short
9545 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9546 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9547 unsigned int VBFlags2)
9549 unsigned char sr1f, cr17=1;
9550 unsigned short result;
9552 if(adaptnum > 2)
9553 return 0xFFFF;
9555 if(DDCdatatype > 4)
9556 return 0xFFFF;
9558 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9559 return 0xFFFF;
9561 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9562 return 0xFFFF;
9564 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9565 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9566 if(VGAEngine == SIS_300_VGA) {
9567 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9568 if(!cr17) {
9569 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9570 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9571 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9574 if((sr1f) || (!cr17)) {
9575 SiS_WaitRetrace1(SiS_Pr);
9576 SiS_WaitRetrace1(SiS_Pr);
9577 SiS_WaitRetrace1(SiS_Pr);
9578 SiS_WaitRetrace1(SiS_Pr);
9581 if(DDCdatatype == 0) {
9582 result = SiS_ProbeDDC(SiS_Pr);
9583 } else {
9584 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9585 if((!result) && (DDCdatatype == 1)) {
9586 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9587 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9588 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9589 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9590 (buffer[0x12] == 1)) {
9591 if(!SiS_Pr->DDCPortMixup) {
9592 if(adaptnum == 1) {
9593 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9594 } else {
9595 if(buffer[0x14] & 0x80) result = 0xFFFE;
9601 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9602 if(VGAEngine == SIS_300_VGA) {
9603 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9605 return result;
9608 /* Generic I2C functions for Chrontel & DDC --------- */
9610 static void
9611 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9613 SiS_SetSCLKHigh(SiS_Pr);
9614 SiS_WaitRetrace1(SiS_Pr);
9616 SiS_SetSCLKLow(SiS_Pr);
9617 SiS_WaitRetrace1(SiS_Pr);
9620 unsigned short
9621 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9623 SiS_WaitRetrace1(SiS_Pr);
9624 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9627 /* Set I2C start condition */
9628 /* This is done by a SD high-to-low transition while SC is high */
9629 static unsigned short
9630 SiS_SetStart(struct SiS_Private *SiS_Pr)
9632 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9633 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9634 SiS_Pr->SiS_DDC_Index,
9635 SiS_Pr->SiS_DDC_NData,
9636 SiS_Pr->SiS_DDC_Data); /* SD->high */
9637 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9638 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9639 SiS_Pr->SiS_DDC_Index,
9640 SiS_Pr->SiS_DDC_NData,
9641 0x00); /* SD->low = start condition */
9642 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9643 return 0;
9646 /* Set I2C stop condition */
9647 /* This is done by a SD low-to-high transition while SC is high */
9648 static unsigned short
9649 SiS_SetStop(struct SiS_Private *SiS_Pr)
9651 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9652 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9653 SiS_Pr->SiS_DDC_Index,
9654 SiS_Pr->SiS_DDC_NData,
9655 0x00); /* SD->low */
9656 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9657 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9658 SiS_Pr->SiS_DDC_Index,
9659 SiS_Pr->SiS_DDC_NData,
9660 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9661 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9662 return 0;
9665 /* Write 8 bits of data */
9666 static unsigned short
9667 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9669 unsigned short i,flag,temp;
9671 flag = 0x80;
9672 for(i = 0; i < 8; i++) {
9673 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9674 if(tempax & flag) {
9675 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9676 SiS_Pr->SiS_DDC_Index,
9677 SiS_Pr->SiS_DDC_NData,
9678 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9679 } else {
9680 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9681 SiS_Pr->SiS_DDC_Index,
9682 SiS_Pr->SiS_DDC_NData,
9683 0x00); /* Write bit (0) to SD */
9685 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9686 flag >>= 1;
9688 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9689 return temp;
9692 static unsigned short
9693 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9695 unsigned short i, temp, getdata;
9697 getdata = 0;
9698 for(i = 0; i < 8; i++) {
9699 getdata <<= 1;
9700 SiS_SetSCLKLow(SiS_Pr);
9701 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9702 SiS_Pr->SiS_DDC_Index,
9703 SiS_Pr->SiS_DDC_NData,
9704 SiS_Pr->SiS_DDC_Data);
9705 SiS_SetSCLKHigh(SiS_Pr);
9706 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9707 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9709 return getdata;
9712 static unsigned short
9713 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9715 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9716 SiS_Pr->SiS_DDC_Index,
9717 SiS_Pr->SiS_DDC_NClk,
9718 0x00); /* SetSCLKLow() */
9719 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9720 return 0;
9723 static unsigned short
9724 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9726 unsigned short temp, watchdog=1000;
9728 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9729 SiS_Pr->SiS_DDC_Index,
9730 SiS_Pr->SiS_DDC_NClk,
9731 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9732 do {
9733 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9734 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9735 if (!watchdog) {
9736 return 0xFFFF;
9738 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9739 return 0;
9742 /* Check I2C acknowledge */
9743 /* Returns 0 if ack ok, non-0 if ack not ok */
9744 static unsigned short
9745 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9747 unsigned short tempah;
9749 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9750 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9751 SiS_Pr->SiS_DDC_Index,
9752 SiS_Pr->SiS_DDC_NData,
9753 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9754 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9755 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9756 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9757 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9758 return 0;
9761 /* End of I2C functions ----------------------- */
9764 /* =============== SiS 315/330 O.E.M. ================= */
9766 #ifdef CONFIG_FB_SIS_315
9768 static unsigned short
9769 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9771 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9772 unsigned short romptr;
9774 if(SiS_Pr->ChipType < SIS_330) {
9775 romptr = SISGETROMW(0x128);
9776 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9777 romptr = SISGETROMW(0x12a);
9778 } else {
9779 romptr = SISGETROMW(0x1a8);
9780 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9781 romptr = SISGETROMW(0x1aa);
9783 return romptr;
9786 static unsigned short
9787 GetLCDromptr(struct SiS_Private *SiS_Pr)
9789 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9790 unsigned short romptr;
9792 if(SiS_Pr->ChipType < SIS_330) {
9793 romptr = SISGETROMW(0x120);
9794 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9795 romptr = SISGETROMW(0x122);
9796 } else {
9797 romptr = SISGETROMW(0x1a0);
9798 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9799 romptr = SISGETROMW(0x1a2);
9801 return romptr;
9804 static unsigned short
9805 GetTVromptr(struct SiS_Private *SiS_Pr)
9807 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9808 unsigned short romptr;
9810 if(SiS_Pr->ChipType < SIS_330) {
9811 romptr = SISGETROMW(0x114);
9812 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9813 romptr = SISGETROMW(0x11a);
9814 } else {
9815 romptr = SISGETROMW(0x194);
9816 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9817 romptr = SISGETROMW(0x19a);
9819 return romptr;
9822 static unsigned short
9823 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9825 unsigned short index;
9827 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9828 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9829 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9830 index >>= 4;
9831 index *= 3;
9832 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9833 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9834 return index;
9839 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9840 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9841 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9843 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9844 } else {
9845 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9847 index--;
9848 index *= 3;
9849 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9850 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9851 return index;
9854 static unsigned short
9855 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9857 unsigned short index;
9859 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9860 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9861 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9862 return index;
9865 static unsigned short
9866 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9868 unsigned short index;
9870 index = 0;
9871 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9876 index <<= 1;
9878 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9879 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9880 index++;
9883 return index;
9886 static unsigned int
9887 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9889 unsigned short index = 0, temp = 0;
9891 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9892 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9893 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9894 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9895 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9896 index = 4;
9897 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9898 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9901 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9902 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9903 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9904 index += addme;
9905 temp++;
9907 temp += 0x0100;
9909 return (unsigned int)(index | (temp << 16));
9912 static unsigned int
9913 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9915 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9918 #if 0
9919 static unsigned int
9920 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9922 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9924 #endif
9926 static int
9927 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9929 int index = 0;
9931 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9932 if(SiS_Pr->SiS_ROMNew) {
9933 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9934 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9935 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9936 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9937 } else {
9938 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9939 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9940 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9941 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9944 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9946 return index;
9949 static void
9950 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9952 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9953 unsigned short delay=0,index,myindex,temp,romptr=0;
9954 bool dochiptest = true;
9956 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9957 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9958 } else {
9959 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9962 /* Find delay (from ROM, internal tables, PCI subsystem) */
9964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9966 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9967 romptr = GetRAMDACromptr(SiS_Pr);
9969 if(romptr) delay = ROMAddr[romptr];
9970 else {
9971 delay = 0x04;
9972 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9973 if(IS_SIS650) {
9974 delay = 0x0a;
9975 } else if(IS_SIS740) {
9976 delay = 0x00;
9977 } else {
9978 delay = 0x0c;
9980 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9981 delay = 0x00;
9985 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9987 bool gotitfrompci = false;
9989 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9991 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9992 if(SiS_Pr->PDC != -1) {
9993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9994 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9995 return;
9997 } else {
9998 if(SiS_Pr->PDCA != -1) {
9999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10000 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10001 return;
10005 /* Custom Panel? */
10007 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10008 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10009 delay = 0x00;
10010 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10011 delay = 0x20;
10013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10014 } else {
10015 delay = 0x0c;
10016 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10017 delay = 0x03;
10018 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10019 delay = 0x00;
10021 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10022 if(IS_SIS740) delay = 0x01;
10023 else delay = 0x03;
10025 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10027 return;
10030 /* This is a piece of typical SiS crap: They code the OEM LCD
10031 * delay into the code, at no defined place in the BIOS.
10032 * We now have to start doing a PCI subsystem check here.
10035 switch(SiS_Pr->SiS_CustomT) {
10036 case CUT_COMPAQ1280:
10037 case CUT_COMPAQ12802:
10038 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10039 gotitfrompci = true;
10040 dochiptest = false;
10041 delay = 0x03;
10043 break;
10044 case CUT_CLEVO1400:
10045 case CUT_CLEVO14002:
10046 gotitfrompci = true;
10047 dochiptest = false;
10048 delay = 0x02;
10049 break;
10050 case CUT_CLEVO1024:
10051 case CUT_CLEVO10242:
10052 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10053 gotitfrompci = true;
10054 dochiptest = false;
10055 delay = 0x33;
10056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10057 delay &= 0x0f;
10059 break;
10062 /* Could we find it through the PCI ID? If no, use ROM or table */
10064 if(!gotitfrompci) {
10066 index = GetLCDPtrIndexBIOS(SiS_Pr);
10067 myindex = GetLCDPtrIndex(SiS_Pr);
10069 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10071 if(SiS_IsNotM650orLater(SiS_Pr)) {
10073 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10074 /* Always use the second pointer on 650; some BIOSes */
10075 /* still carry old 301 data at the first location */
10076 /* romptr = SISGETROMW(0x120); */
10077 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10078 romptr = SISGETROMW(0x122);
10079 if(!romptr) return;
10080 delay = ROMAddr[(romptr + index)];
10081 } else {
10082 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10085 } else {
10087 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10088 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10089 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10093 } else if(SiS_Pr->SiS_UseROM &&
10094 (!(SiS_Pr->SiS_ROMNew)) &&
10095 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10096 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10097 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
10098 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
10099 ((romptr = GetLCDromptr(SiS_Pr)))) {
10101 /* Data for 1280x1024 wrong in 301B BIOS */
10102 /* Data for 1600x1200 wrong in 301C BIOS */
10103 delay = ROMAddr[(romptr + index)];
10105 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10107 if(IS_SIS740) delay = 0x03;
10108 else delay = 0x00;
10110 } else {
10112 delay = SiS310_LCDDelayCompensation_301[myindex];
10113 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10114 if(IS_SIS740) delay = 0x01;
10115 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10116 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10117 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10118 if(IS_SIS740) delay = 0x01; /* ? */
10119 else delay = 0x03;
10120 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10121 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10122 if(IS_SIS740) delay = 0x01;
10123 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10128 } /* got it from PCI */
10130 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10132 dochiptest = false;
10135 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10137 index = GetTVPtrIndex(SiS_Pr);
10139 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10141 if(SiS_IsNotM650orLater(SiS_Pr)) {
10143 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10144 /* Always use the second pointer on 650; some BIOSes */
10145 /* still carry old 301 data at the first location */
10146 /* romptr = SISGETROMW(0x114); */
10147 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10148 romptr = SISGETROMW(0x11a);
10149 if(!romptr) return;
10150 delay = ROMAddr[romptr + index];
10152 } else {
10154 delay = SiS310_TVDelayCompensation_301B[index];
10158 } else {
10160 switch(SiS_Pr->SiS_CustomT) {
10161 case CUT_COMPAQ1280:
10162 case CUT_COMPAQ12802:
10163 case CUT_CLEVO1400:
10164 case CUT_CLEVO14002:
10165 delay = 0x02;
10166 dochiptest = false;
10167 break;
10168 case CUT_CLEVO1024:
10169 case CUT_CLEVO10242:
10170 delay = 0x03;
10171 dochiptest = false;
10172 break;
10173 default:
10174 delay = SiS310_TVDelayCompensation_651301LV[index];
10175 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10176 delay = SiS310_TVDelayCompensation_651302LV[index];
10181 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10183 romptr = GetTVromptr(SiS_Pr);
10184 if(!romptr) return;
10185 delay = ROMAddr[romptr + index];
10187 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10189 delay = SiS310_TVDelayCompensation_LVDS[index];
10191 } else {
10193 delay = SiS310_TVDelayCompensation_301[index];
10194 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10195 if(IS_SIS740) {
10196 delay = SiS310_TVDelayCompensation_740301B[index];
10197 /* LV: use 301 data? BIOS bug? */
10198 } else {
10199 delay = SiS310_TVDelayCompensation_301B[index];
10200 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10206 if(SiS_LCDAEnabled(SiS_Pr)) {
10207 delay &= 0x0f;
10208 dochiptest = false;
10211 } else return;
10213 /* Write delay */
10215 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10217 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10219 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10220 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10221 delay &= 0x0f;
10222 delay |= 0xb0;
10223 } else if(temp == 6) {
10224 delay &= 0x0f;
10225 delay |= 0xc0;
10226 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10227 delay = 0x35;
10229 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10231 } else {
10233 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10237 } else { /* LVDS */
10239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10240 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10241 } else {
10242 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10243 delay <<= 4;
10244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10245 } else {
10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10254 static void
10255 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10257 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10258 unsigned short index,temp,temp1,romptr=0;
10260 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10262 if(ModeNo<=0x13)
10263 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10264 else
10265 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10267 temp = GetTVPtrIndex(SiS_Pr);
10268 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10269 temp1 = temp;
10271 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10272 if(SiS_Pr->ChipType >= SIS_661) {
10273 temp1 = GetOEMTVPtr661(SiS_Pr);
10274 temp1 >>= 1;
10275 romptr = SISGETROMW(0x260);
10276 if(SiS_Pr->ChipType >= SIS_760) {
10277 romptr = SISGETROMW(0x360);
10279 } else if(SiS_Pr->ChipType >= SIS_330) {
10280 romptr = SISGETROMW(0x192);
10281 } else {
10282 romptr = SISGETROMW(0x112);
10286 if(romptr) {
10287 temp1 <<= 1;
10288 temp = ROMAddr[romptr + temp1 + index];
10289 } else {
10290 temp = SiS310_TVAntiFlick1[temp][index];
10292 temp <<= 4;
10294 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10297 static void
10298 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10300 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10301 unsigned short index,temp,temp1,romptr=0;
10303 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10305 if(ModeNo <= 0x13)
10306 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10307 else
10308 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10310 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10311 if(SiS_Pr->ChipType >= SIS_661) {
10312 romptr = SISGETROMW(0x26c);
10313 if(SiS_Pr->ChipType >= SIS_760) {
10314 romptr = SISGETROMW(0x36c);
10316 temp1 = GetOEMTVPtr661(SiS_Pr);
10317 temp1 >>= 1;
10318 } else if(SiS_Pr->ChipType >= SIS_330) {
10319 romptr = SISGETROMW(0x1a4);
10320 } else {
10321 romptr = SISGETROMW(0x124);
10325 if(romptr) {
10326 temp1 <<= 1;
10327 temp = ROMAddr[romptr + temp1 + index];
10328 } else {
10329 temp = SiS310_TVEdge1[temp][index];
10331 temp <<= 5;
10332 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10335 static void
10336 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10338 unsigned short index, temp, i, j;
10340 if(ModeNo <= 0x13) {
10341 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10342 } else {
10343 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10346 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10348 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10349 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10350 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10351 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10353 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10354 for(i=0x35, j=0; i<=0x38; i++, j++) {
10355 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10357 for(i=0x48; i<=0x4A; i++, j++) {
10358 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10360 } else {
10361 for(i=0x35, j=0; i<=0x38; i++, j++) {
10362 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10367 static void
10368 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10370 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10371 unsigned short index,temp,i,j,resinfo,romptr=0;
10372 unsigned int lindex;
10374 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10376 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10377 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10379 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10380 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10381 lindex <<= 2;
10382 for(j=0, i=0x31; i<=0x34; i++, j++) {
10383 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10385 return;
10388 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10389 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10391 if(ModeNo<=0x13) {
10392 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10393 } else {
10394 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10397 temp = GetTVPtrIndex(SiS_Pr);
10398 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10399 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10401 if(SiS_Pr->SiS_UseROM) {
10402 romptr = SISGETROMW(0x116);
10403 if(SiS_Pr->ChipType >= SIS_330) {
10404 romptr = SISGETROMW(0x196);
10406 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10407 romptr = SISGETROMW(0x11c);
10408 if(SiS_Pr->ChipType >= SIS_330) {
10409 romptr = SISGETROMW(0x19c);
10411 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10412 romptr = SISGETROMW(0x116);
10413 if(SiS_Pr->ChipType >= SIS_330) {
10414 romptr = SISGETROMW(0x196);
10419 if(romptr) {
10420 romptr += (temp << 2);
10421 for(j=0, i=0x31; i<=0x34; i++, j++) {
10422 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10424 } else {
10425 index = temp % 2;
10426 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10427 for(j=0, i=0x31; i<=0x34; i++, j++) {
10428 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10429 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10430 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10431 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10432 else
10433 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10437 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10438 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10439 if((resinfo == SIS_RI_640x480) ||
10440 (resinfo == SIS_RI_800x600)) {
10441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10442 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10444 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10445 } else if(resinfo == SIS_RI_1024x768) {
10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10447 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10455 static void
10456 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10457 unsigned short ModeIdIndex, unsigned short RTI)
10459 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10460 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10462 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10463 return;
10465 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10466 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10468 if(SiS_Pr->SiS_ROMNew) {
10469 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10470 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10471 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10472 index = 25;
10473 if(SiS_Pr->UseCustomMode) {
10474 index = SiS_Pr->CSRClock;
10475 } else if(ModeNo > 0x13) {
10476 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10477 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10479 if(index < 25) index = 25;
10480 index = ((index / 25) - 1) << 1;
10481 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10482 index++;
10484 romptr = SISGETROMW(0x104);
10485 delay = ROMAddr[romptr + index];
10486 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10489 } else {
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10493 return;
10497 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10499 if(SiS_Pr->UseCustomMode) delay = 0x04;
10500 else if(ModeNo <= 0x13) delay = 0x04;
10501 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10502 delay |= (delay << 8);
10504 if(SiS_Pr->ChipType >= XGI_20) {
10506 delay = 0x0606;
10507 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10509 delay = 0x0404;
10510 if(SiS_Pr->SiS_XGIROM) {
10511 index = GetTVPtrIndex(SiS_Pr);
10512 if((romptr = SISGETROMW(0x35e))) {
10513 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10514 delay |= (delay << 8);
10518 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10519 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10520 delay -= 0x0404;
10525 } else if(SiS_Pr->ChipType >= SIS_340) {
10527 delay = 0x0606;
10528 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10529 delay = 0x0404;
10531 /* TODO (eventually) */
10533 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10535 /* 3. TV */
10537 index = GetOEMTVPtr661(SiS_Pr);
10538 if(SiS_Pr->SiS_ROMNew) {
10539 romptr = SISGETROMW(0x106);
10540 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10541 delay = ROMAddr[romptr + index];
10542 } else {
10543 delay = 0x04;
10544 if(index > 3) delay = 0;
10547 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10549 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10551 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10552 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10554 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10556 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10557 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10558 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10560 } else {
10562 /* TMDS: Set our own, since BIOS has no idea */
10563 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10564 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10565 switch(SiS_Pr->SiS_LCDResInfo) {
10566 case Panel_1024x768: delay = 0x0008; break;
10567 case Panel_1280x720: delay = 0x0004; break;
10568 case Panel_1280x768:
10569 case Panel_1280x768_2:delay = 0x0004; break;
10570 case Panel_1280x800:
10571 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10572 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10573 case Panel_1280x1024: delay = 0x1e04; break;
10574 case Panel_1400x1050: delay = 0x0004; break;
10575 case Panel_1600x1200: delay = 0x0400; break;
10576 case Panel_1680x1050: delay = 0x0e04; break;
10577 default:
10578 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10579 delay = 0x0008;
10580 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10581 delay = 0x1e04;
10582 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10583 delay = 0x0004;
10584 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10585 delay = 0x0400;
10586 } else
10587 delay = 0x0e04;
10588 break;
10592 /* Override by detected or user-set values */
10593 /* (but only if, for some reason, we can't read value from BIOS) */
10594 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10595 delay = SiS_Pr->PDC & 0x1f;
10597 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10598 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10605 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10606 delay >>= 8;
10607 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10608 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10609 } else {
10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10611 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10615 static void
10616 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10618 unsigned short infoflag;
10619 unsigned char temp;
10621 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10623 if(ModeNo <= 0x13) {
10624 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10625 } else if(SiS_Pr->UseCustomMode) {
10626 infoflag = SiS_Pr->CInfoFlag;
10627 } else {
10628 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10631 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10632 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10635 infoflag &= 0xc0;
10637 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10638 temp = (infoflag >> 6) | 0x0c;
10639 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10640 temp ^= 0x04;
10641 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10643 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10644 } else {
10645 temp = 0x30;
10646 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10647 temp |= infoflag;
10648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10649 temp = 0;
10650 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10651 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10653 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10659 static void
10660 SetPanelParms661(struct SiS_Private *SiS_Pr)
10662 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10663 unsigned short romptr, temp1, temp2;
10665 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10666 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10669 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10670 if(SiS_Pr->LVDSHL != -1) {
10671 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10675 if(SiS_Pr->SiS_ROMNew) {
10677 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10678 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10679 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10680 temp2 = 0xfc;
10681 if(SiS_Pr->LVDSHL != -1) {
10682 temp1 &= 0xfc;
10683 temp2 = 0xf3;
10685 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10687 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10688 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10689 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10696 static void
10697 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10699 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10700 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10701 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10702 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10703 SetPanelParms661(SiS_Pr);
10705 } else {
10706 SetDelayComp(SiS_Pr,ModeNo);
10709 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10710 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10711 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10712 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10713 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10714 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10719 static void
10720 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10721 unsigned short ModeIdIndex, unsigned short RRTI)
10723 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10725 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10727 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10728 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10729 SetPanelParms661(SiS_Pr);
10732 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10733 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10734 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10735 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10736 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10737 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10743 /* FinalizeLCD
10744 * This finalizes some CRT2 registers for the very panel used.
10745 * If we have a backup if these registers, we use it; otherwise
10746 * we set the register according to most BIOSes. However, this
10747 * function looks quite different in every BIOS, so you better
10748 * pray that we have a backup...
10750 static void
10751 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10753 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10754 unsigned short resinfo,modeflag;
10756 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10757 if(SiS_Pr->SiS_ROMNew) return;
10759 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10760 if(SiS_Pr->LVDSHL != -1) {
10761 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10765 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10766 if(SiS_Pr->UseCustomMode) return;
10768 switch(SiS_Pr->SiS_CustomT) {
10769 case CUT_COMPAQ1280:
10770 case CUT_COMPAQ12802:
10771 case CUT_CLEVO1400:
10772 case CUT_CLEVO14002:
10773 return;
10776 if(ModeNo <= 0x13) {
10777 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10778 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10779 } else {
10780 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10781 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10784 if(IS_SIS650) {
10785 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10786 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10787 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10788 } else {
10789 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10794 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10795 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10796 /* Maybe all panels? */
10797 if(SiS_Pr->LVDSHL == -1) {
10798 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10800 return;
10804 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10805 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10806 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10807 if(SiS_Pr->LVDSHL == -1) {
10808 /* Maybe all panels? */
10809 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10811 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10812 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10813 if(tempch == 3) {
10814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10820 return;
10825 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10826 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10827 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10828 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10829 #ifdef SET_EMI
10830 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10831 #endif
10832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10834 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10835 if(SiS_Pr->LVDSHL == -1) {
10836 /* Maybe ACER only? */
10837 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10840 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10842 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10843 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10844 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10845 if(tempch == 0x03) {
10846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10851 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10853 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10862 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10864 if(ModeNo <= 0x13) {
10865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10866 if((resinfo == 0) || (resinfo == 2)) return;
10867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10868 if((resinfo == 1) || (resinfo == 3)) return;
10870 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10871 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10873 #if 0
10874 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10875 tempbx--;
10876 temp = tempbx & 0xff;
10877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10878 temp = (tempbx >> 8) & 0x03;
10879 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10880 #endif
10882 } else if(ModeNo <= 0x13) {
10883 if(ModeNo <= 1) {
10884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10889 if(!(modeflag & HalfDCLK)) {
10890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10896 if(ModeNo == 0x12) {
10897 switch(tempch) {
10898 case 0:
10899 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10905 break;
10906 case 2:
10907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10909 break;
10910 case 3:
10911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10912 break;
10918 } else {
10919 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10920 tempcl &= 0x0f;
10921 tempbh &= 0x70;
10922 tempbh >>= 4;
10923 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10924 tempbx = (tempbh << 8) | tempbl;
10925 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10926 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10927 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10928 tempbx = 770;
10929 } else {
10930 if(tempbx > 770) tempbx = 770;
10931 if(SiS_Pr->SiS_VGAVDE < 600) {
10932 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10933 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10934 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10935 tempbx -= tempax;
10938 } else return;
10940 temp = tempbx & 0xff;
10941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10942 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10943 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10948 #endif
10950 /* ================= SiS 300 O.E.M. ================== */
10952 #ifdef CONFIG_FB_SIS_300
10954 static void
10955 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10956 unsigned short RefTabIndex)
10958 unsigned short crt2crtc=0, modeflag, myindex=0;
10959 unsigned char temp;
10960 int i;
10962 if(ModeNo <= 0x13) {
10963 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10964 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10965 } else {
10966 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10967 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10970 crt2crtc &= 0x3f;
10972 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10976 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10977 if(modeflag & HalfDCLK) myindex = 1;
10979 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10980 for(i=0; i<7; i++) {
10981 if(barco_p1[myindex][crt2crtc][i][0]) {
10982 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10983 barco_p1[myindex][crt2crtc][i][0],
10984 barco_p1[myindex][crt2crtc][i][2],
10985 barco_p1[myindex][crt2crtc][i][1]);
10989 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10990 if(temp & 0x80) {
10991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10992 temp++;
10993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10998 static unsigned short
10999 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11001 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11002 unsigned short tempbx=0,romptr=0;
11003 static const unsigned char customtable300[] = {
11004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11005 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11007 static const unsigned char customtable630[] = {
11008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11009 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11012 if(SiS_Pr->ChipType == SIS_300) {
11014 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11015 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11016 tempbx -= 2;
11017 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11018 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11019 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11021 if(SiS_Pr->SiS_UseROM) {
11022 if(ROMAddr[0x235] & 0x80) {
11023 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11024 if(Flag) {
11025 romptr = SISGETROMW(0x255);
11026 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11027 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11028 if(tempbx == 0xFF) return 0xFFFF;
11030 tempbx <<= 1;
11031 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11035 } else {
11037 if(Flag) {
11038 if(SiS_Pr->SiS_UseROM) {
11039 romptr = SISGETROMW(0x255);
11040 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11041 else tempbx = 0xff;
11042 } else {
11043 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11045 if(tempbx == 0xFF) return 0xFFFF;
11046 tempbx <<= 2;
11047 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11048 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11049 return tempbx;
11051 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11052 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11053 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11057 return tempbx;
11060 static void
11061 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11063 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11064 unsigned short index,temp,romptr=0;
11066 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11068 if(SiS_Pr->SiS_UseROM) {
11069 if(!(ROMAddr[0x237] & 0x01)) return;
11070 if(!(ROMAddr[0x237] & 0x02)) return;
11071 romptr = SISGETROMW(0x24b);
11074 /* The Panel Compensation Delay should be set according to tables
11075 * here. Unfortunately, various BIOS versions don't care about
11076 * a uniform way using eg. ROM byte 0x220, but use different
11077 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11078 * Thus we don't set this if the user selected a custom pdc or if
11079 * we otherwise detected a valid pdc.
11081 if(SiS_Pr->PDC != -1) return;
11083 temp = GetOEMLCDPtr(SiS_Pr, 0);
11085 if(SiS_Pr->UseCustomMode)
11086 index = 0;
11087 else
11088 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11090 if(SiS_Pr->ChipType != SIS_300) {
11091 if(romptr) {
11092 romptr += (temp * 2);
11093 romptr = SISGETROMW(romptr);
11094 romptr += index;
11095 temp = ROMAddr[romptr];
11096 } else {
11097 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11098 temp = SiS300_OEMLCDDelay2[temp][index];
11099 } else {
11100 temp = SiS300_OEMLCDDelay3[temp][index];
11103 } else {
11104 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11105 if(romptr) {
11106 romptr += (temp * 2);
11107 romptr = SISGETROMW(romptr);
11108 romptr += index;
11109 temp = ROMAddr[romptr];
11110 } else {
11111 temp = SiS300_OEMLCDDelay5[temp][index];
11113 } else {
11114 if(SiS_Pr->SiS_UseROM) {
11115 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11116 if(romptr) {
11117 romptr += (temp * 2);
11118 romptr = SISGETROMW(romptr);
11119 romptr += index;
11120 temp = ROMAddr[romptr];
11121 } else {
11122 temp = SiS300_OEMLCDDelay4[temp][index];
11124 } else {
11125 temp = SiS300_OEMLCDDelay4[temp][index];
11129 temp &= 0x3c;
11130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11133 static void
11134 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11136 #if 0 /* Unfinished; Data table missing */
11137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11138 unsigned short index,temp;
11140 if((SiS_Pr->SiS_UseROM) {
11141 if(!(ROMAddr[0x237] & 0x01)) return;
11142 if(!(ROMAddr[0x237] & 0x04)) return;
11143 /* No rom pointer in BIOS header! */
11146 temp = GetOEMLCDPtr(SiS_Pr, 1);
11147 if(temp == 0xFFFF) return;
11149 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11150 for(i=0x14, j=0; i<=0x17; i++, j++) {
11151 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11153 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11155 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11156 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11157 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11158 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11159 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11160 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11162 #endif
11165 static unsigned short
11166 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11168 unsigned short index;
11170 index = 0;
11171 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11172 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11173 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11174 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11175 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11176 } else {
11177 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11178 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11180 return index;
11183 static void
11184 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11186 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11187 unsigned short index,temp,romptr=0;
11189 if(SiS_Pr->SiS_UseROM) {
11190 if(!(ROMAddr[0x238] & 0x01)) return;
11191 if(!(ROMAddr[0x238] & 0x02)) return;
11192 romptr = SISGETROMW(0x241);
11195 temp = GetOEMTVPtr(SiS_Pr);
11197 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11199 if(romptr) {
11200 romptr += (temp * 2);
11201 romptr = SISGETROMW(romptr);
11202 romptr += index;
11203 temp = ROMAddr[romptr];
11204 } else {
11205 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11206 temp = SiS300_OEMTVDelay301[temp][index];
11207 } else {
11208 temp = SiS300_OEMTVDelayLVDS[temp][index];
11211 temp &= 0x3c;
11212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11215 static void
11216 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11218 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11219 unsigned short index,temp,romptr=0;
11221 if(SiS_Pr->SiS_UseROM) {
11222 if(!(ROMAddr[0x238] & 0x01)) return;
11223 if(!(ROMAddr[0x238] & 0x04)) return;
11224 romptr = SISGETROMW(0x243);
11227 temp = GetOEMTVPtr(SiS_Pr);
11229 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11231 if(romptr) {
11232 romptr += (temp * 2);
11233 romptr = SISGETROMW(romptr);
11234 romptr += index;
11235 temp = ROMAddr[romptr];
11236 } else {
11237 temp = SiS300_OEMTVFlicker[temp][index];
11239 temp &= 0x70;
11240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11243 static void
11244 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11246 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11247 unsigned short index,i,j,temp,romptr=0;
11249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11251 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11253 if(SiS_Pr->SiS_UseROM) {
11254 if(!(ROMAddr[0x238] & 0x01)) return;
11255 if(!(ROMAddr[0x238] & 0x08)) return;
11256 romptr = SISGETROMW(0x245);
11259 temp = GetOEMTVPtr(SiS_Pr);
11261 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11263 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11264 for(i=0x31, j=0; i<=0x34; i++, j++) {
11265 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11267 } else {
11268 if(romptr) {
11269 romptr += (temp * 2);
11270 romptr = SISGETROMW(romptr);
11271 romptr += (index * 4);
11272 for(i=0x31, j=0; i<=0x34; i++, j++) {
11273 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11275 } else {
11276 for(i=0x31, j=0; i<=0x34; i++, j++) {
11277 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11283 static void
11284 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11286 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11287 unsigned short index,temp,i,j,romptr=0;
11289 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11291 if(SiS_Pr->SiS_UseROM) {
11292 if(!(ROMAddr[0x238] & 0x01)) return;
11293 if(!(ROMAddr[0x238] & 0x10)) return;
11294 romptr = SISGETROMW(0x247);
11297 temp = GetOEMTVPtr(SiS_Pr);
11299 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11300 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11301 /* NTSCJ uses NTSC filters */
11303 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11305 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11306 for(i=0x35, j=0; i<=0x38; i++, j++) {
11307 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11309 for(i=0x48; i<=0x4A; i++, j++) {
11310 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11312 } else {
11313 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11314 romptr += (temp * 2);
11315 romptr = SISGETROMW(romptr);
11316 romptr += (index * 4);
11317 for(i=0x35, j=0; i<=0x38; i++, j++) {
11318 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11320 } else {
11321 for(i=0x35, j=0; i<=0x38; i++, j++) {
11322 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11328 static unsigned short
11329 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11331 unsigned short ModeIdIndex;
11332 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11334 if(*ModeNo <= 5) *ModeNo |= 1;
11336 for(ModeIdIndex=0; ; ModeIdIndex++) {
11337 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11338 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11341 if(*ModeNo != 0x07) {
11342 if(*ModeNo > 0x03) return ModeIdIndex;
11343 if(VGAINFO & 0x80) return ModeIdIndex;
11344 ModeIdIndex++;
11347 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11348 /* else 350 lines */
11349 return ModeIdIndex;
11352 static void
11353 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11354 unsigned short RefTableIndex)
11356 unsigned short OEMModeIdIndex = 0;
11358 if(!SiS_Pr->UseCustomMode) {
11359 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11360 if(!(OEMModeIdIndex)) return;
11363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11364 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11365 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11366 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11369 if(SiS_Pr->UseCustomMode) return;
11370 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11371 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11372 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11373 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11374 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11375 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11379 #endif