xref: /linux/drivers/video/fbdev/sis/init301.c (revision e9f0878c4b2004ac19581274c1ae4c61ae3ca70e)
1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4  * Mode initializing code (CRT2 section)
5  * for SiS 300/305/540/630/730,
6  *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7  *     XGI V3XT/V5/V8, Z7
8  * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9  *
10  * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11  *
12  * If distributed as part of the Linux kernel, the following license terms
13  * apply:
14  *
15  * * This program is free software; you can redistribute it and/or modify
16  * * it under the terms of the GNU General Public License as published by
17  * * the Free Software Foundation; either version 2 of the named License,
18  * * or any later version.
19  * *
20  * * This program is distributed in the hope that it will be useful,
21  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * * GNU General Public License for more details.
24  * *
25  * * You should have received a copy of the GNU General Public License
26  * * along with this program; if not, write to the Free Software
27  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28  *
29  * Otherwise, the following license terms apply:
30  *
31  * * Redistribution and use in source and binary forms, with or without
32  * * modification, are permitted provided that the following conditions
33  * * are met:
34  * * 1) Redistributions of source code must retain the above copyright
35  * *    notice, this list of conditions and the following disclaimer.
36  * * 2) Redistributions in binary form must reproduce the above copyright
37  * *    notice, this list of conditions and the following disclaimer in the
38  * *    documentation and/or other materials provided with the distribution.
39  * * 3) The name of the author may not be used to endorse or promote products
40  * *    derived from this software without specific prior written permission.
41  * *
42  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52  *
53  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
54  *
55  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56  * Used by permission.
57  *
58  */
59 
60 #if 1
61 #define SET_EMI		/* 302LV/ELV: Set EMI values */
62 #endif
63 
64 #if 1
65 #define SET_PWD		/* 301/302LV: Set PWD */
66 #endif
67 
68 #define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */
69 #define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */
70 #define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */
71 
72 #include "init301.h"
73 
74 #ifdef CONFIG_FB_SIS_300
75 #include "oem300.h"
76 #endif
77 
78 #ifdef CONFIG_FB_SIS_315
79 #include "oem310.h"
80 #endif
81 
82 #define SiS_I2CDELAY      1000
83 #define SiS_I2CDELAYSHORT  150
84 
85 static const unsigned char SiS_YPbPrTable[3][64] = {
86   {
87     0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
88     0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
89     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
90     0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
91     0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
92     0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
93     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
94     0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
95   },
96   {
97     0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
98     0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
99     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
100     0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
101     0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
102     0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
103     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
104     0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
105   },
106   {
107 #if 0 /* OK, but sticks to left edge */
108     0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
109     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
110     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
111     0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
112     0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
113     0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
114     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
115     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
116 #endif
117 #if 1 /* Perfect */
118     0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
119     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
120     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
121     0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
122     0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
123     0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
124     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
125     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
126 #endif
127   }
128 };
129 
130 static const unsigned char SiS_TVPhase[] =
131 {
132 	0x21,0xED,0xBA,0x08,	/* 0x00 SiS_NTSCPhase */
133 	0x2A,0x05,0xE3,0x00,	/* 0x01 SiS_PALPhase */
134 	0x21,0xE4,0x2E,0x9B,	/* 0x02 SiS_PALMPhase */
135 	0x21,0xF4,0x3E,0xBA,	/* 0x03 SiS_PALNPhase */
136 	0x1E,0x8B,0xA2,0xA7,
137 	0x1E,0x83,0x0A,0xE0,	/* 0x05 SiS_SpecialPhaseM */
138 	0x00,0x00,0x00,0x00,
139 	0x00,0x00,0x00,0x00,
140 	0x21,0xF0,0x7B,0xD6,	/* 0x08 SiS_NTSCPhase2 */
141 	0x2A,0x09,0x86,0xE9,	/* 0x09 SiS_PALPhase2 */
142 	0x21,0xE6,0xEF,0xA4,	/* 0x0a SiS_PALMPhase2 */
143 	0x21,0xF6,0x94,0x46,	/* 0x0b SiS_PALNPhase2 */
144 	0x1E,0x8B,0xA2,0xA7,
145 	0x1E,0x83,0x0A,0xE0,	/* 0x0d SiS_SpecialPhaseM */
146 	0x00,0x00,0x00,0x00,
147 	0x00,0x00,0x00,0x00,
148 	0x1e,0x8c,0x5c,0x7a,	/* 0x10 SiS_SpecialPhase */
149 	0x25,0xd4,0xfd,0x5e	/* 0x11 SiS_SpecialPhaseJ */
150 };
151 
152 static const unsigned char SiS_HiTVGroup3_1[] = {
153     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
154     0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
155     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
156     0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
157     0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
158     0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
159     0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
160     0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
161 };
162 
163 static const unsigned char SiS_HiTVGroup3_2[] = {
164     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
165     0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
166     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
167     0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
168     0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
169     0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
170     0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
171     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
172 };
173 
174 /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
175 
176 static const unsigned char SiS_Part2CLVX_1[] = {
177     0x00,0x00,
178     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
179     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
180     0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
181     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
182 };
183 
184 static const unsigned char SiS_Part2CLVX_2[] = {
185     0x00,0x00,
186     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
187     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
188     0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
189     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
190 };
191 
192 static const unsigned char SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
193     0xE0,0x01,
194     0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
195     0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
196     0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
197     0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
198     0x58,0x02,
199     0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
200     0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
201     0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
202     0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
203     0x00,0x03,
204     0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
205     0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
206     0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
207     0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
208     0xFF,0xFF
209 };
210 
211 static const unsigned char SiS_Part2CLVX_4[] = {   /* PAL */
212     0x58,0x02,
213     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
214     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
215     0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
216     0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
217     0x00,0x03,
218     0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
219     0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
220     0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
221     0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
222     0x40,0x02,
223     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
224     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
225     0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
226     0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
227     0xFF,0xFF
228 };
229 
230 static const unsigned char SiS_Part2CLVX_5[] = {   /* 750p */
231     0x00,0x03,
232     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
233     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
234     0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
235     0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
236     0xFF,0xFF
237 };
238 
239 static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */
240     0x00,0x04,
241     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
242     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
243     0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
244     0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
245     0xFF,0xFF,
246 };
247 
248 #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
287 };
288 #endif
289 
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 }
363 };
364 #endif
365 
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 */
372 
373 #ifdef CONFIG_FB_SIS_300
374 static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
375 #endif
376 
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);
396 
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
410 
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);
413 
414 /*********************************************/
415 /*         HELPER: Lock/Unlock CRT2          */
416 /*********************************************/
417 
418 void
419 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
420 {
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);
427 }
428 
429 static
430 void
431 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
432 {
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);
439 }
440 
441 /*********************************************/
442 /*            HELPER: Write SR11             */
443 /*********************************************/
444 
445 static void
446 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
447 {
448    if(SiS_Pr->ChipType >= SIS_661) {
449       DataAND &= 0x0f;
450       DataOR  &= 0x0f;
451    }
452    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
453 }
454 
455 /*********************************************/
456 /*    HELPER: Get Pointer to LCD structure   */
457 /*********************************************/
458 
459 #ifdef CONFIG_FB_SIS_315
460 static unsigned char *
461 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
462 {
463    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
464    unsigned char  *myptr = NULL;
465    unsigned short romindex = 0, reg = 0, idx = 0;
466 
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.
472     */
473 
474    if((SiS_Pr->SiS_ROMNew) &&
475       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
476 
477       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
478       else                           reg = 0x7d;
479 
480       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
481 
482       if(idx < (8*26)) {
483          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
484       }
485       romindex = SISGETROMW(0x100);
486       if(romindex) {
487          romindex += idx;
488          myptr = &ROMAddr[romindex];
489       }
490    }
491    return myptr;
492 }
493 
494 static unsigned short
495 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
496 {
497    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
498    unsigned short romptr = 0;
499 
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.
505     */
506 
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);
511    }
512 
513    return romptr;
514 }
515 #endif
516 
517 /*********************************************/
518 /*           Adjust Rate for CRT2            */
519 /*********************************************/
520 
521 static bool
522 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
523 		unsigned short RRTI, unsigned short *i)
524 {
525    unsigned short checkmask=0, modeid, infoflag;
526 
527    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
528 
529    if(SiS_Pr->SiS_VBType & VB_SISVB) {
530 
531       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
532 
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;
540 	       }
541 	    }
542 	 }
543 
544       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
545 
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;
551 	       }
552 	    }
553 	 }
554 
555       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
556 
557 	 checkmask |= SupportHiVision;
558 
559       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
560 
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;
567 	       }
568 	    }
569 	 }
570 
571       }
572 
573    } else {	/* LVDS */
574 
575       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
576 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
577 	    checkmask |= SupportCHTV;
578 	 }
579       }
580 
581       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
582 	 checkmask |= SupportLCD;
583       }
584 
585    }
586 
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;
592    }
593 
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.
596     */
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;
601    }
602    return false;
603 }
604 
605 /*********************************************/
606 /*              Get rate index               */
607 /*********************************************/
608 
609 unsigned short
610 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
611 {
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
620    };
621 
622    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
623    if(ModeNo == 0xfe) return 0;
624 
625    if(ModeNo <= 0x13) {
626       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
627    } else {
628       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
629    }
630 
631    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
632       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
633 	 if(modeflag & HalfDCLK) return 0;
634       }
635    }
636 
637    if(ModeNo < 0x14) return 0xFFFF;
638 
639    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
640    backupindex = index;
641 
642    if(index > 0) index--;
643 
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;
649 	 }
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;
654 	    }
655 	 }
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;
660 	 }
661       }
662    }
663 
664    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
665    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
666 
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++;
672 	 }
673       }
674    }
675 
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);
685 
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++;
690       }
691    }
692 
693    i--;
694 
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;
699       }
700    }
701 
702    return (RRTI + i);
703 }
704 
705 /*********************************************/
706 /*            STORE CRT2 INFO in CR34        */
707 /*********************************************/
708 
709 static void
710 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
711 {
712    unsigned short temp1, temp2;
713 
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);
719 }
720 
721 /*********************************************/
722 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
723 /*********************************************/
724 
725 #ifdef CONFIG_FB_SIS_300
726 static bool
727 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
728 {
729    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
730    unsigned short temp,temp1;
731 
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;
737       }
738    }
739    return false;
740 }
741 
742 static bool
743 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
744 {
745    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
746    unsigned short temp,temp1;
747 
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;
753       }
754    }
755    return false;
756 }
757 #endif
758 
759 /*********************************************/
760 /*          HELPER: DELAY FUNCTIONS          */
761 /*********************************************/
762 
763 void
764 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
765 {
766    while (delaytime-- > 0)
767       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
768 }
769 
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)
773 {
774    SiS_DDC2Delay(SiS_Pr, delay * 36);
775 }
776 #endif
777 
778 #ifdef CONFIG_FB_SIS_315
779 static void
780 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
781 {
782    while(delay--) {
783       SiS_GenericDelay(SiS_Pr, 6623);
784    }
785 }
786 #endif
787 
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)
791 {
792    while(delay--) {
793       SiS_GenericDelay(SiS_Pr, 66);
794    }
795 }
796 #endif
797 
798 static void
799 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
800 {
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
805 
806    if(SiS_Pr->ChipType < SIS_315H) {
807 
808 #ifdef CONFIG_FB_SIS_300
809 
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;
814       }
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];
824 	 }
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];
829 	    }
830 	 }
831       }
832       SiS_ShortDelay(SiS_Pr, Delay);
833 
834 #endif  /* CONFIG_FB_SIS_300 */
835 
836    } else {
837 
838 #ifdef CONFIG_FB_SIS_315
839 
840       if((SiS_Pr->ChipType >= SIS_661)    ||
841 	 (SiS_Pr->ChipType <= SIS_315PRO) ||
842 	 (SiS_Pr->ChipType == SIS_330)    ||
843 	 (SiS_Pr->SiS_ROMNew)) {
844 
845 	 if(!(DelayTime & 0x01)) {
846 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
847 	 } else {
848 	    SiS_DDC2Delay(SiS_Pr, 0x4000);
849 	 }
850 
851       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
852 	 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
853 	 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {			/* 315 series, LVDS; Special */
854 
855 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
856 	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
857 	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
858 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
859 	    }
860 	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
861 	       DelayIndex = PanelID & 0x0f;
862 	    } else {
863 	       DelayIndex = PanelID >> 4;
864 	    }
865 	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
866 	       Delay = 3;
867 	    } else {
868 	       if(DelayTime >= 2) DelayTime -= 2;
869 	       if(!(DelayTime & 0x01)) {
870 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
871 		} else {
872 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
873 	       }
874 	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
875 		  if(ROMAddr[0x13c] & 0x40) {
876 		     if(!(DelayTime & 0x01)) {
877 			Delay = (unsigned short)ROMAddr[0x17e];
878 		     } else {
879 			Delay = (unsigned short)ROMAddr[0x17f];
880 		     }
881 		  }
882 	       }
883 	    }
884 	    SiS_ShortDelay(SiS_Pr, Delay);
885 	 }
886 
887       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
888 
889 	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
890 	 if(!(DelayTime & 0x01)) {
891 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
892 	 } else {
893 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
894 	 }
895 	 Delay <<= 8;
896 	 SiS_DDC2Delay(SiS_Pr, Delay);
897 
898       }
899 
900 #endif /* CONFIG_FB_SIS_315 */
901 
902    }
903 }
904 
905 #ifdef CONFIG_FB_SIS_315
906 static void
907 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
908 {
909    int i;
910    for(i = 0; i < DelayLoop; i++) {
911       SiS_PanelDelay(SiS_Pr, DelayTime);
912    }
913 }
914 #endif
915 
916 /*********************************************/
917 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
918 /*********************************************/
919 
920 void
921 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
922 {
923    unsigned short watchdog;
924 
925    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
926    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
927 
928    watchdog = 65535;
929    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
930    watchdog = 65535;
931    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
932 }
933 
934 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
935 static void
936 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
937 {
938    unsigned short watchdog;
939 
940    watchdog = 65535;
941    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
942    watchdog = 65535;
943    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
944 }
945 #endif
946 
947 static void
948 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
949 {
950    if(SiS_Pr->ChipType < SIS_315H) {
951 #ifdef CONFIG_FB_SIS_300
952       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
953 	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
954       }
955       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
956 	 SiS_WaitRetrace1(SiS_Pr);
957       } else {
958 	 SiS_WaitRetrace2(SiS_Pr, 0x25);
959       }
960 #endif
961    } else {
962 #ifdef CONFIG_FB_SIS_315
963       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
964 	 SiS_WaitRetrace1(SiS_Pr);
965       } else {
966 	 SiS_WaitRetrace2(SiS_Pr, 0x30);
967       }
968 #endif
969    }
970 }
971 
972 static void
973 SiS_VBWait(struct SiS_Private *SiS_Pr)
974 {
975    unsigned short tempal,temp,i,j;
976 
977    temp = 0;
978    for(i = 0; i < 3; i++) {
979      for(j = 0; j < 100; j++) {
980         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
981         if(temp & 0x01) {
982 	   if((tempal & 0x08))  continue;
983 	   else break;
984         } else {
985 	   if(!(tempal & 0x08)) continue;
986 	   else break;
987         }
988      }
989      temp ^= 0x01;
990    }
991 }
992 
993 static void
994 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
995 {
996    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
997       SiS_VBWait(SiS_Pr);
998    } else {
999       SiS_WaitRetrace1(SiS_Pr);
1000    }
1001 }
1002 
1003 /*********************************************/
1004 /*               HELPER: MISC                */
1005 /*********************************************/
1006 
1007 #ifdef CONFIG_FB_SIS_300
1008 static bool
1009 SiS_Is301B(struct SiS_Private *SiS_Pr)
1010 {
1011    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1012    return false;
1013 }
1014 #endif
1015 
1016 static bool
1017 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1018 {
1019    if(SiS_Pr->ChipType == SIS_730) {
1020       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1021    }
1022    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1023    return false;
1024 }
1025 
1026 bool
1027 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1028 {
1029 #ifdef CONFIG_FB_SIS_315
1030    if(SiS_Pr->ChipType >= SIS_315H) {
1031       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1032 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1033       }
1034    }
1035 #endif
1036    return false;
1037 }
1038 
1039 bool
1040 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1041 {
1042 #ifdef CONFIG_FB_SIS_315
1043    unsigned short flag;
1044 
1045    if(SiS_Pr->ChipType >= SIS_315H) {
1046       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1047       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1048    }
1049 #endif
1050    return false;
1051 }
1052 
1053 #ifdef CONFIG_FB_SIS_315
1054 static bool
1055 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1056 {
1057    if(SiS_IsVAMode(SiS_Pr))  return true;
1058    if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1059    return false;
1060 }
1061 #endif
1062 
1063 static bool
1064 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1065 {
1066 #ifdef CONFIG_FB_SIS_315
1067    if(SiS_Pr->ChipType >= SIS_315H) {
1068       if((SiS_CRT2IsLCD(SiS_Pr)) ||
1069          (SiS_IsVAMode(SiS_Pr))) {
1070 	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1071       }
1072    }
1073 #endif
1074    return false;
1075 }
1076 
1077 #ifdef CONFIG_FB_SIS_315
1078 static bool
1079 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1080 {
1081    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1082    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1083       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1084    }
1085    return false;
1086 }
1087 #endif
1088 
1089 #ifdef CONFIG_FB_SIS_315
1090 static bool
1091 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1092 {
1093    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1094    return false;
1095 }
1096 #endif
1097 
1098 #ifdef CONFIG_FB_SIS_315
1099 static bool
1100 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1101 {
1102    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1103       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1104    }
1105    return false;
1106 }
1107 #endif
1108 
1109 #ifdef CONFIG_FB_SIS_315
1110 static bool
1111 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1112 {
1113    unsigned short flag;
1114 
1115    if(SiS_Pr->ChipType == SIS_650) {
1116       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1117       /* Check for revision != A0 only */
1118       if((flag == 0xe0) || (flag == 0xc0) ||
1119          (flag == 0xb0) || (flag == 0x90)) return false;
1120    } else if(SiS_Pr->ChipType >= SIS_661) return false;
1121    return true;
1122 }
1123 #endif
1124 
1125 #ifdef CONFIG_FB_SIS_315
1126 static bool
1127 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1128 {
1129    if(SiS_Pr->ChipType >= SIS_315H) {
1130       /* YPrPb = 0x08 */
1131       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1132    }
1133    return false;
1134 }
1135 #endif
1136 
1137 #ifdef CONFIG_FB_SIS_315
1138 static bool
1139 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1140 {
1141    if(SiS_Pr->ChipType >= SIS_315H) {
1142       /* Scart = 0x04 */
1143       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1144    }
1145    return false;
1146 }
1147 #endif
1148 
1149 #ifdef CONFIG_FB_SIS_315
1150 static bool
1151 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1152 {
1153    unsigned short flag;
1154 
1155    if(SiS_Pr->ChipType >= SIS_315H) {
1156       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1157       if(flag & SetCRT2ToTV)        return true;
1158       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1159       if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
1160       if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
1161    } else {
1162       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1163       if(flag & SetCRT2ToTV)        return true;
1164    }
1165    return false;
1166 }
1167 #endif
1168 
1169 #ifdef CONFIG_FB_SIS_315
1170 static bool
1171 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1172 {
1173    unsigned short flag;
1174 
1175    if(SiS_Pr->ChipType >= SIS_315H) {
1176       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1177       if(flag & SetCRT2ToLCD) return true;
1178       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1179       if(flag & SetToLCDA)    return true;
1180    } else {
1181       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1182       if(flag & SetCRT2ToLCD) return true;
1183    }
1184    return false;
1185 }
1186 #endif
1187 
1188 static bool
1189 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1190 {
1191    unsigned short flag;
1192 
1193    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1194       return true;
1195    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1196       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1197       if((flag == 1) || (flag == 2)) return true;
1198    }
1199    return false;
1200 }
1201 
1202 static bool
1203 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1204 {
1205    unsigned short flag;
1206 
1207    if(SiS_HaveBridge(SiS_Pr)) {
1208       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1209       if(SiS_Pr->ChipType < SIS_315H) {
1210 	flag &= 0xa0;
1211 	if((flag == 0x80) || (flag == 0x20)) return true;
1212       } else {
1213 	flag &= 0x50;
1214 	if((flag == 0x40) || (flag == 0x10)) return true;
1215       }
1216    }
1217    return false;
1218 }
1219 
1220 static bool
1221 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1222 {
1223    unsigned short flag1;
1224 
1225    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1226    if(flag1 & (SetInSlaveMode >> 8)) return true;
1227    return false;
1228 }
1229 
1230 /*********************************************/
1231 /*       GET VIDEO BRIDGE CONFIG INFO        */
1232 /*********************************************/
1233 
1234 /* Setup general purpose IO for Chrontel communication */
1235 #ifdef CONFIG_FB_SIS_300
1236 void
1237 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1238 {
1239    unsigned int   acpibase;
1240    unsigned short temp;
1241 
1242    if(!(SiS_Pr->SiS_ChSW)) return;
1243 
1244    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1245    acpibase &= 0xFFFF;
1246    if(!acpibase) return;
1247    temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
1248    temp &= 0xFEFF;
1249    SiS_SetRegShort((acpibase + 0x3c), temp);
1250    temp = SiS_GetRegShort((acpibase + 0x3c));
1251    temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
1252    temp &= 0xFEFF;
1253    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1254    SiS_SetRegShort((acpibase + 0x3a), temp);
1255    temp = SiS_GetRegShort((acpibase + 0x3a));
1256 }
1257 #endif
1258 
1259 void
1260 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1261 		unsigned short ModeIdIndex, int checkcrt2mode)
1262 {
1263    unsigned short tempax, tempbx, temp;
1264    unsigned short modeflag, resinfo = 0;
1265 
1266    SiS_Pr->SiS_SetFlag = 0;
1267 
1268    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1269 
1270    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1271 
1272    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1273       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1274    }
1275 
1276    tempbx = 0;
1277 
1278    if(SiS_HaveBridge(SiS_Pr)) {
1279 
1280 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1281 	tempbx |= temp;
1282 	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1283 	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1284 	tempbx |= tempax;
1285 
1286 #ifdef CONFIG_FB_SIS_315
1287 	if(SiS_Pr->ChipType >= SIS_315H) {
1288 	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1289 	      if(ModeNo == 0x03) {
1290 		 /* Mode 0x03 is never in driver mode */
1291 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1292 	      }
1293 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1294 		 /* Reset LCDA setting if not driver mode */
1295 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1296 	      }
1297 	      if(IS_SIS650) {
1298 		 if(SiS_Pr->SiS_UseLCDA) {
1299 		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1300 		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1301 			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1302 		       }
1303 		    }
1304 		 }
1305 	      }
1306 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1307 	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1308 		 tempbx |= SetCRT2ToLCDA;
1309 	      }
1310 	   }
1311 
1312 	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1313 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1314 	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1315 		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1316 		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1317 		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1318 		    tempbx |= SetCRT2ToYPbPr525750;
1319 		 }
1320 	      }
1321 	   }
1322 
1323 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1324 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1325 	      if(temp & SetToLCDA) {
1326 		 tempbx |= SetCRT2ToLCDA;
1327 	      }
1328 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1329 		 if(temp & EnableCHYPbPr) {
1330 		    tempbx |= SetCRT2ToCHYPbPr;
1331 		 }
1332 	      }
1333 	   }
1334 	}
1335 
1336 #endif  /* CONFIG_FB_SIS_315 */
1337 
1338         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1339 	   tempbx &= ~(SetCRT2ToRAMDAC);
1340 	}
1341 
1342 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1343 	   temp = SetCRT2ToSVIDEO   |
1344 		  SetCRT2ToAVIDEO   |
1345 		  SetCRT2ToSCART    |
1346 		  SetCRT2ToLCDA     |
1347 		  SetCRT2ToLCD      |
1348 		  SetCRT2ToRAMDAC   |
1349 		  SetCRT2ToHiVision |
1350 		  SetCRT2ToYPbPr525750;
1351 	} else {
1352 	   if(SiS_Pr->ChipType >= SIS_315H) {
1353 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1354 		 temp = SetCRT2ToAVIDEO |
1355 		        SetCRT2ToSVIDEO |
1356 		        SetCRT2ToSCART  |
1357 		        SetCRT2ToLCDA   |
1358 		        SetCRT2ToLCD    |
1359 		        SetCRT2ToCHYPbPr;
1360 	      } else {
1361 		 temp = SetCRT2ToLCDA   |
1362 		        SetCRT2ToLCD;
1363 	      }
1364 	   } else {
1365 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1366 		 temp = SetCRT2ToTV | SetCRT2ToLCD;
1367 	      } else {
1368 		 temp = SetCRT2ToLCD;
1369 	      }
1370 	   }
1371 	}
1372 
1373 	if(!(tempbx & temp)) {
1374 	   tempax = DisableCRT2Display;
1375 	   tempbx = 0;
1376 	}
1377 
1378 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1379 
1380 	   unsigned short clearmask = ( DriverMode |
1381 				DisableCRT2Display |
1382 				LoadDACFlag 	   |
1383 				SetNotSimuMode 	   |
1384 				SetInSlaveMode 	   |
1385 				SetPALTV 	   |
1386 				SwitchCRT2	   |
1387 				SetSimuScanMode );
1388 
1389 	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1390 	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1391 	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1392 	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1393 	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1394 	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1395 
1396 	} else {
1397 
1398 	   if(SiS_Pr->ChipType >= SIS_315H) {
1399 	      if(tempbx & SetCRT2ToLCDA) {
1400 		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1401 	      }
1402 	   }
1403 	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1404 	      if(tempbx & SetCRT2ToTV) {
1405 		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1406 	      }
1407 	   }
1408 	   if(tempbx & SetCRT2ToLCD) {
1409 	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1410 	   }
1411 	   if(SiS_Pr->ChipType >= SIS_315H) {
1412 	      if(tempbx & SetCRT2ToLCDA) {
1413 	         tempbx |= SetCRT2ToLCD;
1414 	      }
1415 	   }
1416 
1417 	}
1418 
1419 	if(tempax & DisableCRT2Display) {
1420 	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1421 	      tempbx = SetSimuScanMode | DisableCRT2Display;
1422 	   }
1423 	}
1424 
1425 	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1426 
1427 	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1428 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1429 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1430 	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1431 	      modeflag &= (~CRT2Mode);
1432 	   }
1433 	}
1434 
1435 	if(!(tempbx & SetSimuScanMode)) {
1436 	   if(tempbx & SwitchCRT2) {
1437 	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1438 		 if(resinfo != SIS_RI_1600x1200) {
1439 		    tempbx |= SetSimuScanMode;
1440 		 }
1441               }
1442 	   } else {
1443 	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
1444 		 if(!(tempbx & DriverMode)) {
1445 		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1446 		       tempbx |= SetSimuScanMode;
1447 		    }
1448 		 }
1449 	      }
1450 	   }
1451 	}
1452 
1453 	if(!(tempbx & DisableCRT2Display)) {
1454 	   if(tempbx & DriverMode) {
1455 	      if(tempbx & SetSimuScanMode) {
1456 		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1457 		    if(resinfo != SIS_RI_1600x1200) {
1458 		       tempbx |= SetInSlaveMode;
1459 		    }
1460 		 }
1461 	      }
1462 	   } else {
1463 	      tempbx |= SetInSlaveMode;
1464 	   }
1465 	}
1466 
1467    }
1468 
1469    SiS_Pr->SiS_VBInfo = tempbx;
1470 
1471 #ifdef CONFIG_FB_SIS_300
1472    if(SiS_Pr->ChipType == SIS_630) {
1473       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1474    }
1475 #endif
1476 
1477 #if 0
1478    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1479       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1480 #endif
1481 }
1482 
1483 /*********************************************/
1484 /*           DETERMINE YPbPr MODE            */
1485 /*********************************************/
1486 
1487 void
1488 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1489 {
1490 
1491    unsigned char temp;
1492 
1493    /* Note: This variable is only used on 30xLV systems.
1494     * CR38 has a different meaning on LVDS/CH7019 systems.
1495     * On 661 and later, these bits moved to CR35.
1496     *
1497     * On 301, 301B, only HiVision 1080i is supported.
1498     * On 30xLV, 301C, only YPbPr 1080i is supported.
1499     */
1500 
1501    SiS_Pr->SiS_YPbPr = 0;
1502    if(SiS_Pr->ChipType >= SIS_661) return;
1503 
1504    if(SiS_Pr->SiS_VBType) {
1505       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1506 	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1507       }
1508    }
1509 
1510    if(SiS_Pr->ChipType >= SIS_315H) {
1511       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1512 	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1513 	 if(temp & 0x08) {
1514 	    switch((temp >> 4)) {
1515 	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1516 	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1517 	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1518 	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1519 	    }
1520 	 }
1521       }
1522    }
1523 
1524 }
1525 
1526 /*********************************************/
1527 /*           DETERMINE TVMode flag           */
1528 /*********************************************/
1529 
1530 void
1531 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1532 {
1533    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1534    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1535    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1536 
1537    SiS_Pr->SiS_TVMode = 0;
1538 
1539    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1540    if(SiS_Pr->UseCustomMode) return;
1541 
1542    if(ModeNo > 0x13) {
1543       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1544    }
1545 
1546    if(SiS_Pr->ChipType < SIS_661) {
1547 
1548       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1549 
1550       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1551 	 temp = 0;
1552 	 if((SiS_Pr->ChipType == SIS_630) ||
1553 	    (SiS_Pr->ChipType == SIS_730)) {
1554 	    temp = 0x35;
1555 	    romindex = 0xfe;
1556 	 } else if(SiS_Pr->ChipType >= SIS_315H) {
1557 	    temp = 0x38;
1558 	    if(SiS_Pr->ChipType < XGI_20) {
1559 	       romindex = 0xf3;
1560 	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1561 	    }
1562 	 }
1563 	 if(temp) {
1564 	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1565 	       OutputSelect = ROMAddr[romindex];
1566 	       if(!(OutputSelect & EnablePALMN)) {
1567 		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1568 	       }
1569 	    }
1570 	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1571 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1572 	       if(temp1 & EnablePALM) {		/* 0x40 */
1573 		  SiS_Pr->SiS_TVMode |= TVSetPALM;
1574 		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1575 	       } else if(temp1 & EnablePALN) {	/* 0x80 */
1576 		  SiS_Pr->SiS_TVMode |= TVSetPALN;
1577 	       }
1578 	    } else {
1579 	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
1580 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1581 	       }
1582 	    }
1583 	 }
1584 	 /* Translate HiVision/YPbPr to our new flags */
1585 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1586 	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1587 	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1588 	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1589 	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1590 	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1591 	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1592 	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1593 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1594 	       SiS_Pr->SiS_TVMode |= TVSetPAL;
1595 	    }
1596 	 }
1597       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1598 	 if(SiS_Pr->SiS_CHOverScan) {
1599 	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1600 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1601 	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1602 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1603 	       }
1604 	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1605 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1606 	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1607 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1608 	       }
1609 	    }
1610 	    if(SiS_Pr->SiS_CHSOverScan) {
1611 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1612 	    }
1613 	 }
1614 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1615 	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1616 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1617 	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1618 	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1619 	    } else {
1620 	       if(temp & EnableNTSCJ) {
1621 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1622 	       }
1623 	    }
1624 	 }
1625       }
1626 
1627    } else {  /* 661 and later */
1628 
1629       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1630       if(temp1 & 0x01) {
1631 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1632 	 if(temp1 & 0x08) {
1633 	    SiS_Pr->SiS_TVMode |= TVSetPALN;
1634 	 } else if(temp1 & 0x04) {
1635 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1636 	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1637 	    }
1638 	    SiS_Pr->SiS_TVMode |= TVSetPALM;
1639 	 }
1640       } else {
1641 	 if(temp1 & 0x02) {
1642 	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1643 	 }
1644       }
1645       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1646 	 if(SiS_Pr->SiS_CHOverScan) {
1647 	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1648 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1649 	    }
1650 	 }
1651       }
1652       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1653 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1654 	    temp1 &= 0xe0;
1655 	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1656 	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1657 	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1658 	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1659 	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1660 	 }
1661 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1662 	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1663 	       SiS_Pr->SiS_TVMode |= TVAspect169;
1664 	    } else {
1665 	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1666 	       if(temp1 & 0x02) {
1667 		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1668 		     SiS_Pr->SiS_TVMode |= TVAspect169;
1669 		  } else {
1670 		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1671 		  }
1672 	       } else {
1673 		  SiS_Pr->SiS_TVMode |= TVAspect43;
1674 	       }
1675 	    }
1676 	 }
1677       }
1678    }
1679 
1680    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1681 
1682    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1683 
1684       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1685 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1686 	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1687       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1688 	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1689 	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1690 	 }
1691       }
1692 
1693       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1694 	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1695 	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1696 	 }
1697       }
1698 
1699       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1700 	 if(resinfo == SIS_RI_1024x768) {
1701 	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1702 	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
1703 	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1704 	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1705 	    }
1706 	 }
1707       }
1708 
1709       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1710       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1711 	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1712 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1713       } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1714 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1715       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1716 	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1717 	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1718 	 }
1719       }
1720 
1721    }
1722 
1723    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1724 }
1725 
1726 /*********************************************/
1727 /*               GET LCD INFO                */
1728 /*********************************************/
1729 
1730 static unsigned short
1731 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1732 {
1733    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1734    /* Translate my LCDResInfo to BIOS value */
1735    switch(temp) {
1736    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1737    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1738    case Panel_1280x854:   temp = Panel661_1280x854; break;
1739    }
1740    return temp;
1741 }
1742 
1743 static void
1744 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1745 {
1746 #ifdef CONFIG_FB_SIS_315
1747    unsigned char  *ROMAddr;
1748    unsigned short temp;
1749 
1750    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1751       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1752 	 SiS_Pr->SiS_NeedRomModeData = true;
1753 	 SiS_Pr->PanelHT  = temp;
1754       }
1755       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1756 	 SiS_Pr->SiS_NeedRomModeData = true;
1757 	 SiS_Pr->PanelVT  = temp;
1758       }
1759       SiS_Pr->PanelHRS = SISGETROMW(10);
1760       SiS_Pr->PanelHRE = SISGETROMW(12);
1761       SiS_Pr->PanelVRS = SISGETROMW(14);
1762       SiS_Pr->PanelVRE = SISGETROMW(16);
1763       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1764       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1765 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1766       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1767 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1768       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1769 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1770 
1771    }
1772 #endif
1773 }
1774 
1775 static void
1776 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1777 			const unsigned char *nonscalingmodes)
1778 {
1779    int i = 0;
1780    while(nonscalingmodes[i] != 0xff) {
1781       if(nonscalingmodes[i++] == resinfo) {
1782 	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1783 	    (SiS_Pr->UsePanelScaler == -1)) {
1784 	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1785 	 }
1786 	 break;
1787       }
1788    }
1789 }
1790 
1791 void
1792 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1793 {
1794   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1795   bool panelcanscale = false;
1796 #ifdef CONFIG_FB_SIS_300
1797   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1798   static const unsigned char SiS300SeriesLCDRes[] =
1799           { 0,  1,  2,  3,  7,  4,  5,  8,
1800 	    0,  0, 10,  0,  0,  0,  0, 15 };
1801 #endif
1802 #ifdef CONFIG_FB_SIS_315
1803   unsigned char   *myptr = NULL;
1804 #endif
1805 
1806   SiS_Pr->SiS_LCDResInfo  = 0;
1807   SiS_Pr->SiS_LCDTypeInfo = 0;
1808   SiS_Pr->SiS_LCDInfo     = 0;
1809   SiS_Pr->PanelHRS        = 999; /* HSync start */
1810   SiS_Pr->PanelHRE        = 999; /* HSync end */
1811   SiS_Pr->PanelVRS        = 999; /* VSync start */
1812   SiS_Pr->PanelVRE        = 999; /* VSync end */
1813   SiS_Pr->SiS_NeedRomModeData = false;
1814 
1815   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1816   SiS_Pr->Alternate1600x1200 = false;
1817 
1818   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1819 
1820   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1821 
1822   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1823      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1824      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1825      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1826   }
1827 
1828   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1829 
1830   /* For broken BIOSes: Assume 1024x768 */
1831   if(temp == 0) temp = 0x02;
1832 
1833   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1834      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1835   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1836      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1837   } else {
1838      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1839   }
1840   temp &= 0x0f;
1841 #ifdef CONFIG_FB_SIS_300
1842   if(SiS_Pr->ChipType < SIS_315H) {
1843      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1844      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1845         if(temp < 0x0f) temp &= 0x07;
1846      }
1847      /* Translate 300 series LCDRes to 315 series for unified usage */
1848      temp = SiS300SeriesLCDRes[temp];
1849   }
1850 #endif
1851 
1852   /* Translate to our internal types */
1853 #ifdef CONFIG_FB_SIS_315
1854   if(SiS_Pr->ChipType == SIS_550) {
1855      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1856      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1857      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1858   } else if(SiS_Pr->ChipType >= SIS_661) {
1859      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1860   }
1861 #endif
1862 
1863   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
1864      if(temp == Panel310_1280x768) {
1865         temp = Panel_1280x768_2;
1866      }
1867      if(SiS_Pr->SiS_ROMNew) {
1868 	if(temp == Panel661_1280x800) {
1869 	   temp = Panel_1280x800_2;
1870 	}
1871      }
1872   }
1873 
1874   SiS_Pr->SiS_LCDResInfo = temp;
1875 
1876 #ifdef CONFIG_FB_SIS_300
1877   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1878      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1879 	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1880      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1881 	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1882      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1883 	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1884      }
1885   }
1886 #endif
1887 
1888   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1889      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1890 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1891   } else {
1892      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1893 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1894   }
1895 
1896   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1897   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1898   /* Need temp below! */
1899 
1900   /* These must/can't scale no matter what */
1901   switch(SiS_Pr->SiS_LCDResInfo) {
1902   case Panel_320x240_1:
1903   case Panel_320x240_2:
1904   case Panel_320x240_3:
1905   case Panel_1280x960:
1906       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1907       break;
1908   case Panel_640x480:
1909       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1910   }
1911 
1912   panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1913 
1914   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1915   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1916 
1917   /* Dual link, Pass 1:1 BIOS default, etc. */
1918 #ifdef CONFIG_FB_SIS_315
1919   if(SiS_Pr->ChipType >= SIS_661) {
1920      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1921 	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1922      }
1923      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1924 	if(SiS_Pr->SiS_ROMNew) {
1925 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1926 	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1927 	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1928 	}
1929      }
1930   } else if(SiS_Pr->ChipType >= SIS_315H) {
1931      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1932 	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1933      }
1934      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1935 	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1936 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1937 	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1938 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1939 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1940 	}
1941      } else if(!(SiS_Pr->SiS_ROMNew)) {
1942 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1943 	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1944 	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1945 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1946 	   }
1947 	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1948 	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1949 	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1950 	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1951 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1952 	   }
1953 	}
1954      }
1955   }
1956 #endif
1957 
1958   /* Pass 1:1 */
1959   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1960      /* Always center screen on LVDS (if scaling is disabled) */
1961      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1962   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1963      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1964 	/* Always center screen on SiS LVDS (if scaling is disabled) */
1965 	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1966      } else {
1967 	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1968 	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1969 	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1970      }
1971   }
1972 
1973   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1974   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1975 
1976   switch(SiS_Pr->SiS_LCDResInfo) {
1977      case Panel_320x240_1:
1978      case Panel_320x240_2:
1979      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1980 			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1981 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1982 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1983 			    break;
1984      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1985 						      SiS_Pr->PanelVRE  =    3;
1986 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1987 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1988 			    break;
1989      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1990      			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1991 			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1992 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1993 			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1994 			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1995 			    break;
1996      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1997 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1998 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1999 			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
2000 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2001 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2002 			    break;
2003      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2004 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2005 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2006 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2007 			    if(SiS_Pr->ChipType < SIS_315H) {
2008 			       SiS_Pr->PanelHRS = 23;
2009 						      SiS_Pr->PanelVRE  =    5;
2010 			    }
2011 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2012 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2013 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2014 			    break;
2015      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
2016 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2017 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2018 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2019 			    if(SiS_Pr->ChipType < SIS_315H) {
2020 			       SiS_Pr->PanelHRS = 23;
2021 						      SiS_Pr->PanelVRE  =    5;
2022 			    }
2023 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2024 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2025 			    break;
2026      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
2027 			    break;
2028      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
2029 			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
2030 			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
2031 			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
2032 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2033 			    /* Data above for TMDS (projector); get from BIOS for LVDS */
2034 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2035 			    break;
2036      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2037 			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2038 			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
2039 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2040 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2041 			    } else {
2042 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
2043 			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2044 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2045 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2046 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2047 			    }
2048 			    break;
2049      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2050 			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
2051 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2052 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2053 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2054 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2055 			    break;
2056      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2057 			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
2058 			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
2059 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2060 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2061 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2062 			    break;
2063      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2064 			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
2065 			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
2066 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2067 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2068 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2069 			    break;
2070      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
2071 			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
2072 			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
2073 			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
2074 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2075 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2076 			    break;
2077      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
2078 			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
2079 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2080 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2081 			    if(resinfo == SIS_RI_1280x1024) {
2082 			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2083 			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2084 			    }
2085 			    break;
2086      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2087 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2088 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2089 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2090 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2091 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2092 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2093 			    break;
2094      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2095 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2096 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2097 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2098 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2099 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2100 			    break;
2101      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2102 			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
2103 			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
2104 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2105 			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2106 			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2107 			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2108 				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
2109 				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
2110 				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
2111 				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2112 				  SiS_Pr->Alternate1600x1200 = true;
2113 			       }
2114 			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2115 			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
2116 			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2117 			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2118 			    }
2119 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2120 			    break;
2121      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2122 			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
2123 			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
2124 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2125 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2126 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2127 			    break;
2128      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2129 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2130 			    break;
2131      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
2132 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2133 			    break;
2134      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
2135 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2136 			    break;
2137      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2138 			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2139 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
2140 			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
2141 			    if(SiS_Pr->CP_PreferredIndex != -1) {
2142 			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2143 			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2144 			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2145 			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2146 			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2147 			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2148 			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2149 			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2150 			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2151 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2152 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2153 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2154 			       if(SiS_Pr->CP_PrefClock) {
2155 				  int idx;
2156 				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2157 				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2158 				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2159 				  else				   idx = VCLK_CUSTOM_315;
2160 				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
2161 				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2162 				  SiS_Pr->SiS_VCLKData[idx].SR2B =
2163 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2164 				  SiS_Pr->SiS_VCLKData[idx].SR2C =
2165 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2166 			       }
2167 			    }
2168 			    break;
2169      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2170 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2171 			    break;
2172   }
2173 
2174   /* Special cases */
2175   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
2176       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
2177       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2178       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2179       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2180       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2181      SiS_Pr->PanelHRS = 999;
2182      SiS_Pr->PanelHRE = 999;
2183   }
2184 
2185   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2186       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2187       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2188       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2189      SiS_Pr->PanelVRS = 999;
2190      SiS_Pr->PanelVRE = 999;
2191   }
2192 
2193   /* DontExpand overrule */
2194   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2195 
2196      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2197 	/* No scaling for this mode on any panel (LCD=CRT2)*/
2198 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2199      }
2200 
2201      switch(SiS_Pr->SiS_LCDResInfo) {
2202 
2203      case Panel_Custom:
2204      case Panel_1152x864:
2205      case Panel_1280x768:	/* TMDS only */
2206 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2207 	break;
2208 
2209      case Panel_800x600: {
2210 	static const unsigned char nonscalingmodes[] = {
2211 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2212 	};
2213 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2214 	break;
2215      }
2216      case Panel_1024x768: {
2217 	static const unsigned char nonscalingmodes[] = {
2218 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2219 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2220 	   0xff
2221 	};
2222 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2223 	break;
2224      }
2225      case Panel_1280x720: {
2226 	static const unsigned char nonscalingmodes[] = {
2227 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2228 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2229 	   0xff
2230 	};
2231 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2232 	if(SiS_Pr->PanelHT == 1650) {
2233 	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2234 	}
2235 	break;
2236      }
2237      case Panel_1280x768_2: {  /* LVDS only */
2238 	static const unsigned char nonscalingmodes[] = {
2239 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2240 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2241 	   SIS_RI_1152x768,0xff
2242 	};
2243 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2244 	switch(resinfo) {
2245 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2246 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2247 			       }
2248 			       break;
2249 	}
2250 	break;
2251      }
2252      case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
2253 	static const unsigned char nonscalingmodes[] = {
2254 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2255 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2256 	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2257 	};
2258 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2259 	break;
2260      }
2261      case Panel_1280x800_2:  { 	/* SiS LVDS */
2262 	static const unsigned char nonscalingmodes[] = {
2263 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2264 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2265 	   SIS_RI_1152x768,0xff
2266 	};
2267 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2268 	switch(resinfo) {
2269 	case SIS_RI_1280x720:
2270 	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
2271 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2272 			       }
2273 			       break;
2274 	}
2275 	break;
2276      }
2277      case Panel_1280x854: {  	/* SiS LVDS */
2278 	static const unsigned char nonscalingmodes[] = {
2279 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2280 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2281 	   SIS_RI_1152x768,0xff
2282 	};
2283 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2284 	switch(resinfo) {
2285 	case SIS_RI_1280x720:
2286 	case SIS_RI_1280x768:
2287 	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2288 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2289 			       }
2290 			       break;
2291 	}
2292 	break;
2293      }
2294      case Panel_1280x960: {
2295 	static const unsigned char nonscalingmodes[] = {
2296 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2297 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2298 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2299 	   SIS_RI_1280x854,0xff
2300 	};
2301 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2302 	break;
2303      }
2304      case Panel_1280x1024: {
2305 	static const unsigned char nonscalingmodes[] = {
2306 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2307 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2308 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2309 	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
2310 	};
2311 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2312 	break;
2313      }
2314      case Panel_1400x1050: {
2315 	static const unsigned char nonscalingmodes[] = {
2316 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2317 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2318 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2319 	     SIS_RI_1280x960,0xff
2320 	};
2321 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2322 	switch(resinfo) {
2323 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2324 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2325 			       }
2326 			       break;
2327 	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2328 			       break;
2329 	}
2330 	break;
2331      }
2332      case Panel_1600x1200: {
2333 	static const unsigned char nonscalingmodes[] = {
2334 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2335 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2336 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2337 	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2338 	};
2339 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2340 	break;
2341      }
2342      case Panel_1680x1050: {
2343 	static const unsigned char nonscalingmodes[] = {
2344 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2345 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2346 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2347 	     SIS_RI_1360x1024,0xff
2348 	};
2349 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2350 	break;
2351      }
2352      }
2353   }
2354 
2355 #ifdef CONFIG_FB_SIS_300
2356   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2357      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2358 	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2359      }
2360   }
2361 
2362   if(SiS_Pr->ChipType < SIS_315H) {
2363      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2364 	if(SiS_Pr->SiS_UseROM) {
2365 	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2366 	      if(!(ROMAddr[0x235] & 0x02)) {
2367 		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2368 	      }
2369 	   }
2370 	}
2371      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2372 	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2373 	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2374 	}
2375      }
2376   }
2377 #endif
2378 
2379   /* Special cases */
2380 
2381   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2382      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2383   }
2384 
2385   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2386      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2387   }
2388 
2389   switch(SiS_Pr->SiS_LCDResInfo) {
2390   case Panel_640x480:
2391      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2392      break;
2393   case Panel_1280x800:
2394      /* Don't pass 1:1 by default (TMDS special) */
2395      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2396      break;
2397   case Panel_1280x960:
2398      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2399      break;
2400   case Panel_Custom:
2401      if((!SiS_Pr->CP_PrefClock) ||
2402         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2403         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2404      }
2405      break;
2406   }
2407 
2408   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2409      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2410   }
2411 
2412   /* (In)validate LCDPass11 flag */
2413   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2414      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2415   }
2416 
2417   /* LVDS DDA */
2418   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2419 
2420      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2421 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2422 	   if(ModeNo == 0x12) {
2423 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2424 		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2425 	      }
2426 	   } else if(ModeNo > 0x13) {
2427 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2428 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2429 		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2430 		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2431 		    }
2432 		 }
2433 	      }
2434 	   }
2435 	}
2436      }
2437 
2438      if(modeflag & HalfDCLK) {
2439 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2440 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2441 	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2442 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2443 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2444 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2445 	} else if(ModeNo > 0x13) {
2446 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2447 	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2448 	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2449 	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2450 	   }
2451 	}
2452      }
2453 
2454   }
2455 
2456   /* VESA timing */
2457   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2458      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2459 	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2460      }
2461   } else {
2462      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2463   }
2464 
2465 #if 0
2466   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2467 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2468 #endif
2469 }
2470 
2471 /*********************************************/
2472 /*                 GET VCLK                  */
2473 /*********************************************/
2474 
2475 unsigned short
2476 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2477 		unsigned short RefreshRateTableIndex)
2478 {
2479   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2480   unsigned short resinfo, tempbx;
2481   const unsigned char *CHTVVCLKPtr = NULL;
2482 
2483   if(ModeNo <= 0x13) {
2484      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2485      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2486      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2487      VCLKIndexGENCRT = VCLKIndexGEN;
2488   } else {
2489      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2490      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2491      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2492      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2493 		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2494   }
2495 
2496   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2497 
2498      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2499 
2500 	CRT2Index >>= 6;
2501 	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2502 
2503 	   if(SiS_Pr->ChipType < SIS_315H) {
2504 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2505 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2506 		 VCLKIndex = VCLKIndexGEN;
2507 	      }
2508 	   } else {
2509 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2510 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2511 		 switch(resinfo) {
2512 		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2513 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2514 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2515 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2516 		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2517 		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2518 		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2519 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2520 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2521 		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2522 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2523 		 default:              VCLKIndex = VCLKIndexGEN;
2524 		 }
2525 
2526 		 if(ModeNo <= 0x13) {
2527 		    if(SiS_Pr->ChipType <= SIS_315PRO) {
2528 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2529 		    } else {
2530 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2531 		    }
2532 		 }
2533 		 if(SiS_Pr->ChipType <= SIS_315PRO) {
2534 		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2535 		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2536 		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2537 		 }
2538 	      }
2539 	   }
2540 
2541 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2542 
2543 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2544 	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
2545 	      else                                  	   VCLKIndex = HiTVVCLK;
2546 	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2547 	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2548 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2549 	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2550 	   else						   VCLKIndex = TVVCLK;
2551 
2552 	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2553 	   else				   VCLKIndex += TVCLKBASE_315;
2554 
2555 	} else {							/* VGA2 */
2556 
2557 	   VCLKIndex = VCLKIndexGENCRT;
2558 	   if(SiS_Pr->ChipType < SIS_315H) {
2559 	      if(ModeNo > 0x13) {
2560 		 if( (SiS_Pr->ChipType == SIS_630) &&
2561 		     (SiS_Pr->ChipRevision >= 0x30)) {
2562 		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2563 		 }
2564 		 /* Better VGA2 clock for 1280x1024@75 */
2565 		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2566 	      }
2567 	   }
2568 	}
2569 
2570      } else {   /* If not programming CRT2 */
2571 
2572 	VCLKIndex = VCLKIndexGENCRT;
2573 	if(SiS_Pr->ChipType < SIS_315H) {
2574 	   if(ModeNo > 0x13) {
2575 	      if( (SiS_Pr->ChipType != SIS_630) &&
2576 		  (SiS_Pr->ChipType != SIS_300) ) {
2577 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2578 	      }
2579 	   }
2580 	}
2581      }
2582 
2583   } else {       /*   LVDS  */
2584 
2585      VCLKIndex = CRT2Index;
2586 
2587      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2588 
2589 	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2590 
2591 	   VCLKIndex &= 0x1f;
2592 	   tempbx = 0;
2593 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2594 	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2595 	      tempbx += 2;
2596 	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2597 		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2598 	      }
2599 	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2600 		 tempbx = 4;
2601 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2602 	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2603 		 tempbx = 6;
2604 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2605 	      }
2606 	   }
2607 	   switch(tempbx) {
2608 	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2609 	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2610 	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2611 	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2612 	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2613 	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2614 	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2615 	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2616 	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2617 	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2618 	   }
2619 	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2620 
2621 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2622 
2623 	   if(SiS_Pr->ChipType < SIS_315H) {
2624 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2625 	   } else {
2626 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2627 	   }
2628 
2629 #ifdef CONFIG_FB_SIS_300
2630 	   /* Special Timing: Barco iQ Pro R series */
2631 	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2632 
2633 	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2634 	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2635 	      if(SiS_Pr->ChipType < SIS_315H) {
2636 		 VCLKIndex = VCLK34_300;
2637 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2638 	      } else {
2639 		 VCLKIndex = VCLK34_315;
2640 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2641 	      }
2642 	   }
2643 #endif
2644 
2645 	} else {
2646 
2647 	   VCLKIndex = VCLKIndexGENCRT;
2648 	   if(SiS_Pr->ChipType < SIS_315H) {
2649 	      if(ModeNo > 0x13) {
2650 		 if( (SiS_Pr->ChipType == SIS_630) &&
2651 		     (SiS_Pr->ChipRevision >= 0x30) ) {
2652 		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2653 		 }
2654 	      }
2655 	   }
2656 	}
2657 
2658      } else {  /* if not programming CRT2 */
2659 
2660 	VCLKIndex = VCLKIndexGENCRT;
2661 	if(SiS_Pr->ChipType < SIS_315H) {
2662 	   if(ModeNo > 0x13) {
2663 	      if( (SiS_Pr->ChipType != SIS_630) &&
2664 		  (SiS_Pr->ChipType != SIS_300) ) {
2665 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2666 	      }
2667 #if 0
2668 	      if(SiS_Pr->ChipType == SIS_730) {
2669 		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2670 		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2671 	      }
2672 #endif
2673 	   }
2674         }
2675 
2676      }
2677 
2678   }
2679 
2680   return VCLKIndex;
2681 }
2682 
2683 /*********************************************/
2684 /*        SET CRT2 MODE TYPE REGISTERS       */
2685 /*********************************************/
2686 
2687 static void
2688 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2689 {
2690   unsigned short i, j, modeflag, tempah=0;
2691   short tempcl;
2692 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2693   unsigned short tempbl;
2694 #endif
2695 #ifdef CONFIG_FB_SIS_315
2696   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2697   unsigned short tempah2, tempbl2;
2698 #endif
2699 
2700   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2701 
2702   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2703 
2704      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2705      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2706 
2707   } else {
2708 
2709      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2710      if(SiS_Pr->ChipType >= SIS_315H) {
2711         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2712      }
2713 
2714      tempcl = SiS_Pr->SiS_ModeType;
2715 
2716      if(SiS_Pr->ChipType < SIS_315H) {
2717 
2718 #ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
2719 
2720 	/* For 301BDH: (with LCD via LVDS) */
2721 	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2722 	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2723 	   tempbl &= 0xef;
2724 	   tempbl |= 0x02;
2725 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2726 	      tempbl |= 0x10;
2727 	      tempbl &= 0xfd;
2728 	   }
2729 	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2730 	}
2731 
2732 	if(ModeNo > 0x13) {
2733 	   tempcl -= ModeVGA;
2734 	   if(tempcl >= 0) {
2735 	      tempah = ((0x10 >> tempcl) | 0x80);
2736 	   }
2737 	} else tempah = 0x80;
2738 
2739 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2740 
2741 #endif  /* CONFIG_FB_SIS_300 */
2742 
2743      } else {
2744 
2745 #ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
2746 
2747 	if(ModeNo > 0x13) {
2748 	   tempcl -= ModeVGA;
2749 	   if(tempcl >= 0) {
2750 	      tempah = (0x08 >> tempcl);
2751 	      if (tempah == 0) tempah = 1;
2752 	      tempah |= 0x40;
2753 	   }
2754 	} else tempah = 0x40;
2755 
2756 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2757 
2758 #endif  /* CONFIG_FB_SIS_315 */
2759 
2760      }
2761 
2762      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2763 
2764      if(SiS_Pr->ChipType < SIS_315H) {
2765 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2766      } else {
2767 #ifdef CONFIG_FB_SIS_315
2768 	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2769 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2770 	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2771 	   if(IS_SIS740) {
2772 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2773 	   } else {
2774 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2775 	   }
2776 	}
2777 #endif
2778      }
2779 
2780      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2781 
2782 	tempah = 0x01;
2783 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2784 	   tempah |= 0x02;
2785 	}
2786 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2787 	   tempah ^= 0x05;
2788 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2789 	      tempah ^= 0x01;
2790 	   }
2791 	}
2792 
2793 	if(SiS_Pr->ChipType < SIS_315H) {
2794 
2795 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2796 
2797 	   tempah = (tempah << 5) & 0xFF;
2798 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2799 	   tempah = (tempah >> 5) & 0xFF;
2800 
2801 	} else {
2802 
2803 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2804 	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2805 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2806 	   tempah &= ~0x08;
2807 
2808 	}
2809 
2810 	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2811 	   tempah |= 0x10;
2812 	}
2813 
2814 	tempah |= 0x80;
2815 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2816 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2817 	}
2818 
2819 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2820 	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2821 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2822 		 tempah |= 0x20;
2823 	      }
2824 	   }
2825 	}
2826 
2827 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2828 
2829 	tempah = 0x80;
2830 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2831 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2832 	}
2833 
2834 	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2835 
2836 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2837 	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2838 	      tempah |= 0x40;
2839 	   }
2840 	}
2841 
2842 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2843 
2844      } else {  /* LVDS */
2845 
2846 	if(SiS_Pr->ChipType >= SIS_315H) {
2847 
2848 #ifdef CONFIG_FB_SIS_315
2849 	   /* LVDS can only be slave in 8bpp modes */
2850 	   tempah = 0x80;
2851 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2852 	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2853 	         tempah |= 0x02;
2854 	      }
2855 	   }
2856 
2857 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2858 
2859 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2860 
2861 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2862 
2863 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2864 #endif
2865 
2866 	} else {
2867 
2868 #ifdef CONFIG_FB_SIS_300
2869 	   tempah = 0;
2870 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2871 	      tempah |= 0x02;
2872 	   }
2873 	   tempah <<= 5;
2874 
2875 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2876 
2877 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2878 #endif
2879 
2880 	}
2881 
2882      }
2883 
2884   }  /* LCDA */
2885 
2886   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2887 
2888      if(SiS_Pr->ChipType >= SIS_315H) {
2889 
2890 #ifdef CONFIG_FB_SIS_315
2891 	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2892 
2893 	/* The following is nearly unpreditable and varies from machine
2894 	 * to machine. Especially the 301DH seems to be a real trouble
2895 	 * maker. Some BIOSes simply set the registers (like in the
2896 	 * NoLCD-if-statements here), some set them according to the
2897 	 * LCDA stuff. It is very likely that some machines are not
2898 	 * treated correctly in the following, very case-orientated
2899 	 * code. What do I do then...?
2900 	 */
2901 
2902 	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2903 
2904 	if(!(IS_SIS740)) {
2905 	   tempah = 0x04;						   /* For all bridges */
2906 	   tempbl = 0xfb;
2907 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2908 	      tempah = 0x00;
2909 	      if(SiS_IsDualEdge(SiS_Pr)) {
2910 	         tempbl = 0xff;
2911 	      }
2912 	   }
2913 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2914 	}
2915 
2916 	/* The following two are responsible for eventually wrong colors
2917 	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2918 	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2919 	 * in a 650 box (Jake). What is the criteria?
2920 	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2921 	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2922 	 * chipset than the bridge revision.
2923 	 */
2924 
2925 	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2926 	   tempah = 0x30;
2927 	   tempbl = 0xc0;
2928 	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2929 	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2930 	      tempah = 0x00;
2931 	      tempbl = 0x00;
2932 	   }
2933 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2934 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2935 	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2936 	   /* Fixes "TV-blue-bug" on 315+301 */
2937 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
2938 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2939 	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2940 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
2941 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2942 	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
2943 	   tempah = 0x30; tempah2 = 0xc0;
2944 	   tempbl = 0xcf; tempbl2 = 0x3f;
2945 	   if(SiS_Pr->SiS_TVBlue == 0) {
2946 	         tempah = tempah2 = 0x00;
2947 	   } else if(SiS_Pr->SiS_TVBlue == -1) {
2948 	      /* Set on 651/M650, clear on 315/650 */
2949 	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2950 	         tempah = tempah2 = 0x00;
2951 	      }
2952 	   }
2953 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2954 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2955 	} else {
2956 	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
2957 	   tempbl = 0xcf; tempbl2 = 0x3f;
2958 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2959 	      tempah = tempah2 = 0x00;
2960 	      if(SiS_IsDualEdge(SiS_Pr)) {
2961 		 tempbl = tempbl2 = 0xff;
2962 	      }
2963 	   }
2964 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2965 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2966 	}
2967 
2968 	if(IS_SIS740) {
2969 	   tempah = 0x80;
2970 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2971 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2972 	} else {
2973 	   tempah = 0x00;
2974 	   tempbl = 0x7f;
2975 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2976 	      tempbl = 0xff;
2977 	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2978 	   }
2979 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2980 	}
2981 
2982 #endif /* CONFIG_FB_SIS_315 */
2983 
2984      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2985 
2986 #ifdef CONFIG_FB_SIS_300
2987 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2988 
2989 	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2990 	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2991 	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2992 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2993 	} else {
2994 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2995 	}
2996 #endif
2997 
2998      }
2999 
3000      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3001 	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
3002 	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3003 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3004         }
3005      }
3006 
3007   } else {  /* LVDS */
3008 
3009 #ifdef CONFIG_FB_SIS_315
3010      if(SiS_Pr->ChipType >= SIS_315H) {
3011 
3012 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3013 
3014 	   tempah = 0x04;
3015 	   tempbl = 0xfb;
3016 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3017 	      tempah = 0x00;
3018 	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3019 	   }
3020 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3021 
3022 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3023 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3024 	   }
3025 
3026 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3027 
3028 	} else if(SiS_Pr->ChipType == SIS_550) {
3029 
3030 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3031 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3032 
3033 	}
3034 
3035      }
3036 #endif
3037 
3038   }
3039 
3040 }
3041 
3042 /*********************************************/
3043 /*            GET RESOLUTION DATA            */
3044 /*********************************************/
3045 
3046 unsigned short
3047 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3048 {
3049    if(ModeNo <= 0x13)
3050       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3051    else
3052       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3053 }
3054 
3055 static void
3056 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3057 {
3058    unsigned short xres, yres, modeflag=0, resindex;
3059 
3060    if(SiS_Pr->UseCustomMode) {
3061       xres = SiS_Pr->CHDisplay;
3062       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3063       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3064       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3065       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3066       return;
3067    }
3068 
3069    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3070 
3071    if(ModeNo <= 0x13) {
3072       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3073       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3074    } else {
3075       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3076       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3077       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3078    }
3079 
3080    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3081 
3082       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3083 	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3084 	    if(yres == 350) yres = 400;
3085 	 }
3086 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3087 	    if(ModeNo == 0x12) yres = 400;
3088 	 }
3089       }
3090 
3091       if(modeflag & HalfDCLK)       xres <<= 1;
3092       if(modeflag & DoubleScanMode) yres <<= 1;
3093 
3094    }
3095 
3096    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3097 
3098       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3099 	 switch(SiS_Pr->SiS_LCDResInfo) {
3100 	   case Panel_1024x768:
3101 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3102 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3103 		    if(yres == 350) yres = 357;
3104 		    if(yres == 400) yres = 420;
3105 		    if(yres == 480) yres = 525;
3106 		 }
3107 	      }
3108 	      break;
3109 	   case Panel_1280x1024:
3110 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3111 		 /* BIOS bug - does this regardless of scaling */
3112 		 if(yres == 400) yres = 405;
3113 	      }
3114 	      if(yres == 350) yres = 360;
3115 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3116 		 if(yres == 360) yres = 375;
3117 	      }
3118 	      break;
3119 	   case Panel_1600x1200:
3120 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3121 		 if(yres == 1024) yres = 1056;
3122 	      }
3123 	      break;
3124 	 }
3125       }
3126 
3127    } else {
3128 
3129       if(SiS_Pr->SiS_VBType & VB_SISVB) {
3130 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3131 	    if(xres == 720) xres = 640;
3132 	 }
3133       } else if(xres == 720) xres = 640;
3134 
3135       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3136 	 yres = 400;
3137 	 if(SiS_Pr->ChipType >= SIS_315H) {
3138 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3139 	 } else {
3140 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3141 	 }
3142 	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3143       }
3144 
3145    }
3146    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3147    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3148 }
3149 
3150 /*********************************************/
3151 /*           GET CRT2 TIMING DATA            */
3152 /*********************************************/
3153 
3154 static void
3155 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3156 	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3157 	       unsigned short *ResIndex)
3158 {
3159   unsigned short tempbx=0, tempal=0, resinfo=0;
3160 
3161   if(ModeNo <= 0x13) {
3162      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3163   } else {
3164      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3165      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3166   }
3167 
3168   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3169 
3170      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
3171 
3172 	tempbx = SiS_Pr->SiS_LCDResInfo;
3173 	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3174 
3175 	/* patch index */
3176 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3177 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
3178 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3179 	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3180 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3181 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3182 	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
3183 	}
3184 
3185 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3186 	   /* Pass 1:1 only (center-screen handled outside) */
3187 	   /* This is never called for the panel's native resolution */
3188 	   /* since Pass1:1 will not be set in this case */
3189 	   tempbx = 100;
3190 	   if(ModeNo >= 0x13) {
3191 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3192 	   }
3193 	}
3194 
3195 #ifdef CONFIG_FB_SIS_315
3196 	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3197 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3198 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3199 		 tempbx = 200;
3200 		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3201 	      }
3202 	   }
3203 	}
3204 #endif
3205 
3206      } else {						  	/* TV */
3207 
3208 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3209 	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3210 	   tempbx = 2;
3211 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3212 	      tempbx = 13;
3213 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3214 	   }
3215 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3216 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
3217 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
3218 	   else						tempbx = 5;
3219 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3220 	} else {
3221 	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
3222 	   else						tempbx = 4;
3223 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3224 	}
3225 
3226      }
3227 
3228      tempal &= 0x3F;
3229 
3230      if(ModeNo > 0x13) {
3231         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3232 	   switch(resinfo) {
3233 	   case SIS_RI_720x480:
3234 	      tempal = 6;
3235 	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
3236 	      break;
3237 	   case SIS_RI_720x576:
3238 	   case SIS_RI_768x576:
3239 	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3240 	      tempal = 6;
3241 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3242 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
3243 	      }
3244 	      break;
3245 	   case SIS_RI_800x480:
3246 	      tempal = 4;
3247 	      break;
3248 	   case SIS_RI_512x384:
3249 	   case SIS_RI_1024x768:
3250 	      tempal = 7;
3251 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3252 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
3253 	      }
3254 	      break;
3255 	   case SIS_RI_1280x720:
3256 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3257 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
3258 	      }
3259 	      break;
3260 	   }
3261 	}
3262      }
3263 
3264      *CRT2Index = tempbx;
3265      *ResIndex = tempal;
3266 
3267   } else {   /* LVDS, 301B-DH (if running on LCD) */
3268 
3269      tempbx = 0;
3270      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3271 
3272 	tempbx = 90;
3273 	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3274 	   tempbx = 92;
3275 	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
3276 	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3277 	   }
3278 	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3279 	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3280 	}
3281 	if(tempbx != 99) {
3282 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3283 	}
3284 
3285      } else {
3286 
3287 	switch(SiS_Pr->SiS_LCDResInfo) {
3288 	case Panel_640x480:   tempbx = 12; break;
3289 	case Panel_320x240_1: tempbx = 10; break;
3290 	case Panel_320x240_2:
3291 	case Panel_320x240_3: tempbx = 14; break;
3292 	case Panel_800x600:   tempbx = 16; break;
3293 	case Panel_1024x600:  tempbx = 18; break;
3294 	case Panel_1152x768:
3295 	case Panel_1024x768:  tempbx = 20; break;
3296 	case Panel_1280x768:  tempbx = 22; break;
3297 	case Panel_1280x1024: tempbx = 24; break;
3298 	case Panel_1400x1050: tempbx = 26; break;
3299 	case Panel_1600x1200: tempbx = 28; break;
3300 #ifdef CONFIG_FB_SIS_300
3301 	case Panel_Barco1366: tempbx = 80; break;
3302 #endif
3303 	}
3304 
3305 	switch(SiS_Pr->SiS_LCDResInfo) {
3306 	case Panel_320x240_1:
3307 	case Panel_320x240_2:
3308 	case Panel_320x240_3:
3309 	case Panel_640x480:
3310 	   break;
3311 	default:
3312 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3313 	}
3314 
3315 	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3316 
3317 #ifdef CONFIG_FB_SIS_300
3318 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3319 	   tempbx = 82;
3320 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3321 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3322 	   tempbx = 84;
3323 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3324 	}
3325 #endif
3326 
3327      }
3328 
3329      (*CRT2Index) = tempbx;
3330      (*ResIndex) = tempal & 0x1F;
3331   }
3332 }
3333 
3334 static void
3335 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3336 		unsigned short RefreshRateTableIndex)
3337 {
3338   unsigned short tempax=0, tempbx=0, index, dotclock;
3339   unsigned short temp1=0, modeflag=0, tempcx=0;
3340 
3341   SiS_Pr->SiS_RVBHCMAX  = 1;
3342   SiS_Pr->SiS_RVBHCFACT = 1;
3343 
3344   if(ModeNo <= 0x13) {
3345 
3346      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3347      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3348 
3349      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3350      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3351      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3352 
3353      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3354 
3355   } else {
3356 
3357      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3358      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3359 
3360      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3361      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3362      tempax &= 0x03FF;
3363      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3364      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3365      tempcx &= 0x0100;
3366      tempcx <<= 2;
3367      tempbx |= tempcx;
3368      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3369 
3370      dotclock = 8;
3371 
3372   }
3373 
3374   if(temp1 & 0x01) tempbx |= 0x0100;
3375   if(temp1 & 0x20) tempbx |= 0x0200;
3376 
3377   tempax += 5;
3378   tempax *= dotclock;
3379   if(modeflag & HalfDCLK) tempax <<= 1;
3380 
3381   tempbx++;
3382 
3383   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3384   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3385 }
3386 
3387 static void
3388 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3389 		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3390 {
3391    unsigned short ResIndex;
3392 
3393    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3394       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3395 	 if(SiS_Pr->UseCustomMode) {
3396 	    ResIndex = SiS_Pr->CHTotal;
3397 	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3398 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3399 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3400 	 } else {
3401 	    if(ModeNo < 0x13) {
3402 	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3403 	    } else {
3404 	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3405 	    }
3406 	    if(ResIndex == 0x09) {
3407 	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3408 	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3409 	    }
3410 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3411 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3412 	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3413 	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3414 	 }
3415       } else {
3416 	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3417 	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3418       }
3419    } else {
3420       /* This handles custom modes and custom panels */
3421       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3422       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3423       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3424       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3425       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3426       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3427    }
3428 }
3429 
3430 static void
3431 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3432                     unsigned short RefreshRateTableIndex)
3433 {
3434    unsigned short CRT2Index, ResIndex, backup;
3435    const struct SiS_LVDSData *LVDSData = NULL;
3436 
3437    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3438 
3439    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3440       SiS_Pr->SiS_RVBHCMAX  = 1;
3441       SiS_Pr->SiS_RVBHCFACT = 1;
3442       SiS_Pr->SiS_NewFlickerMode = 0;
3443       SiS_Pr->SiS_RVBHRS = 50;
3444       SiS_Pr->SiS_RY1COE = 0;
3445       SiS_Pr->SiS_RY2COE = 0;
3446       SiS_Pr->SiS_RY3COE = 0;
3447       SiS_Pr->SiS_RY4COE = 0;
3448       SiS_Pr->SiS_RVBHRS2 = 0;
3449    }
3450 
3451    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3452 
3453 #ifdef CONFIG_FB_SIS_315
3454       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3455       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3456 #endif
3457 
3458    } else {
3459 
3460       /* 301BDH needs LVDS Data */
3461       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3462       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3463 	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3464       }
3465 
3466       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3467                      		            &CRT2Index, &ResIndex);
3468 
3469       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3470 
3471       switch(CRT2Index) {
3472 	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3473 	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3474 	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3475 	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3476 	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3477 	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3478 #ifdef CONFIG_FB_SIS_300
3479 	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3480 	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3481 	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3482 	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3483 	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3484 #endif
3485 	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3486 	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3487 	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3488 	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3489 	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3490 	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3491 	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3492 	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3493 	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
3494       }
3495 
3496       if(LVDSData) {
3497 	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3498 	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3499 	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3500 	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3501       } else {
3502 	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3503       }
3504 
3505       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3506 	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3507 	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3508 	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3509 	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3510 	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3511             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3512 #ifdef CONFIG_FB_SIS_300
3513 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3514 	       if(ResIndex < 0x08) {
3515 		  SiS_Pr->SiS_HDE = 1280;
3516 		  SiS_Pr->SiS_VDE = 1024;
3517 	       }
3518 	    }
3519 #endif
3520          }
3521       }
3522    }
3523 }
3524 
3525 static void
3526 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3527 		unsigned short RefreshRateTableIndex)
3528 {
3529   unsigned char  *ROMAddr = NULL;
3530   unsigned short tempax, tempbx, modeflag, romptr=0;
3531   unsigned short resinfo, CRT2Index, ResIndex;
3532   const struct SiS_LCDData *LCDPtr = NULL;
3533   const struct SiS_TVData  *TVPtr  = NULL;
3534 #ifdef CONFIG_FB_SIS_315
3535   short resinfo661;
3536 #endif
3537 
3538   if(ModeNo <= 0x13) {
3539      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3540      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3541   } else if(SiS_Pr->UseCustomMode) {
3542      modeflag = SiS_Pr->CModeFlag;
3543      resinfo = 0;
3544   } else {
3545      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3546      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3547 #ifdef CONFIG_FB_SIS_315
3548      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3549      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3550 	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3551 	 (resinfo661 >= 0)                     &&
3552 	 (SiS_Pr->SiS_NeedRomModeData) ) {
3553 	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3554 	   if((romptr = (SISGETROMW(21)))) {
3555 	      romptr += (resinfo661 * 10);
3556 	      ROMAddr = SiS_Pr->VirtualRomBase;
3557 	   }
3558 	}
3559      }
3560 #endif
3561   }
3562 
3563   SiS_Pr->SiS_NewFlickerMode = 0;
3564   SiS_Pr->SiS_RVBHRS = 50;
3565   SiS_Pr->SiS_RY1COE = 0;
3566   SiS_Pr->SiS_RY2COE = 0;
3567   SiS_Pr->SiS_RY3COE = 0;
3568   SiS_Pr->SiS_RY4COE = 0;
3569   SiS_Pr->SiS_RVBHRS2 = 0;
3570 
3571   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3572 
3573   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3574 
3575      if(SiS_Pr->UseCustomMode) {
3576 
3577 	SiS_Pr->SiS_RVBHCMAX  = 1;
3578 	SiS_Pr->SiS_RVBHCFACT = 1;
3579 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3580 	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3581 
3582 	tempax = SiS_Pr->CHTotal;
3583 	if(modeflag & HalfDCLK) tempax <<= 1;
3584 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3585 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3586 
3587      } else {
3588 
3589 	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3590 
3591      }
3592 
3593   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3594 
3595      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3596 		    &CRT2Index,&ResIndex);
3597 
3598      switch(CRT2Index) {
3599 	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3600 	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3601 	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3602 	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3603 	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3604 	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3605 	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3606 	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3607 	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3608 	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3609 	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3610 	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3611 	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3612 	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3613      }
3614 
3615      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3616      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3617      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3618      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3619      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3620      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3621      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3622      if(modeflag & HalfDCLK) {
3623 	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3624 	if(SiS_Pr->SiS_RVBHRS2) {
3625 	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3626 	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3627 	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3628 	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3629 	}
3630      } else {
3631 	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3632      }
3633      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3634 
3635      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3636 
3637 	if((resinfo == SIS_RI_960x600)   ||
3638 	   (resinfo == SIS_RI_1024x768)  ||
3639 	   (resinfo == SIS_RI_1280x1024) ||
3640 	   (resinfo == SIS_RI_1280x720)) {
3641 	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3642 	}
3643 
3644 	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3645 
3646 	SiS_Pr->SiS_HT = ExtHiTVHT;
3647 	SiS_Pr->SiS_VT = ExtHiTVVT;
3648 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3649 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3650 	      SiS_Pr->SiS_HT = StHiTVHT;
3651 	      SiS_Pr->SiS_VT = StHiTVVT;
3652 	   }
3653 	}
3654 
3655      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3656 
3657 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3658 	   SiS_Pr->SiS_HT = 1650;
3659 	   SiS_Pr->SiS_VT = 750;
3660 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3661 	   SiS_Pr->SiS_HT = NTSCHT;
3662 	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3663 	   SiS_Pr->SiS_VT = NTSCVT;
3664 	} else {
3665 	   SiS_Pr->SiS_HT = NTSCHT;
3666 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3667 	   SiS_Pr->SiS_VT = NTSCVT;
3668 	}
3669 
3670      } else {
3671 
3672 	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3673 	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3674 	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3675 	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3676 
3677 	if(modeflag & HalfDCLK) {
3678 	   SiS_Pr->SiS_RY1COE = 0x00;
3679 	   SiS_Pr->SiS_RY2COE = 0xf4;
3680 	   SiS_Pr->SiS_RY3COE = 0x10;
3681 	   SiS_Pr->SiS_RY4COE = 0x38;
3682 	}
3683 
3684 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3685 	   SiS_Pr->SiS_HT = NTSCHT;
3686 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3687 	   SiS_Pr->SiS_VT = NTSCVT;
3688 	} else {
3689 	   SiS_Pr->SiS_HT = PALHT;
3690 	   SiS_Pr->SiS_VT = PALVT;
3691 	}
3692 
3693      }
3694 
3695   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3696 
3697      SiS_Pr->SiS_RVBHCMAX  = 1;
3698      SiS_Pr->SiS_RVBHCFACT = 1;
3699 
3700      if(SiS_Pr->UseCustomMode) {
3701 
3702 	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3703 	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3704 
3705 	tempax = SiS_Pr->CHTotal;
3706 	if(modeflag & HalfDCLK) tempax <<= 1;
3707 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3708 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3709 
3710      } else {
3711 
3712 	bool gotit = false;
3713 
3714 	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3715 
3716 	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3717 	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3718 	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3719 	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3720 	   gotit = true;
3721 
3722 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3723 
3724 #ifdef CONFIG_FB_SIS_315
3725 	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3726 	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3727 	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3728 	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3729 	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3730 	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3731 	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3732 	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3733 	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3734 	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3735 	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3736 	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3737 	   }
3738 	   if(SiS_Pr->SiS_VGAHT) gotit = true;
3739 	   else {
3740 	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3741 	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3742 	      SiS_Pr->SiS_RVBHCMAX  = 1;
3743 	      SiS_Pr->SiS_RVBHCFACT = 1;
3744 	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3745 	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3746 	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3747 	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3748 	      SiS_Pr->SiS_RVBHRS2 = 0;
3749 	      gotit = true;
3750 	   }
3751 #endif
3752 
3753 	}
3754 
3755 	if(!gotit) {
3756 
3757 	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3758 			  &CRT2Index,&ResIndex);
3759 
3760 	   switch(CRT2Index) {
3761 	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3762 	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3763 	      case Panel_1280x720      :
3764 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3765 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3766 	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3767 	      case Panel_1280x800      :
3768 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3769 	      case Panel_1280x800_2    :
3770 	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3771 	      case Panel_1280x854      :
3772 	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3773 	      case Panel_1280x960      :
3774 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3775 	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3776 	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3777 	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3778 	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3779 	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3780 	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3781 	      case Panel_1680x1050     :
3782 	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3783 	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3784 #ifdef CONFIG_FB_SIS_315
3785 	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3786 	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3787 #endif
3788 	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3789 	   }
3790 
3791 	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3792 	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3793 	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3794 	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3795 	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3796 	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3797 
3798         }
3799 
3800 	tempax = SiS_Pr->PanelXRes;
3801 	tempbx = SiS_Pr->PanelYRes;
3802 
3803 	switch(SiS_Pr->SiS_LCDResInfo) {
3804 	case Panel_1024x768:
3805 	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3806 	      if(SiS_Pr->ChipType < SIS_315H) {
3807 		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3808 		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3809 	      }
3810 	   } else {
3811 	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3812 	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3813 	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3814 	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3815 	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3816 	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3817 	   }
3818 	   break;
3819 	case Panel_1280x960:
3820 	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3821 	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3822 	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3823 	   break;
3824 	case Panel_1280x1024:
3825 	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3826 	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3827 	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3828 	   break;
3829 	case Panel_1600x1200:
3830 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3831 	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3832 	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3833 	   }
3834 	   break;
3835 	}
3836 
3837 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3838 	   tempax = SiS_Pr->SiS_VGAHDE;
3839 	   tempbx = SiS_Pr->SiS_VGAVDE;
3840 	}
3841 
3842 	SiS_Pr->SiS_HDE = tempax;
3843 	SiS_Pr->SiS_VDE = tempbx;
3844      }
3845   }
3846 }
3847 
3848 static void
3849 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3850                 unsigned short RefreshRateTableIndex)
3851 {
3852 
3853    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3854 
3855       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3856          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3857       } else {
3858 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3859 	    /* Need LVDS Data for LCD on 301B-DH */
3860 	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3861 	 } else {
3862 	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3863 	 }
3864       }
3865 
3866    } else {
3867 
3868       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3869 
3870    }
3871 }
3872 
3873 /*********************************************/
3874 /*         GET LVDS DES (SKEW) DATA          */
3875 /*********************************************/
3876 
3877 static const struct SiS_LVDSDes *
3878 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3879 {
3880    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3881 
3882 #ifdef CONFIG_FB_SIS_300
3883    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3884 
3885       if(SiS_Pr->ChipType < SIS_315H) {
3886 	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3887 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3888 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3889 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3890 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3891 	       }
3892             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3893 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3894 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3895 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3896 	       }
3897 	    }
3898 	 }
3899       }
3900    }
3901 #endif
3902    return PanelDesPtr;
3903 }
3904 
3905 static void
3906 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3907                    unsigned short RefreshRateTableIndex)
3908 {
3909   unsigned short modeflag, ResIndex;
3910   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3911 
3912   SiS_Pr->SiS_LCDHDES = 0;
3913   SiS_Pr->SiS_LCDVDES = 0;
3914 
3915   /* Some special cases */
3916   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3917 
3918      /* Trumpion */
3919      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3920 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3921 	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3922 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3923 	   }
3924 	}
3925 	return;
3926      }
3927 
3928      /* 640x480 on LVDS */
3929      if(SiS_Pr->ChipType < SIS_315H) {
3930 	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3931 	   SiS_Pr->SiS_LCDHDES = 8;
3932 	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3933 	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3934 	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3935 	   return;
3936 	}
3937      }
3938 
3939   } /* LCD */
3940 
3941   if( (SiS_Pr->UseCustomMode) 		         ||
3942       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3943       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3944       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3945       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3946      return;
3947   }
3948 
3949   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3950   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3951 
3952   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3953 
3954 #ifdef CONFIG_FB_SIS_315
3955      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3956 	/* non-pass 1:1 only, see above */
3957 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3958 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3959 	}
3960 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3961 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3962 	}
3963      }
3964      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3965 	switch(SiS_Pr->SiS_CustomT) {
3966 	case CUT_UNIWILL1024:
3967 	case CUT_UNIWILL10242:
3968 	case CUT_CLEVO1400:
3969 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3970 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3971 	   }
3972 	   break;
3973 	}
3974 	switch(SiS_Pr->SiS_LCDResInfo) {
3975 	case Panel_1280x1024:
3976 	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3977 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3978 	   }
3979 	   break;
3980 	case Panel_1280x800:	/* Verified for Averatec 6240 */
3981 	case Panel_1280x800_2:	/* Verified for Asus A4L */
3982 	case Panel_1280x854:    /* Not verified yet FIXME */
3983 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3984 	   break;
3985 	}
3986      }
3987 #endif
3988 
3989   } else {
3990 
3991      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3992 
3993 	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3994 	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3995 	}
3996 
3997      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3998 
3999 	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
4000 	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
4001 
4002      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4003 
4004 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4005 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4006 	}
4007 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4008 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4009 	} else {
4010 	   if(SiS_Pr->ChipType < SIS_315H) {
4011 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4012 	   } else {
4013 	      switch(SiS_Pr->SiS_LCDResInfo) {
4014 	      case Panel_800x600:
4015 	      case Panel_1024x768:
4016 	      case Panel_1280x1024:
4017 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4018 		 break;
4019 	      case Panel_1400x1050:
4020 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4021 		 break;
4022 	      }
4023 	   }
4024 	}
4025 
4026      } else {
4027 
4028         if(SiS_Pr->ChipType < SIS_315H) {
4029 #ifdef CONFIG_FB_SIS_300
4030 	   switch(SiS_Pr->SiS_LCDResInfo) {
4031 	   case Panel_800x600:
4032 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4033 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4034 	      } else {
4035 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4036 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4037 		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4038 		 else                          SiS_Pr->SiS_LCDVDES -= 4;
4039 	      }
4040 	      break;
4041 	   case Panel_1024x768:
4042 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4043 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4044 	      } else {
4045 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4046 		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4047 		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4048 	      }
4049 	      break;
4050 	   case Panel_1024x600:
4051 	   default:
4052 	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4053 		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4054 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4055 	      } else {
4056 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4057 	      }
4058 	      break;
4059 	   }
4060 
4061 	   switch(SiS_Pr->SiS_LCDTypeInfo) {
4062 	   case 1:
4063 	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4064 	      break;
4065 	   case 3: /* 640x480 only? */
4066 	      SiS_Pr->SiS_LCDHDES = 8;
4067 	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4068 	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4069 	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4070 	      break;
4071 	   }
4072 #endif
4073         } else {
4074 #ifdef CONFIG_FB_SIS_315
4075 	   switch(SiS_Pr->SiS_LCDResInfo) {
4076 	   case Panel_1024x768:
4077 	   case Panel_1280x1024:
4078 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4079 	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4080 	      }
4081 	      break;
4082 	   case Panel_320x240_1:
4083 	   case Panel_320x240_2:
4084 	   case Panel_320x240_3:
4085 	      SiS_Pr->SiS_LCDVDES = 524;
4086 	      break;
4087 	   }
4088 #endif
4089 	}
4090      }
4091 
4092      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4093 	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4094 	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4095 	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4096 	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4097 	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4098 	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4099 	         if(SiS_Pr->ChipType < SIS_315H) {
4100 	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4101 	         } else {
4102 #ifdef CONFIG_FB_SIS_315
4103 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
4104 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4105 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4106 		    if(!(modeflag & HalfDCLK)) {
4107 		       SiS_Pr->SiS_LCDHDES = 320;
4108 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4109 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4110         	    }
4111 #endif
4112 		 }
4113 	      }
4114 	   }
4115 	}
4116      }
4117   }
4118 }
4119 
4120 /*********************************************/
4121 /*           DISABLE VIDEO BRIDGE            */
4122 /*********************************************/
4123 
4124 #ifdef CONFIG_FB_SIS_315
4125 static int
4126 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4127 {
4128    int ret = 0;
4129 #ifdef SET_PWD
4130    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4131    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4132    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4133    unsigned short temp;
4134 
4135    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4136        (romptr)				&&
4137        (SiS_Pr->SiS_PWDOffset) ) {
4138       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4139       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4140       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4141       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4142       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4143       temp = 0x00;
4144       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4145          temp = 0x80;
4146 	 ret = 1;
4147       }
4148       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4149    }
4150 #endif
4151    return ret;
4152 }
4153 #endif
4154 
4155 /* NEVER use any variables (VBInfo), this will be called
4156  * from outside the context of modeswitch!
4157  * MUST call getVBType before calling this
4158  */
4159 void
4160 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4161 {
4162 #ifdef CONFIG_FB_SIS_315
4163   unsigned short tempah, pushax=0, modenum;
4164 #endif
4165   unsigned short temp=0;
4166 
4167   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4168 
4169      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
4170 
4171 	if(SiS_Pr->ChipType < SIS_315H) {
4172 
4173 #ifdef CONFIG_FB_SIS_300	   /* 300 series */
4174 
4175 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4176 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4177 		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4178 	      } else {
4179 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4180 	      }
4181 	      SiS_PanelDelay(SiS_Pr, 3);
4182 	   }
4183 	   if(SiS_Is301B(SiS_Pr)) {
4184 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4185 	      SiS_ShortDelay(SiS_Pr,1);
4186 	   }
4187 	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4188 	   SiS_DisplayOff(SiS_Pr);
4189 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4190 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4191 	   SiS_UnLockCRT2(SiS_Pr);
4192 	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4193 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4194 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4195 	   }
4196 	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4197 	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4198 	      SiS_PanelDelay(SiS_Pr, 2);
4199 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4200 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4201 	      } else {
4202 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4203 	      }
4204 	   }
4205 
4206 #endif  /* CONFIG_FB_SIS_300 */
4207 
4208         } else {
4209 
4210 #ifdef CONFIG_FB_SIS_315	   /* 315 series */
4211 
4212 	   int didpwd = 0;
4213 	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4214 	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4215 
4216 	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4217 
4218 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4219 
4220 #ifdef SET_EMI
4221 	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4222 		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4223 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4224 		 }
4225 	      }
4226 #endif
4227 
4228 	      didpwd = SiS_HandlePWD(SiS_Pr);
4229 
4230 	      if( (modenum <= 0x13)           ||
4231 		  (SiS_IsVAMode(SiS_Pr))      ||
4232 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4233 		 if(!didpwd) {
4234 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4235 		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4236 		 } else {
4237 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4238 		 }
4239 	      }
4240 
4241 	      if(!custom1) {
4242 		 SiS_DDC2Delay(SiS_Pr,0xff00);
4243 		 SiS_DDC2Delay(SiS_Pr,0xe000);
4244 		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4245 		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4246 		 if(IS_SIS740) {
4247 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4248 		 }
4249 	         SiS_PanelDelay(SiS_Pr, 3);
4250 	      }
4251 
4252 	   }
4253 
4254 	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4255 	      /* if(SiS_Pr->ChipType < SIS_340) {*/
4256 		 tempah = 0xef;
4257 		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4258 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4259 	      /*}*/
4260 	   }
4261 
4262 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4263 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4264 	   }
4265 
4266 	   tempah = 0x3f;
4267 	   if(SiS_IsDualEdge(SiS_Pr)) {
4268 	      tempah = 0x7f;
4269 	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4270 	   }
4271 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4272 
4273 	   if((SiS_IsVAMode(SiS_Pr)) ||
4274 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4275 
4276 	      SiS_DisplayOff(SiS_Pr);
4277 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4278 		 SiS_PanelDelay(SiS_Pr, 2);
4279 	      }
4280 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4281 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4282 
4283 	   }
4284 
4285 	   if((!(SiS_IsVAMode(SiS_Pr))) ||
4286 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4287 
4288 	      if(!(SiS_IsDualEdge(SiS_Pr))) {
4289 		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4290 		 SiS_DisplayOff(SiS_Pr);
4291 	      }
4292 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4293 
4294 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4295 		 SiS_PanelDelay(SiS_Pr, 2);
4296 	      }
4297 
4298 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4299 	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4300 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4301 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4302 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4303 
4304 	   }
4305 
4306 	   if(SiS_IsNotM650orLater(SiS_Pr)) {
4307 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4308 	   }
4309 
4310 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4311 
4312 	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4313 		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4314 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4315 
4316 		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4317 		 if(!didpwd) {
4318 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4319 		 }
4320 		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4321 	      }
4322 
4323 	      if(!custom1) {
4324 		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4325 		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4326 		    if(SiS_IsVAorLCD(SiS_Pr)) {
4327 		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4328 		    }
4329 		 }
4330 	      }
4331 
4332 	   }
4333 
4334 #endif /* CONFIG_FB_SIS_315 */
4335 
4336 	}
4337 
4338      } else {     /* ============ For 301 ================ */
4339 
4340         if(SiS_Pr->ChipType < SIS_315H) {
4341 #ifdef CONFIG_FB_SIS_300
4342 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4343 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4344 	      SiS_PanelDelay(SiS_Pr, 3);
4345 	   }
4346 #endif
4347 	}
4348 
4349 	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4350 	SiS_DisplayOff(SiS_Pr);
4351 
4352 	if(SiS_Pr->ChipType >= SIS_315H) {
4353 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4354 	}
4355 
4356 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4357 
4358 	if(SiS_Pr->ChipType >= SIS_315H) {
4359 	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4360 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4361 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4362 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4363 	} else {
4364 #ifdef CONFIG_FB_SIS_300
4365 	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4366 	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4367 		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4368 		SiS_PanelDelay(SiS_Pr, 2);
4369 		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4370 	    }
4371 #endif
4372 	}
4373 
4374       }
4375 
4376   } else {     /* ============ For LVDS =============*/
4377 
4378     if(SiS_Pr->ChipType < SIS_315H) {
4379 
4380 #ifdef CONFIG_FB_SIS_300	/* 300 series */
4381 
4382 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4383 	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4384 	}
4385 
4386 	if(SiS_Pr->ChipType == SIS_730) {
4387 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4388 	      SiS_WaitVBRetrace(SiS_Pr);
4389 	   }
4390 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4391 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4392 	      SiS_PanelDelay(SiS_Pr, 3);
4393 	   }
4394 	} else {
4395 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4396 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4397 		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4398 		    SiS_WaitVBRetrace(SiS_Pr);
4399 		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4400 		       SiS_DisplayOff(SiS_Pr);
4401 		    }
4402 		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4403 		    SiS_PanelDelay(SiS_Pr, 3);
4404 		 }
4405 	      }
4406 	   }
4407 	}
4408 
4409 	SiS_DisplayOff(SiS_Pr);
4410 
4411 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4412 
4413 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4414 	SiS_UnLockCRT2(SiS_Pr);
4415 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4416 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4417 
4418 	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4419 	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4420 	   SiS_PanelDelay(SiS_Pr, 2);
4421 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4422 	}
4423 
4424 #endif  /* CONFIG_FB_SIS_300 */
4425 
4426     } else {
4427 
4428 #ifdef CONFIG_FB_SIS_315	/* 315 series */
4429 
4430 	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4431 	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4432 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4433 	   /* } */
4434 	}
4435 
4436 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4437 
4438 	   if(SiS_Pr->ChipType == SIS_740) {
4439 	      temp = SiS_GetCH701x(SiS_Pr,0x61);
4440 	      if(temp < 1) {
4441 		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4442 		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4443 	      }
4444 
4445 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4446 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4447 		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4448 	      }
4449 	   }
4450 
4451 	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4452 	       (SiS_IsVAMode(SiS_Pr)) ) {
4453 	      SiS_Chrontel701xBLOff(SiS_Pr);
4454 	      SiS_Chrontel701xOff(SiS_Pr);
4455 	   }
4456 
4457 	   if(SiS_Pr->ChipType != SIS_740) {
4458 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4459 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4460 		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4461 	      }
4462 	   }
4463 
4464 	}
4465 
4466 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4467 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4468 	   SiS_PanelDelay(SiS_Pr, 3);
4469 	}
4470 
4471 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4472 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4473 	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4474 	   SiS_DisplayOff(SiS_Pr);
4475 	}
4476 
4477 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4478 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4479 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4480 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4481 	}
4482 
4483 	if(SiS_Pr->ChipType == SIS_740) {
4484 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4485 	}
4486 
4487 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4488 
4489 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4490 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4491 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4492 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4493 	}
4494 
4495 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4496 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4497 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4498 	      if(SiS_Pr->ChipType == SIS_550) {
4499 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4500 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4501 	      }
4502 	   }
4503 	} else {
4504 	   if(SiS_Pr->ChipType == SIS_740) {
4505 	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4506 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4507 	      }
4508 	   } else if(SiS_IsVAMode(SiS_Pr)) {
4509 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4510 	   }
4511 	}
4512 
4513 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4514 	   if(SiS_IsDualEdge(SiS_Pr)) {
4515 	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4516 	   } else {
4517 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4518 	   }
4519 	}
4520 
4521 	SiS_UnLockCRT2(SiS_Pr);
4522 
4523 	if(SiS_Pr->ChipType == SIS_550) {
4524 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4525 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4526 	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4527 		   (!(SiS_IsDualEdge(SiS_Pr))) ||
4528 		   (!(SiS_IsVAMode(SiS_Pr))) ) {
4529 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4530 	}
4531 
4532         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4533 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4534 	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4535 		 SiS_PanelDelay(SiS_Pr, 2);
4536 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4537 	      }
4538 	   }
4539         }
4540 
4541 #endif  /* CONFIG_FB_SIS_315 */
4542 
4543     }  /* 315 series */
4544 
4545   }  /* LVDS */
4546 
4547 }
4548 
4549 /*********************************************/
4550 /*            ENABLE VIDEO BRIDGE            */
4551 /*********************************************/
4552 
4553 /* NEVER use any variables (VBInfo), this will be called
4554  * from outside the context of a mode switch!
4555  * MUST call getVBType before calling this
4556  */
4557 static
4558 void
4559 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4560 {
4561   unsigned short temp=0, tempah;
4562 #ifdef CONFIG_FB_SIS_315
4563   unsigned short temp1, pushax=0;
4564   bool delaylong = false;
4565 #endif
4566 
4567   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4568 
4569     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
4570 
4571       if(SiS_Pr->ChipType < SIS_315H) {
4572 
4573 #ifdef CONFIG_FB_SIS_300     /* 300 series */
4574 
4575 	 if(SiS_CRT2IsLCD(SiS_Pr)) {
4576 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4577 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4578 	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4579 	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4580 	    }
4581 	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4582 	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4583 		  SiS_PanelDelay(SiS_Pr, 0);
4584 	       }
4585 	    }
4586 	 }
4587 
4588 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4589 	    (SiS_CRT2IsLCD(SiS_Pr))) {
4590 
4591 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4592 	    SiS_DisplayOn(SiS_Pr);
4593 	    SiS_UnLockCRT2(SiS_Pr);
4594 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4595 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4596 	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4597 	    } else {
4598 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4599 	    }
4600 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4601 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4602 		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4603 		     SiS_PanelDelay(SiS_Pr, 1);
4604 		  }
4605 		  SiS_WaitVBRetrace(SiS_Pr);
4606 		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4607 	       }
4608 	    }
4609 
4610 	 } else {
4611 
4612 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4613 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4614 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4615 	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4616 	    }
4617 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4618 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4619 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4620 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4621 	    SiS_DisplayOn(SiS_Pr);
4622 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4623 	       if(SiS_CRT2IsLCD(SiS_Pr)) {
4624 		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4625 		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4626 		        SiS_PanelDelay(SiS_Pr, 1);
4627 		     }
4628 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4629 		  }
4630 	       }
4631 	    }
4632 
4633 	 }
4634 
4635 
4636 #endif /* CONFIG_FB_SIS_300 */
4637 
4638       } else {
4639 
4640 #ifdef CONFIG_FB_SIS_315    /* 315 series */
4641 
4642 #ifdef SET_EMI
4643 	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4644 	 int didpwd = 0;
4645 	 /* unsigned short  emidelay=0; */
4646 #endif
4647 
4648 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4649 	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4650 #ifdef SET_EMI
4651 	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4652 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4653 	    }
4654 #endif
4655 	 }
4656 
4657 	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4658 	    /*if(SiS_Pr->ChipType < SIS_340) { */
4659 	       tempah = 0x10;
4660 	       if(SiS_LCDAEnabled(SiS_Pr)) {
4661 		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4662 		  else			    tempah = 0x08;
4663 	       }
4664 	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4665 	    /*}*/
4666 	 }
4667 
4668 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4669 
4670 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4671 	    SiS_DisplayOff(SiS_Pr);
4672 	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4673 	    if(IS_SIS740) {
4674 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4675 	    }
4676 
4677 	    didpwd = SiS_HandlePWD(SiS_Pr);
4678 
4679 	    if(SiS_IsVAorLCD(SiS_Pr)) {
4680 	       if(!didpwd) {
4681 		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4682 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4683 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4684 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4685 		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4686 		        SiS_GenericDelay(SiS_Pr, 17664);
4687 		     }
4688 		  }
4689 	       } else {
4690 		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4691 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4692 		     SiS_GenericDelay(SiS_Pr, 17664);
4693 		  }
4694 	       }
4695 	    }
4696 
4697 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4698 	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4699 	       delaylong = true;
4700 	    }
4701 
4702 	 }
4703 
4704 	 if(!(SiS_IsVAMode(SiS_Pr))) {
4705 
4706 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4707 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4708 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4709 	       if(!(tempah & SetCRT2ToRAMDAC)) {
4710 		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4711 	       }
4712 	    }
4713 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4714 
4715 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4716 
4717 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4718 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4719 
4720 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4721 	       SiS_PanelDelay(SiS_Pr, 2);
4722 	    }
4723 
4724 	 } else {
4725 
4726 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4727 
4728 	 }
4729 
4730 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4731 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4732 
4733 	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4734 	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
4735 	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
4736 	       /* Enable "LVDS PLL power on" (even on 301C) */
4737 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4738 	       /* Enable "LVDS Driver Power on" (even on 301C) */
4739 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4740 	    }
4741 	 }
4742 
4743 	 tempah = 0xc0;
4744 	 if(SiS_IsDualEdge(SiS_Pr)) {
4745 	    tempah = 0x80;
4746 	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4747 	 }
4748 	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4749 
4750 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4751 
4752 	    SiS_PanelDelay(SiS_Pr, 2);
4753 
4754 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4755 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4756 
4757 	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4758 #ifdef SET_EMI
4759 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4760 		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4761 		  SiS_GenericDelay(SiS_Pr, 2048);
4762 	       }
4763 #endif
4764 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4765 
4766 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4767 #ifdef SET_EMI
4768 		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4769 
4770 		  if(SiS_Pr->SiS_ROMNew) {
4771 		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4772 		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4773 		     if(romptr) {
4774 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4775 			SiS_Pr->EMI_30 = 0;
4776 			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4777 			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4778 			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4779 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4780 			/* emidelay = SISGETROMW((romptr + 0x22)); */
4781 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4782 		     }
4783 		  }
4784 
4785 		  /*                                              (P4_30|0x40)  */
4786 		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4787 		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4788 		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4789 		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4790 		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4791 		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4792 		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4793 		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4794 		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4795 
4796 		  if(SiS_Pr->HaveEMI) {
4797 		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4798 		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4799 		  } else {
4800 		     r30 = 0;
4801 		  }
4802 
4803 		  /* EMI_30 is read at driver start; however, the BIOS sets this
4804 		   * (if it is used) only if the LCD is in use. In case we caught
4805 		   * the machine while on TV output, this bit is not set and we
4806 		   * don't know if it should be set - hence our detection is wrong.
4807 		   * Work-around this here:
4808 		   */
4809 
4810 		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4811 		     switch((cr36 & 0x0f)) {
4812 		     case 2:
4813 			r30 |= 0x40;
4814 			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4815 			if(!SiS_Pr->HaveEMI) {
4816 			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4817 			   if((cr36 & 0xf0) == 0x30) {
4818 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4819 			   }
4820 			}
4821 			break;
4822 		     case 3:  /* 1280x1024 */
4823 			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4824 			if(!SiS_Pr->HaveEMI) {
4825 			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4826 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4827 			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4828 			   }
4829 			}
4830 			break;
4831 		     case 9:  /* 1400x1050 */
4832 			r30 |= 0x40;
4833 			if(!SiS_Pr->HaveEMI) {
4834 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4835 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4836 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4837 			   }
4838 			}
4839 			break;
4840 		     case 11: /* 1600x1200 - unknown */
4841 			r30 |= 0x40;
4842 			if(!SiS_Pr->HaveEMI) {
4843 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4844 			}
4845 		     }
4846                   }
4847 
4848 		  /* BIOS values don't work so well sometimes */
4849 		  if(!SiS_Pr->OverruleEMI) {
4850 #ifdef COMPAL_HACK
4851 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4852 			if((cr36 & 0x0f) == 0x09) {
4853 			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4854 			}
4855  		     }
4856 #endif
4857 #ifdef COMPAQ_HACK
4858 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4859 			if((cr36 & 0x0f) == 0x03) {
4860 			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4861 			}
4862 		     }
4863 #endif
4864 #ifdef ASUS_HACK
4865 		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4866 			if((cr36 & 0x0f) == 0x02) {
4867 			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4868 			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4869 			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4870 			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4871 			}
4872 		     }
4873 #endif
4874 		  }
4875 
4876 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4877 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4878 		     SiS_GenericDelay(SiS_Pr, 2048);
4879 		  }
4880 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4881 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4882 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4883 #endif	/* SET_EMI */
4884 
4885 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4886 
4887 #ifdef SET_EMI
4888 		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4889 		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
4890 		     if(r30 & 0x40) {
4891 			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4892 			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4893 			if(delaylong) {
4894 			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4895 			   delaylong = false;
4896 			}
4897 			SiS_WaitVBRetrace(SiS_Pr);
4898 			SiS_WaitVBRetrace(SiS_Pr);
4899 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4900 			   SiS_GenericDelay(SiS_Pr, 1280);
4901 			}
4902 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4903 			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4904 		     }
4905 		  }
4906 #endif
4907 	       }
4908 	    }
4909 
4910 	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4911 	       if(SiS_IsVAorLCD(SiS_Pr)) {
4912 		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4913 		  if(delaylong) {
4914 		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4915 		  }
4916 		  SiS_WaitVBRetrace(SiS_Pr);
4917 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4918 		     SiS_GenericDelay(SiS_Pr, 2048);
4919 		     SiS_WaitVBRetrace(SiS_Pr);
4920 		  }
4921 		  if(!didpwd) {
4922 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4923 		  } else {
4924 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4925 		  }
4926 	       }
4927 	    }
4928 
4929 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4930 	    SiS_DisplayOn(SiS_Pr);
4931 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4932 
4933 	 }
4934 
4935 	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4936 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4937 	 }
4938 
4939 #endif /* CONFIG_FB_SIS_315 */
4940 
4941       }
4942 
4943     } else {	/* ============  For 301 ================ */
4944 
4945        if(SiS_Pr->ChipType < SIS_315H) {
4946 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4947 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4948 	     SiS_PanelDelay(SiS_Pr, 0);
4949 	  }
4950        }
4951 
4952        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4953        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4954 	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4955 	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4956        }
4957        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4958 
4959        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4960 
4961        if(SiS_Pr->ChipType >= SIS_315H) {
4962 	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4963 	  if(!(temp & 0x80)) {
4964 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4965 	  }
4966        }
4967 
4968        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4969 
4970        SiS_VBLongWait(SiS_Pr);
4971        SiS_DisplayOn(SiS_Pr);
4972        if(SiS_Pr->ChipType >= SIS_315H) {
4973 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4974        }
4975        SiS_VBLongWait(SiS_Pr);
4976 
4977        if(SiS_Pr->ChipType < SIS_315H) {
4978 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4979 	     SiS_PanelDelay(SiS_Pr, 1);
4980 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4981 	  }
4982        }
4983 
4984     }
4985 
4986   } else {   /* =================== For LVDS ================== */
4987 
4988     if(SiS_Pr->ChipType < SIS_315H) {
4989 
4990 #ifdef CONFIG_FB_SIS_300    /* 300 series */
4991 
4992        if(SiS_CRT2IsLCD(SiS_Pr)) {
4993 	  if(SiS_Pr->ChipType == SIS_730) {
4994 	     SiS_PanelDelay(SiS_Pr, 1);
4995 	     SiS_PanelDelay(SiS_Pr, 1);
4996 	     SiS_PanelDelay(SiS_Pr, 1);
4997 	  }
4998 	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4999 	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
5000 	     SiS_PanelDelay(SiS_Pr, 0);
5001 	  }
5002        }
5003 
5004        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5005        SiS_DisplayOn(SiS_Pr);
5006        SiS_UnLockCRT2(SiS_Pr);
5007        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5008        if(SiS_BridgeInSlavemode(SiS_Pr)) {
5009 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5010        } else {
5011 	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5012        }
5013 
5014        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5015 	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5016 	     SiS_WaitVBRetrace(SiS_Pr);
5017 	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5018 	  }
5019        }
5020 
5021        if(SiS_CRT2IsLCD(SiS_Pr)) {
5022 	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5023 	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5024 		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5025 		   SiS_PanelDelay(SiS_Pr, 1);
5026 		   SiS_PanelDelay(SiS_Pr, 1);
5027 		}
5028 		SiS_WaitVBRetrace(SiS_Pr);
5029 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5030 	     }
5031 	  }
5032        }
5033 
5034 #endif  /* CONFIG_FB_SIS_300 */
5035 
5036     } else {
5037 
5038 #ifdef CONFIG_FB_SIS_315    /* 315 series */
5039 
5040        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5041 	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
5042 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5043 	  /*}*/
5044        }
5045 
5046        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5047 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5048 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5049 	     SiS_PanelDelay(SiS_Pr, 0);
5050 	  }
5051        }
5052 
5053        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5054        SiS_UnLockCRT2(SiS_Pr);
5055 
5056        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5057 
5058        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5059 	  temp = SiS_GetCH701x(SiS_Pr,0x66);
5060 	  temp &= 0x20;
5061 	  SiS_Chrontel701xBLOff(SiS_Pr);
5062        }
5063 
5064        if(SiS_Pr->ChipType != SIS_550) {
5065 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5066        }
5067 
5068        if(SiS_Pr->ChipType == SIS_740) {
5069 	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5070 	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5071 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5072 	     }
5073 	  }
5074        }
5075 
5076        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5077        if(!(temp1 & 0x80)) {
5078 	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5079        }
5080 
5081        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5082 	  if(temp) {
5083 	     SiS_Chrontel701xBLOn(SiS_Pr);
5084 	  }
5085        }
5086 
5087        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5088 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5089 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5090 	     if(SiS_Pr->ChipType == SIS_550) {
5091 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5092 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5093 	     }
5094 	  }
5095        } else if(SiS_IsVAMode(SiS_Pr)) {
5096 	  if(SiS_Pr->ChipType != SIS_740) {
5097 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5098 	  }
5099        }
5100 
5101        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5102 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5103        }
5104 
5105        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5106 	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5107 	     SiS_Chrontel701xOn(SiS_Pr);
5108 	  }
5109 	  if( (SiS_IsVAMode(SiS_Pr)) ||
5110 	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5111 	     SiS_ChrontelDoSomething1(SiS_Pr);
5112 	  }
5113        }
5114 
5115        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5116 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5117 	     if( (SiS_IsVAMode(SiS_Pr)) ||
5118 		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5119 		SiS_Chrontel701xBLOn(SiS_Pr);
5120 		SiS_ChrontelInitTVVSync(SiS_Pr);
5121 	     }
5122 	  }
5123        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5124 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5125 	     if(SiS_CRT2IsLCD(SiS_Pr)) {
5126 		SiS_PanelDelay(SiS_Pr, 1);
5127 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5128 	     }
5129 	  }
5130        }
5131 
5132 #endif  /* CONFIG_FB_SIS_315 */
5133 
5134     } /* 310 series */
5135 
5136   }  /* LVDS */
5137 
5138 }
5139 
5140 /*********************************************/
5141 /*         SET PART 1 REGISTER GROUP         */
5142 /*********************************************/
5143 
5144 /* Set CRT2 OFFSET / PITCH */
5145 static void
5146 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5147 		unsigned short RRTI)
5148 {
5149    unsigned short offset;
5150    unsigned char  temp;
5151 
5152    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5153 
5154    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5155 
5156    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5157    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5158 
5159    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5160    if(offset & 0x07) temp++;
5161    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5162 }
5163 
5164 /* Set CRT2 sync and PanelLink mode */
5165 static void
5166 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5167 {
5168    unsigned short tempah=0, tempbl, infoflag;
5169 
5170    tempbl = 0xC0;
5171 
5172    if(SiS_Pr->UseCustomMode) {
5173       infoflag = SiS_Pr->CInfoFlag;
5174    } else {
5175       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5176    }
5177 
5178    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
5179 
5180       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5181 	 tempah = 0;
5182       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5183 	 tempah = SiS_Pr->SiS_LCDInfo;
5184       } else tempah = infoflag >> 8;
5185       tempah &= 0xC0;
5186       tempah |= 0x20;
5187       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5188       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5189 	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5190 	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5191 	    tempah |= 0xf0;
5192 	 }
5193 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5194 	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
5195 	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5196 	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5197 	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5198 	    tempah |= 0x30;
5199 	 }
5200 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5201 	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5202 	    tempah &= ~0xc0;
5203 	 }
5204       }
5205       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5206 	 if(SiS_Pr->ChipType >= SIS_315H) {
5207 	    tempah >>= 3;
5208 	    tempah &= 0x18;
5209 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5210 	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5211 	 } else {
5212 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5213 	 }
5214       } else {
5215 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5216       }
5217 
5218    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5219 
5220       if(SiS_Pr->ChipType < SIS_315H) {
5221 
5222 #ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
5223 
5224 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
5225 
5226 	    tempah = infoflag >> 8;
5227 	    tempbl = 0;
5228 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5229 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5230 		  tempah = SiS_Pr->SiS_LCDInfo;
5231 		  tempbl = (tempah >> 6) & 0x03;
5232 	       }
5233 	    }
5234 	    tempah &= 0xC0;
5235 	    tempah |= 0x20;
5236 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5237 	    tempah |= 0xc0;
5238 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5239 	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5240 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5241 	    }
5242 
5243 	 } else {							/* 630 - 301 */
5244 
5245 	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5246 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5247 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5248 
5249 	 }
5250 
5251 #endif /* CONFIG_FB_SIS_300 */
5252 
5253       } else {
5254 
5255 #ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
5256 
5257 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
5258 
5259 	    tempbl = 0;
5260 	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5261 	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5262 	       tempah = infoflag >> 8;
5263 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5264 		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5265 	       }
5266 	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5267 		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5268 	       tempah = infoflag >> 8;
5269 	       tempbl = 0x03;
5270 	    } else {
5271 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5272 	       tempbl = (tempah >> 6) & 0x03;
5273 	       tempbl |= 0x08;
5274 	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5275 	    }
5276 	    tempah &= 0xC0;
5277 	    tempah |= 0x20;
5278 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5279 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5280 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5281 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5282 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5283 		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5284 	       }
5285 	    }
5286 
5287 	 } else {							/* 315 - TMDS */
5288 
5289 	    tempah = tempbl = infoflag >> 8;
5290 	    if(!SiS_Pr->UseCustomMode) {
5291 	       tempbl = 0;
5292 	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5293 		  if(ModeNo <= 0x13) {
5294 		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5295 		  }
5296 	       }
5297 	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5298 		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5299 		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5300 		       tempah = SiS_Pr->SiS_LCDInfo;
5301 		       tempbl = (tempah >> 6) & 0x03;
5302 		    }
5303 		  }
5304 	       }
5305 	    }
5306 	    tempah &= 0xC0;
5307 	    tempah |= 0x20;
5308 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5309 	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5310 	       /* Imitate BIOS bug */
5311 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5312 	    }
5313 	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5314 	       tempah >>= 3;
5315 	       tempah &= 0x18;
5316 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5317 	    } else {
5318 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5319 	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5320 		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5321 		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5322 		  }
5323 	       }
5324 	    }
5325 
5326          }
5327 #endif  /* CONFIG_FB_SIS_315 */
5328       }
5329    }
5330 }
5331 
5332 /* Set CRT2 FIFO on 300/540/630/730 */
5333 #ifdef CONFIG_FB_SIS_300
5334 static void
5335 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5336 {
5337   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5338   unsigned short temp, index, modeidindex, refreshratetableindex;
5339   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5340   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5341   unsigned int   data, pci50, pciA0;
5342   static const unsigned char colortharray[] = {
5343   	1, 1, 2, 2, 3, 4
5344   };
5345 
5346   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5347 
5348   if(!SiS_Pr->CRT1UsesCustomMode) {
5349 
5350      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5351      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5352      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5353      SiS_Pr->SiS_SelectCRT2Rate = 0;
5354      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5355 
5356      if(CRT1ModeNo >= 0x13) {
5357         /* Get VCLK */
5358 	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5359 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5360 
5361 	/* Get colordepth */
5362 	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5363 	if(!colorth) colorth++;
5364      }
5365 
5366   } else {
5367 
5368      CRT1ModeNo = 0xfe;
5369 
5370      /* Get VCLK */
5371      VCLK = SiS_Pr->CSRClock_CRT1;
5372 
5373      /* Get color depth */
5374      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5375 
5376   }
5377 
5378   if(CRT1ModeNo >= 0x13) {
5379      /* Get MCLK */
5380      if(SiS_Pr->ChipType == SIS_300) {
5381         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5382      } else {
5383         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5384      }
5385      index &= 0x07;
5386      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5387 
5388      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5389      if(!temp) temp++;
5390      temp <<= 2;
5391 
5392      data2 = temp - ((colorth * VCLK) / MCLK);
5393 
5394      temp = (28 * 16) % data2;
5395      data2 = (28 * 16) / data2;
5396      if(temp) data2++;
5397 
5398      if(SiS_Pr->ChipType == SIS_300) {
5399 
5400 	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5401 	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5402 
5403      } else {
5404 
5405 	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5406 	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5407 
5408         if(SiS_Pr->ChipType == SIS_730) {
5409 
5410 	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5411 	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
5412 
5413 	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5414 	   index = 0;  /* -- do it like the BIOS anyway... */
5415 
5416 	} else {
5417 
5418 	   pci50 >>= 24;
5419 	   pciA0 >>= 24;
5420 
5421 	   index = (pci50 >> 1) & 0x07;
5422 
5423 	   if(pci50 & 0x01)    index += 6;
5424 	   if(!(pciA0 & 0x01)) index += 24;
5425 
5426 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5427 
5428 	}
5429 
5430 	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5431 	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5432 
5433      }
5434 
5435      data += data2;						/* CRT1 Request Period */
5436 
5437      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5438      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5439 
5440      if(!SiS_Pr->UseCustomMode) {
5441 
5442 	CRT2ModeNo = ModeNo;
5443 	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5444 
5445 	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5446 
5447 	/* Get VCLK  */
5448 	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5449 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5450 
5451 	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5452 	   if(SiS_Pr->SiS_UseROM) {
5453 	      if(ROMAddr[0x220] & 0x01) {
5454 		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5455 	      }
5456            }
5457         }
5458 
5459      } else {
5460 
5461 	/* Get VCLK */
5462 	CRT2ModeNo = 0xfe;
5463 	VCLK = SiS_Pr->CSRClock;
5464 
5465      }
5466 
5467      /* Get colordepth */
5468      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5469      if(!colorth) colorth++;
5470 
5471      data = data * VCLK * colorth;
5472      temp = data % (MCLK << 4);
5473      data = data / (MCLK << 4);
5474      if(temp) data++;
5475 
5476      if(data < 6) data = 6;
5477      else if(data > 0x14) data = 0x14;
5478 
5479      if(SiS_Pr->ChipType == SIS_300) {
5480         temp = 0x16;
5481 	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5482 	   temp = 0x13;
5483      } else {
5484         temp = 0x16;
5485 	if(( (SiS_Pr->ChipType == SIS_630) ||
5486 	     (SiS_Pr->ChipType == SIS_730) )  &&
5487 	   (SiS_Pr->ChipRevision >= 0x30))
5488 	   temp = 0x1b;
5489      }
5490      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5491 
5492      if((SiS_Pr->ChipType == SIS_630) &&
5493 	(SiS_Pr->ChipRevision >= 0x30)) {
5494 	if(data > 0x13) data = 0x13;
5495      }
5496      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5497 
5498   } else {  /* If mode <= 0x13, we just restore everything */
5499 
5500      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5501      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5502 
5503   }
5504 }
5505 #endif
5506 
5507 /* Set CRT2 FIFO on 315/330 series */
5508 #ifdef CONFIG_FB_SIS_315
5509 static void
5510 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5511 {
5512   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5513   if( (SiS_Pr->ChipType == SIS_760)      &&
5514       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5515       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5516       (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5517       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5518      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5519      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5520      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5521      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5522      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5523      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5524   } else {
5525      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5526   }
5527 
5528 }
5529 #endif
5530 
5531 static unsigned short
5532 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5533 {
5534   unsigned int tempax,tempbx;
5535 
5536   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5537   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5538   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5539   return (unsigned short)tempax;
5540 }
5541 
5542 /* Set Part 1 / SiS bridge slave mode */
5543 static void
5544 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5545                   unsigned short RefreshRateTableIndex)
5546 {
5547   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5548   static const unsigned short CRTranslation[] = {
5549        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5550 	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5551        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5552 	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5553        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5554 	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5555   };
5556 
5557   if(ModeNo <= 0x13) {
5558      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5559   } else if(SiS_Pr->UseCustomMode) {
5560      modeflag = SiS_Pr->CModeFlag;
5561      xres = SiS_Pr->CHDisplay;
5562   } else {
5563      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5564      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5565   }
5566 
5567   /* The following is only done if bridge is in slave mode: */
5568 
5569   if(SiS_Pr->ChipType >= SIS_315H) {
5570      if(xres >= 1600) {  /* BIOS: == 1600 */
5571         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5572      }
5573   }
5574 
5575   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5576 
5577   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5578   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5579 
5580   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5581   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5582      SiS_Pr->CHBlankStart += 16;
5583   }
5584 
5585   SiS_Pr->CHBlankEnd = 32;
5586   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5587      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5588   }
5589 
5590   temp = SiS_Pr->SiS_VGAHT - 96;
5591   if(!(modeflag & HalfDCLK)) temp -= 32;
5592   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5593      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5594      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5595      temp -= 3;
5596      temp <<= 3;
5597   } else {
5598      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5599   }
5600   SiS_Pr->CHSyncStart = temp;
5601 
5602   SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
5603 
5604   SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
5605 
5606   VGAVDE = SiS_Pr->SiS_VGAVDE;
5607   if     (VGAVDE ==  357) VGAVDE =  350;
5608   else if(VGAVDE ==  360) VGAVDE =  350;
5609   else if(VGAVDE ==  375) VGAVDE =  350;
5610   else if(VGAVDE ==  405) VGAVDE =  400;
5611   else if(VGAVDE ==  420) VGAVDE =  400;
5612   else if(VGAVDE ==  525) VGAVDE =  480;
5613   else if(VGAVDE == 1056) VGAVDE = 1024;
5614   SiS_Pr->CVDisplay = VGAVDE;
5615 
5616   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5617 
5618   SiS_Pr->CVBlankEnd = 1;
5619   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5620 
5621   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5622   SiS_Pr->CVSyncStart = VGAVDE + temp;
5623 
5624   temp >>= 3;
5625   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5626 
5627   SiS_CalcCRRegisters(SiS_Pr, 0);
5628   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5629 
5630   for(i = 0; i <= 7; i++) {
5631      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5632   }
5633   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5634      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5635   }
5636   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5637      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5638   }
5639   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5640      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5641   }
5642 
5643   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5644   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5645 
5646   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5647   if(modeflag & DoubleScanMode) temp |= 0x80;
5648   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5649 
5650   temp = 0;
5651   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5652   if(modeflag & HalfDCLK) temp |= 0x08;
5653   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5654 
5655   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
5656   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
5657 
5658   temp = 0;
5659   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5660      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5661   }
5662   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
5663 
5664   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5665   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
5666 }
5667 
5668 /* Setup panel link
5669  * This is used for LVDS, LCDA and Chrontel TV output
5670  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5671  */
5672 static void
5673 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5674 		unsigned short RefreshRateTableIndex)
5675 {
5676   unsigned short modeflag, resinfo = 0;
5677   unsigned short push2, tempax, tempbx, tempcx, temp;
5678   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5679   bool islvds = false, issis  = false, chkdclkfirst = false;
5680 #ifdef CONFIG_FB_SIS_300
5681   unsigned short crt2crtc = 0;
5682 #endif
5683 #ifdef CONFIG_FB_SIS_315
5684   unsigned short pushcx;
5685 #endif
5686 
5687   if(ModeNo <= 0x13) {
5688      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5689      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5690 #ifdef CONFIG_FB_SIS_300
5691      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5692 #endif
5693   } else if(SiS_Pr->UseCustomMode) {
5694      modeflag = SiS_Pr->CModeFlag;
5695   } else {
5696      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5697      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5698 #ifdef CONFIG_FB_SIS_300
5699      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5700 #endif
5701   }
5702 
5703   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5704   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5705      islvds = true;
5706   }
5707 
5708   /* is really sis if sis bridge, but not 301B-DH */
5709   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5710      issis = true;
5711   }
5712 
5713   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5714      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5715         chkdclkfirst = true;
5716      }
5717   }
5718 
5719 #ifdef CONFIG_FB_SIS_315
5720   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5721      if(IS_SIS330) {
5722         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5723      } else if(IS_SIS740) {
5724         if(islvds) {
5725            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5726 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5727         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5728            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5729         }
5730      } else {
5731         if(islvds) {
5732            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5733 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5734         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5735            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5736 	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5737 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5738 	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5739 	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5740 	      }
5741 	   }
5742         }
5743      }
5744   }
5745 #endif
5746 
5747   /* Horizontal */
5748 
5749   tempax = SiS_Pr->SiS_LCDHDES;
5750   if(islvds) {
5751      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5752 	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5753 	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5754 	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5755 	      tempax -= 8;
5756 	   }
5757 	}
5758      }
5759   }
5760 
5761   temp = (tempax & 0x0007);
5762   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5763   temp = (tempax >> 3) & 0x00FF;
5764   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5765 
5766   tempbx = SiS_Pr->SiS_HDE;
5767   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5768      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5769         tempbx = SiS_Pr->PanelXRes;
5770      }
5771      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5772         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5773         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5774         tempbx >>= 1;
5775      }
5776   }
5777 
5778   tempax += tempbx;
5779   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5780 
5781   temp = tempax;
5782   if(temp & 0x07) temp += 8;
5783   temp >>= 3;
5784   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5785 
5786   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5787 
5788   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5789      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5790         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5791      }
5792   }
5793 
5794   tempcx += tempax;
5795   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5796 
5797   temp = (tempcx >> 3) & 0x00FF;
5798   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5799      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5800 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5801 	   switch(ModeNo) {
5802 	   case 0x04:
5803 	   case 0x05:
5804 	   case 0x0d: temp = 0x56; break;
5805 	   case 0x10: temp = 0x60; break;
5806 	   case 0x13: temp = 0x5f; break;
5807 	   case 0x40:
5808 	   case 0x41:
5809 	   case 0x4f:
5810 	   case 0x43:
5811 	   case 0x44:
5812 	   case 0x62:
5813 	   case 0x56:
5814 	   case 0x53:
5815 	   case 0x5d:
5816 	   case 0x5e: temp = 0x54; break;
5817 	   }
5818 	}
5819      }
5820   }
5821   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5822 
5823   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5824      temp += 2;
5825      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5826 	temp += 8;
5827 	if(SiS_Pr->PanelHRE != 999) {
5828 	   temp = tempcx + SiS_Pr->PanelHRE;
5829 	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5830 	   temp >>= 3;
5831 	}
5832      }
5833   } else {
5834      temp += 10;
5835   }
5836 
5837   temp &= 0x1F;
5838   temp |= ((tempcx & 0x07) << 5);
5839   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5840 
5841   /* Vertical */
5842 
5843   tempax = SiS_Pr->SiS_VGAVDE;
5844   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5845      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5846 	tempax = SiS_Pr->PanelYRes;
5847      }
5848   }
5849 
5850   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5851   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5852 
5853   push2 = tempbx;
5854 
5855   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5856   if(SiS_Pr->ChipType < SIS_315H) {
5857      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5858 	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5859 	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5860 	}
5861      }
5862   }
5863   if(islvds) tempcx >>= 1;
5864   else       tempcx >>= 2;
5865 
5866   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5867       (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5868       (SiS_Pr->PanelVRS != 999) ) {
5869      tempcx = SiS_Pr->PanelVRS;
5870      tempbx += tempcx;
5871      if(issis) tempbx++;
5872   } else {
5873      tempbx += tempcx;
5874      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5875      else if(issis)                   tempbx++;
5876   }
5877 
5878   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5879 
5880   temp = tempbx & 0x00FF;
5881   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5882      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5883 	if(ModeNo == 0x10) temp = 0xa9;
5884      }
5885   }
5886   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
5887 
5888   tempcx >>= 3;
5889   tempcx++;
5890 
5891   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5892      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5893         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5894      }
5895   }
5896 
5897   tempcx += tempbx;
5898   temp = tempcx & 0x000F;
5899   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5900 
5901   temp = ((tempbx >> 8) & 0x07) << 3;
5902   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5903      if(SiS_Pr->SiS_HDE != 640) {
5904         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5905      }
5906   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5907   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5908   tempbx = 0x87;
5909   if((SiS_Pr->ChipType >= SIS_315H) ||
5910      (SiS_Pr->ChipRevision >= 0x30)) {
5911      tempbx = 0x07;
5912      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5913 	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5914      }
5915      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5916      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5917 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5918 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5919 	} else {
5920 	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5921 	}
5922      }
5923   }
5924   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5925 
5926   tempbx = push2;						/* BPLVDEE */
5927 
5928   tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
5929 
5930   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5931      switch(SiS_Pr->SiS_LCDResInfo) {
5932      case Panel_640x480:
5933 	tempbx = SiS_Pr->SiS_VGAVDE - 1;
5934 	tempcx = SiS_Pr->SiS_VGAVDE;
5935 	break;
5936      case Panel_800x600:
5937 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5938 	   if(resinfo == SIS_RI_800x600) tempcx++;
5939 	}
5940 	break;
5941      case Panel_1024x600:
5942 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5943 	   if(resinfo == SIS_RI_1024x600) tempcx++;
5944 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5945 	      if(resinfo == SIS_RI_800x600) tempcx++;
5946 	   }
5947 	}
5948 	break;
5949      case Panel_1024x768:
5950 	if(SiS_Pr->ChipType < SIS_315H) {
5951 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5952 	      if(resinfo == SIS_RI_1024x768) tempcx++;
5953 	   }
5954 	}
5955 	break;
5956      }
5957   }
5958 
5959   temp = ((tempbx >> 8) & 0x07) << 3;
5960   temp |= ((tempcx >> 8) & 0x07);
5961   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5962   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5963   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5964 
5965   /* Vertical scaling */
5966 
5967   if(SiS_Pr->ChipType < SIS_315H) {
5968 
5969 #ifdef CONFIG_FB_SIS_300      /* 300 series */
5970      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5971      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5972      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5973      if(temp) tempeax++;
5974 
5975      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5976 
5977      temp = (unsigned short)(tempeax & 0x00FF);
5978      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5979      tempvcfact = temp;
5980 #endif /* CONFIG_FB_SIS_300 */
5981 
5982   } else {
5983 
5984 #ifdef CONFIG_FB_SIS_315  /* 315 series */
5985      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5986      tempebx = SiS_Pr->SiS_VDE;
5987      temp = (tempeax % tempebx);
5988      tempeax = tempeax / tempebx;
5989      if(temp) tempeax++;
5990      tempvcfact = tempeax;
5991 
5992      temp = (unsigned short)(tempeax & 0x00FF);
5993      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5994      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5995      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5996      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5997      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5998      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5999 
6000      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
6001         temp = (unsigned short)(tempeax & 0x00FF);
6002         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6003         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6004         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6005         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6006         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6007         temp = 0;
6008         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6009         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6010      }
6011 #endif
6012 
6013   }
6014 
6015   /* Horizontal scaling */
6016 
6017   tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6018   if(chkdclkfirst) {
6019      if(modeflag & HalfDCLK) tempeax >>= 1;
6020   }
6021   tempebx = tempeax << 16;
6022   if(SiS_Pr->SiS_HDE == tempeax) {
6023      tempecx = 0xFFFF;
6024   } else {
6025      tempecx = tempebx / SiS_Pr->SiS_HDE;
6026      if(SiS_Pr->ChipType >= SIS_315H) {
6027         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6028      }
6029   }
6030 
6031   if(SiS_Pr->ChipType >= SIS_315H) {
6032      tempeax = (tempebx / tempecx) - 1;
6033   } else {
6034      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6035   }
6036   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6037   temp = (unsigned short)(tempecx & 0x00FF);
6038   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6039 
6040   if(SiS_Pr->ChipType >= SIS_315H) {
6041      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6042      tempbx = (unsigned short)(tempeax & 0xFFFF);
6043   } else {
6044      tempeax = SiS_Pr->SiS_VGAVDE << 6;
6045      tempbx = tempvcfact & 0x3f;
6046      if(tempbx == 0) tempbx = 64;
6047      tempeax /= tempbx;
6048      tempbx = (unsigned short)(tempeax & 0xFFFF);
6049   }
6050   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6051   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6052      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6053      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
6054   }
6055 
6056   temp = ((tempbx >> 8) & 0x07) << 3;
6057   temp = temp | ((tempecx >> 8) & 0x07);
6058   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6059   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6060 
6061   tempecx >>= 16;						/* BPLHCFACT  */
6062   if(!chkdclkfirst) {
6063      if(modeflag & HalfDCLK) tempecx >>= 1;
6064   }
6065   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6066   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6067   temp = (unsigned short)(tempecx & 0x00FF);
6068   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6069 
6070 #ifdef CONFIG_FB_SIS_315
6071   if(SiS_Pr->ChipType >= SIS_315H) {
6072      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6073         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6074            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6075 	}
6076      } else {
6077         if(islvds) {
6078            if(SiS_Pr->ChipType == SIS_740) {
6079               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6080            } else {
6081 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6082            }
6083         }
6084      }
6085   }
6086 #endif
6087 
6088 #ifdef CONFIG_FB_SIS_300
6089   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6090      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6091      unsigned char *trumpdata;
6092      int   i, j = crt2crtc;
6093      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
6094      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6095      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6096 
6097      if(SiS_Pr->SiS_UseROM) {
6098 	trumpdata = &ROMAddr[0x8001 + (j * 80)];
6099      } else {
6100 	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6101 	trumpdata = &SiS300_TrumpionData[j][0];
6102      }
6103 
6104      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6105      for(i=0; i<5; i++) {
6106 	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6107      }
6108      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6109 	if(ModeNo == 0x13) {
6110 	   for(i=0; i<4; i++) {
6111 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6112 	   }
6113 	} else if(ModeNo == 0x10) {
6114 	   for(i=0; i<4; i++) {
6115 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6116 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6117 	   }
6118 	}
6119      }
6120      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6121   }
6122 #endif
6123 
6124 #ifdef CONFIG_FB_SIS_315
6125   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6126      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6127      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6128      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6129      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6130      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6131      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6132      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6133      tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6134      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6135         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6136         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6137      tempax += 64;
6138      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6139      temp = (tempax >> 8) << 3;
6140      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6141      tempax += 32;						/* Blpe = lBlps+32 */
6142      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6143      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
6144      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6145 
6146      tempax = SiS_Pr->SiS_VDE;
6147      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6148         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6149         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6150      tempax >>= 1;
6151      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6152      temp = (tempax >> 8) << 3;
6153      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6154 
6155      tempeax = SiS_Pr->SiS_HDE;
6156      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6157         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6158         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6159      tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
6160      temp = tempeax & 0x7f;
6161      tempeax >>= 7;
6162      if(temp) tempeax++;
6163      temp = tempeax & 0x3f;
6164      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6165      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
6166      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6167      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6168      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6169 
6170      tempax = SiS_Pr->SiS_HDE;
6171      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6172         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6173         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6174      tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
6175      pushcx = tempax;
6176      temp = tempax & 0x00FF;
6177      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6178      temp = ((tempax & 0xFF00) >> 8) << 3;
6179      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6180 
6181      tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6182      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6183         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6184         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6185      tempeax = tempax * pushcx;
6186      temp = tempeax & 0xFF;
6187      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6188      temp = (tempeax & 0xFF00) >> 8;
6189      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6190      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6191      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6192      temp = ((tempeax & 0x01000000) >> 24) << 7;
6193      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6194 
6195      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6196      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6197      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6198      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6199      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6200 
6201      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6202         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6203         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6204         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6205         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6206         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6207         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6208         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6209         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6210         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6211         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6212         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6213         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6214         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6215         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6216         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6217         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6218         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6219         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6220         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6221         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6222      }
6223   }
6224 #endif  /* CONFIG_FB_SIS_315 */
6225 }
6226 
6227 /* Set Part 1 */
6228 static void
6229 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6230 		unsigned short RefreshRateTableIndex)
6231 {
6232 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6233   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6234 #endif
6235   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6236   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6237 #ifdef CONFIG_FB_SIS_315
6238   unsigned short  tempbl=0;
6239 #endif
6240 
6241   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6242      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6243      return;
6244   }
6245 
6246   if(ModeNo <= 0x13) {
6247      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6248   } else if(SiS_Pr->UseCustomMode) {
6249      modeflag = SiS_Pr->CModeFlag;
6250   } else {
6251      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6252      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6253      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6254   }
6255 
6256   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6257 
6258   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6259          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6260          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6261 
6262      if(SiS_Pr->ChipType < SIS_315H ) {
6263 #ifdef CONFIG_FB_SIS_300
6264 	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6265 #endif
6266      } else {
6267 #ifdef CONFIG_FB_SIS_315
6268 	SiS_SetCRT2FIFO_310(SiS_Pr);
6269 #endif
6270      }
6271 
6272      /* 1. Horizontal setup */
6273 
6274      if(SiS_Pr->ChipType < SIS_315H ) {
6275 
6276 #ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
6277 
6278 	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
6279 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6280 
6281 	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6282 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6283 
6284 	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6285 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6286 
6287 	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6288 	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6289 	tempbx = pushbx + tempcx;
6290 	tempcx <<= 1;
6291 	tempcx += tempbx;
6292 
6293 	bridgeadd = 12;
6294 
6295 #endif /* CONFIG_FB_SIS_300 */
6296 
6297      } else {
6298 
6299 #ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
6300 
6301 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
6302 	if(modeflag & HalfDCLK) {
6303 	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6304 	      tempcx >>= 1;
6305 	   } else {
6306 	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
6307 	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6308 	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6309 	         tempcx = SiS_Pr->SiS_HT - tempax;
6310 	      }
6311 	   }
6312 	}
6313 	tempcx--;
6314 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6315 	temp = (tempcx >> 4) & 0xF0;
6316 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6317 
6318 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
6319 	tempbx = SiS_Pr->SiS_VGAHDE;
6320 	tempcx -= tempbx;
6321 	tempcx >>= 2;
6322 	if(modeflag & HalfDCLK) {
6323 	   tempbx >>= 1;
6324 	   tempcx >>= 1;
6325 	}
6326 	tempbx += 16;
6327 
6328 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6329 
6330 	pushbx = tempbx;
6331 	tempcx >>= 1;
6332 	tempbx += tempcx;
6333 	tempcx += tempbx;
6334 
6335 	bridgeadd = 16;
6336 
6337 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6338 	   if(SiS_Pr->ChipType >= SIS_661) {
6339 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6340 		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6341 		 if(resinfo == SIS_RI_1280x1024) {
6342 		    tempcx = (tempcx & 0xff00) | 0x30;
6343 		 } else if(resinfo == SIS_RI_1600x1200) {
6344 		    tempcx = (tempcx & 0xff00) | 0xff;
6345 		 }
6346 	      }
6347 	   }
6348         }
6349 
6350 #endif  /* CONFIG_FB_SIS_315 */
6351 
6352      }  /* 315/330 series */
6353 
6354      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6355 
6356 	if(SiS_Pr->UseCustomMode) {
6357 	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6358 	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6359 	   tempax = SiS_Pr->SiS_VGAHT;
6360 	   if(modeflag & HalfDCLK) tempax >>= 1;
6361 	   tempax--;
6362 	   if(tempcx > tempax) tempcx = tempax;
6363 	}
6364 
6365 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6366 	   unsigned char cr4, cr14, cr5, cr15;
6367 	   if(SiS_Pr->UseCustomMode) {
6368 	      cr4  = SiS_Pr->CCRT1CRTC[4];
6369 	      cr14 = SiS_Pr->CCRT1CRTC[14];
6370 	      cr5  = SiS_Pr->CCRT1CRTC[5];
6371 	      cr15 = SiS_Pr->CCRT1CRTC[15];
6372 	   } else {
6373 	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6374 	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6375 	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6376 	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6377 	   }
6378 	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6379 	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6380 	   tempcx &= 0x00FF;
6381 	   tempcx |= (tempbx & 0xFF00);
6382 	   tempbx += bridgeadd;
6383 	   tempcx += bridgeadd;
6384 	   tempax = SiS_Pr->SiS_VGAHT;
6385 	   if(modeflag & HalfDCLK) tempax >>= 1;
6386 	   tempax--;
6387 	   if(tempcx > tempax) tempcx = tempax;
6388 	}
6389 
6390 	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6391 	   tempbx = 1040;
6392 	   tempcx = 1044;   /* HWCursor bug! */
6393 	}
6394 
6395      }
6396 
6397      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6398 
6399      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6400 
6401      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6402      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6403 
6404      /* 2. Vertical setup */
6405 
6406      tempcx = SiS_Pr->SiS_VGAVT - 1;
6407      temp = tempcx & 0x00FF;
6408 
6409      if(SiS_Pr->ChipType < SIS_661) {
6410         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6411 	   if(SiS_Pr->ChipType < SIS_315H) {
6412 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6413 	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6414 	            temp--;
6415 	         }
6416 	      }
6417 	   } else {
6418 	      temp--;
6419 	   }
6420 	} else if(SiS_Pr->ChipType >= SIS_315H) {
6421 	   temp--;
6422 	}
6423      }
6424      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6425 
6426      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6427      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6428 
6429      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6430      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6431 
6432      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6433 	tempbx++;
6434 	tempax = tempbx;
6435 	tempcx++;
6436 	tempcx -= tempax;
6437 	tempcx >>= 2;
6438 	tempbx += tempcx;
6439 	if(tempcx < 4) tempcx = 4;
6440 	tempcx >>= 2;
6441 	tempcx += tempbx;
6442 	tempcx++;
6443      } else {
6444 	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6445 	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6446      }
6447 
6448      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6449 	if(SiS_Pr->UseCustomMode) {
6450 	   tempbx = SiS_Pr->CVSyncStart;
6451 	   tempcx = SiS_Pr->CVSyncEnd;
6452 	}
6453 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6454 	   unsigned char cr8, cr7, cr13;
6455 	   if(SiS_Pr->UseCustomMode) {
6456 	      cr8    = SiS_Pr->CCRT1CRTC[8];
6457 	      cr7    = SiS_Pr->CCRT1CRTC[7];
6458 	      cr13   = SiS_Pr->CCRT1CRTC[13];
6459 	      tempcx = SiS_Pr->CCRT1CRTC[9];
6460 	   } else {
6461 	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6462 	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6463 	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6464 	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6465 	   }
6466 	   tempbx = cr8;
6467 	   if(cr7  & 0x04) tempbx |= 0x0100;
6468 	   if(cr7  & 0x80) tempbx |= 0x0200;
6469 	   if(cr13 & 0x08) tempbx |= 0x0400;
6470 	}
6471      }
6472      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6473 
6474      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6475      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6476 
6477      /* 3. Panel delay compensation */
6478 
6479      if(SiS_Pr->ChipType < SIS_315H) {
6480 
6481 #ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
6482 
6483 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6484 	   temp = 0x20;
6485 	   if(SiS_Pr->ChipType == SIS_300) {
6486 	      temp = 0x10;
6487 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6488 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6489 	   }
6490 	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6491 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6492 	   }
6493 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6494 	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6495 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6496 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6497 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6498 	      else 					    temp = 0x20;
6499 	   }
6500 	   if(SiS_Pr->SiS_UseROM) {
6501 	      if(ROMAddr[0x220] & 0x80) {
6502 		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6503 		    temp = ROMAddr[0x221];
6504 		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6505 		    temp = ROMAddr[0x222];
6506 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6507 		    temp = ROMAddr[0x223];
6508 		 else
6509 		    temp = ROMAddr[0x224];
6510 	      }
6511 	   }
6512 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6513 	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6514 	   }
6515 
6516 	} else {
6517 	   temp = 0x20;
6518 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6519 	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6520 	   }
6521 	   if(SiS_Pr->SiS_UseROM) {
6522 	      if(ROMAddr[0x220] & 0x80) {
6523 	         temp = ROMAddr[0x220];
6524 	      }
6525 	   }
6526 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6527 	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6528 	   }
6529 	}
6530 
6531 	temp &= 0x3c;
6532 
6533 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6534 
6535 #endif  /* CONFIG_FB_SIS_300 */
6536 
6537      } else {
6538 
6539 #ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
6540 
6541 	if(SiS_Pr->ChipType < SIS_661) {
6542 
6543 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6544 
6545 	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6546 	      else 		              temp = 0x00;
6547 
6548 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6549 	      tempbl = 0xF0;
6550 	      if(SiS_Pr->ChipType == SIS_650) {
6551 		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6552 		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6553 		 }
6554 	      }
6555 
6556 	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6557 		 temp = 0x08;
6558 		 tempbl = 0;
6559 		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6560 		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6561 		 }
6562 	      }
6563 
6564 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6565 	   }
6566 
6567 	} /* < 661 */
6568 
6569 	tempax = 0;
6570 	if(modeflag & DoubleScanMode) tempax |= 0x80;
6571 	if(modeflag & HalfDCLK)       tempax |= 0x40;
6572 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6573 
6574 #endif  /* CONFIG_FB_SIS_315 */
6575 
6576      }
6577 
6578   }  /* Slavemode */
6579 
6580   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6581      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6582 	/* For 301BDH with LCD, we set up the Panel Link */
6583 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6584      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6585 	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6586      }
6587   } else {
6588      if(SiS_Pr->ChipType < SIS_315H) {
6589 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6590      } else {
6591 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6592 	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6593 	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6594 	   }
6595 	} else {
6596 	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6597 	}
6598      }
6599   }
6600 }
6601 
6602 /*********************************************/
6603 /*         SET PART 2 REGISTER GROUP         */
6604 /*********************************************/
6605 
6606 #ifdef CONFIG_FB_SIS_315
6607 static unsigned char *
6608 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6609 {
6610    const unsigned char *tableptr = NULL;
6611    unsigned short      a, b, p = 0;
6612 
6613    a = SiS_Pr->SiS_VGAHDE;
6614    b = SiS_Pr->SiS_HDE;
6615    if(tabletype) {
6616       a = SiS_Pr->SiS_VGAVDE;
6617       b = SiS_Pr->SiS_VDE;
6618    }
6619 
6620    if(a < b) {
6621       tableptr = SiS_Part2CLVX_1;
6622    } else if(a == b) {
6623       tableptr = SiS_Part2CLVX_2;
6624    } else {
6625       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6626 	 tableptr = SiS_Part2CLVX_4;
6627       } else {
6628 	 tableptr = SiS_Part2CLVX_3;
6629       }
6630       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6631 	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
6632 	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
6633 	 else 				         	tableptr = SiS_Part2CLVX_5;
6634       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6635 	 tableptr = SiS_Part2CLVX_6;
6636       }
6637       do {
6638 	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6639 	 p += 0x42;
6640       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6641       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6642    }
6643    p += 2;
6644    return ((unsigned char *)&tableptr[p]);
6645 }
6646 
6647 static void
6648 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6649 	      	    unsigned short RefreshRateTableIndex)
6650 {
6651    unsigned char *tableptr;
6652    unsigned char temp;
6653    int i, j;
6654 
6655    if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6656 
6657    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6658    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6659       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6660    }
6661    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6662       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6663       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6664          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6665       }
6666    }
6667    temp = 0x10;
6668    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6669    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6670 }
6671 
6672 static bool
6673 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6674 		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6675 		    unsigned short *ResIndex)
6676 {
6677 
6678   if(SiS_Pr->ChipType < SIS_315H) return false;
6679 
6680   if(ModeNo <= 0x13)
6681      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6682   else
6683      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6684 
6685   (*ResIndex) &= 0x3f;
6686   (*CRT2Index) = 0;
6687 
6688   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6689      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6690         (*CRT2Index) = 200;
6691      }
6692   }
6693 
6694   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6695      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6696         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6697      }
6698   }
6699   return (((*CRT2Index) != 0));
6700 }
6701 #endif
6702 
6703 #ifdef CONFIG_FB_SIS_300
6704 static void
6705 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6706 {
6707    unsigned short tempcx;
6708    static const unsigned char atable[] = {
6709        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6710        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6711    };
6712 
6713    if(!SiS_Pr->UseCustomMode) {
6714       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6715 	      (SiS_Pr->ChipType == SIS_730) ) &&
6716 	    (SiS_Pr->ChipRevision > 2) )  &&
6717 	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6718 	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6719 	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6720 	 if(ModeNo == 0x13) {
6721 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6722 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6723 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6724 	 } else if((crt2crtc & 0x3F) == 4) {
6725 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6726 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6727 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6728 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6729 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6730 	 }
6731       }
6732 
6733       if(SiS_Pr->ChipType < SIS_315H) {
6734 	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6735 	    crt2crtc &= 0x1f;
6736 	    tempcx = 0;
6737 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6738 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6739 		  tempcx += 7;
6740 	       }
6741 	    }
6742 	    tempcx += crt2crtc;
6743 	    if(crt2crtc >= 4) {
6744 	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6745 	    }
6746 
6747 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6748 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6749 		  if(crt2crtc == 4) {
6750 		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6751 		  }
6752 	       }
6753 	    }
6754 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6755 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6756 	 }
6757       }
6758    }
6759 }
6760 
6761 /* For ECS A907. Highly preliminary. */
6762 static void
6763 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6764 		    unsigned short ModeNo)
6765 {
6766   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6767   unsigned short crt2crtc, resindex;
6768   int i, j;
6769 
6770   if(SiS_Pr->ChipType != SIS_300) return;
6771   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6772   if(SiS_Pr->UseCustomMode) return;
6773 
6774   if(ModeNo <= 0x13) {
6775      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6776   } else {
6777      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6778   }
6779 
6780   resindex = crt2crtc & 0x3F;
6781   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6782   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6783 
6784   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6785   if(ModeNo > 0x13) {
6786      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6787      resindex = 4;
6788   }
6789 
6790   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6791   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6792   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6793      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6794   }
6795   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6796      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6797   }
6798   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6799      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6800   }
6801   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6802   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6803 }
6804 #endif
6805 
6806 static void
6807 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6808 {
6809   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6810   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6811   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6812 
6813   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6814      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6815         static const unsigned char specialtv[] = {
6816 		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6817 		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6818 		0x58,0xe4,0x73,0xda,0x13
6819 	};
6820 	int i, j;
6821 	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6822 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6823 	}
6824 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6825 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6826 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6827 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6828 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6829 	   } else {
6830 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6831 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6832 	   }
6833 	}
6834      }
6835   } else {
6836      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6837         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6838         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6839         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6840      } else {
6841         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6842         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6843      }
6844   }
6845 }
6846 
6847 static void
6848 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6849 {
6850   unsigned short temp;
6851 
6852   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6853      if(SiS_Pr->SiS_VGAVDE == 525) {
6854 	temp = 0xc3;
6855 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6856 	   temp++;
6857 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6858 	}
6859 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6860 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6861      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6862 	temp = 0x4d;
6863 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6864 	   temp++;
6865 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6866 	}
6867 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6868      }
6869   }
6870 
6871   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6872      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6873 	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6874 	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6875 	   /* Not always for LV, see SetGrp2 */
6876 	}
6877 	temp = 1;
6878 	if(ModeNo <= 0x13) temp = 3;
6879 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6880      }
6881 #if 0
6882      /* 651+301C, for 1280x768 - do I really need that? */
6883      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6884         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6885 	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6886 	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6887 	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6888 	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
6889 	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6890 	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
6891 	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6892 	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6893 	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6894 	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6895 	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
6896 	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6897 	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6898 	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
6899 	   }
6900 	}
6901      }
6902 #endif
6903   }
6904 }
6905 
6906 static void
6907 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6908 		unsigned short RefreshRateTableIndex)
6909 {
6910   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6911   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6912   unsigned int   longtemp, PhaseIndex;
6913   bool           newtvphase;
6914   const unsigned char *TimingPoint;
6915 #ifdef CONFIG_FB_SIS_315
6916   unsigned short resindex, CRT2Index;
6917   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6918 
6919   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6920 #endif
6921 
6922   if(ModeNo <= 0x13) {
6923      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6924      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6925   } else if(SiS_Pr->UseCustomMode) {
6926      modeflag = SiS_Pr->CModeFlag;
6927      crt2crtc = 0;
6928   } else {
6929      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6930      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6931   }
6932 
6933   temp = 0;
6934   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6935   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6936   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6937   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6938 
6939   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
6940 
6941   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6942 
6943   PhaseIndex  = 0x01; /* SiS_PALPhase */
6944   TimingPoint = SiS_Pr->SiS_PALTiming;
6945 
6946   newtvphase = false;
6947   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6948       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6949 	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6950      newtvphase = true;
6951   }
6952 
6953   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6954 
6955      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6956      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6957         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6958         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6959 	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6960         }
6961      }
6962 
6963   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6964 
6965      i = 0;
6966      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6967      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6968 
6969      TimingPoint = &SiS_YPbPrTable[i][0];
6970 
6971      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6972 
6973   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6974 
6975      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6976 
6977   } else {
6978 
6979      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6980      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
6981      if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
6982 
6983   }
6984 
6985   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6986      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
6987      if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
6988   }
6989 
6990   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6991      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6992         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6993      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6994         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6995      } else {
6996         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6997      }
6998   }
6999 
7000   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
7001      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
7002   }
7003 
7004   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7005      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7006   }
7007   for(i = 0x39; i <= 0x45; i++, j++) {
7008      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7009   }
7010 
7011   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7012      if(SiS_Pr->SiS_ModeType != ModeText) {
7013         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7014      }
7015   }
7016 
7017   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7018 
7019   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7020   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7021   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7022   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7023 
7024   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
7025   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
7026   else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;
7027   else						tempax = 440; /* NTSC, YPbPr 525 */
7028 
7029   if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7030       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7031         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7032 
7033      tempax -= SiS_Pr->SiS_VDE;
7034      tempax >>= 1;
7035      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7036         tempax >>= 1;
7037      }
7038      tempax &= 0x00ff;
7039 
7040      temp = tempax + (unsigned short)TimingPoint[0];
7041      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7042 
7043      temp = tempax + (unsigned short)TimingPoint[1];
7044      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7045 
7046      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7047         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7048            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7049            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7050         } else {
7051            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7052            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7053         }
7054      }
7055 
7056   }
7057 
7058   tempcx = SiS_Pr->SiS_HT;
7059   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7060   tempcx--;
7061   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7062   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7063   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7064 
7065   tempcx = SiS_Pr->SiS_HT >> 1;
7066   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7067   tempcx += 7;
7068   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7069   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7070 
7071   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7072   tempbx += tempcx;
7073   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7074   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7075 
7076   tempbx += 8;
7077   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7078      tempbx -= 4;
7079      tempcx = tempbx;
7080   }
7081   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7082 
7083   j += 2;
7084   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7085   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7086   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7087 
7088   tempcx += 8;
7089   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7090   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7091 
7092   tempcx = SiS_Pr->SiS_HT >> 1;
7093   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7094   j += 2;
7095   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7096   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7097 
7098   tempcx -= 11;
7099   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7100      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7101   }
7102   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7103 
7104   tempbx = SiS_Pr->SiS_VDE;
7105   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7106      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7107      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7108      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7109   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7110              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7111      tempbx >>= 1;
7112      if(SiS_Pr->ChipType >= SIS_315H) {
7113         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7114 	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7115 	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7116 	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7117 	      if(crt2crtc == 4) tempbx++;
7118 	   }
7119 	}
7120      }
7121      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7122         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7123 	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7124 	}
7125 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7126 	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7127         }
7128      }
7129   }
7130   tempbx -= 2;
7131   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7132 
7133   temp = (tempcx >> 8) & 0x0F;
7134   temp |= ((tempbx >> 2) & 0xC0);
7135   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7136      temp |= 0x10;
7137      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7138   }
7139   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7140 
7141   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7142      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7143   }
7144 
7145   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7146      tempbx = SiS_Pr->SiS_VDE;
7147      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7148          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7149         tempbx >>= 1;
7150      }
7151      tempbx -= 3;
7152      temp = ((tempbx >> 3) & 0x60) | 0x18;
7153      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7154      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7155 
7156      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7157 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7158      }
7159   }
7160 
7161   tempbx = 0;
7162   if(!(modeflag & HalfDCLK)) {
7163      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7164         tempax = 0;
7165         tempbx |= 0x20;
7166      }
7167   }
7168 
7169   tempch = tempcl = 0x01;
7170   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7171      if(SiS_Pr->SiS_VGAHDE >= 960) {
7172         if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7173 	   tempcl = 0x20;
7174 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
7175               tempch = 20;
7176               tempbx &= ~0x20;
7177            } else {
7178 	      tempch = 25; /* OK */
7179 	   }
7180         }
7181      }
7182   }
7183 
7184   if(!(tempbx & 0x20)) {
7185      if(modeflag & HalfDCLK) tempcl <<= 1;
7186      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7187      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7188      tempax = longtemp / SiS_Pr->SiS_HDE;
7189      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7190      tempbx |= ((tempax >> 8) & 0x1F);
7191      tempcx = tempax >> 13;
7192   }
7193 
7194   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7195   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7196 
7197   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7198 
7199      tempcx &= 0x07;
7200      if(tempbx & 0x20) tempcx = 0;
7201      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7202 
7203      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7204         tempbx = 0x0382;
7205         tempcx = 0x007e;
7206      } else {
7207         tempbx = 0x0369;
7208         tempcx = 0x0061;
7209      }
7210      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7211      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7212      temp = (tempcx & 0x0300) >> 6;
7213      temp |= ((tempbx >> 8) & 0x03);
7214      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7215         temp |= 0x10;
7216 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7217 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7218      }
7219      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7220 
7221      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7222      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7223 
7224      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7225 
7226      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7227         temp = 0;
7228         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7229         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7230      }
7231 
7232   }
7233 
7234   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7235      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7236         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7237         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7238      }
7239      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7240   }
7241 
7242   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7243      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7244         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7245      }
7246   }
7247 
7248   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7249 
7250   /* From here: Part2 LCD setup */
7251 
7252   tempbx = SiS_Pr->SiS_HDE;
7253   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7254   tempbx--;			         	/* RHACTE = HDE - 1 */
7255   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7256   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7257 
7258   temp = 0x01;
7259   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7260      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7261         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7262            temp = 0x02;
7263            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7264               temp = 0x01;
7265 	   }
7266         }
7267      }
7268   }
7269   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7270 
7271   tempbx = SiS_Pr->SiS_VDE - 1;
7272   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7273   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7274 
7275   tempcx = SiS_Pr->SiS_VT - 1;
7276   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7277   temp = (tempcx >> 3) & 0xE0;
7278   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7279      /* Enable dithering; only do this for 32bpp mode */
7280      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7281         temp |= 0x10;
7282      }
7283   }
7284   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7285 
7286   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7287   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7288 
7289   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7290   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7291 
7292 #ifdef CONFIG_FB_SIS_315
7293   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7294                           			&CRT2Index, &resindex)) {
7295       switch(CRT2Index) {
7296         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7297 	default:
7298         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7299       }
7300 
7301       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7302       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7303       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7304         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305       }
7306       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7307         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308       }
7309       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7310         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7311       }
7312       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7313       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7314 
7315       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7316 
7317   } else {
7318 #endif
7319 
7320     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7321     /*             Clevo dual-link 1024x768 */
7322     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7323     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7324 
7325     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7326        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7327           tempbx = SiS_Pr->SiS_VDE - 1;
7328           tempcx = SiS_Pr->SiS_VT - 1;
7329        } else {
7330           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7331 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7332        }
7333     } else {
7334        tempbx = SiS_Pr->PanelYRes;
7335        tempcx = SiS_Pr->SiS_VT;
7336        tempax = 1;
7337        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7338           tempax = SiS_Pr->PanelYRes;
7339 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7340           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7341              tempax = tempcx = 0;
7342           } else {
7343              tempax -= SiS_Pr->SiS_VDE;
7344           }
7345           tempax >>= 1;
7346        }
7347        tempcx -= tempax; /* lcdvdes */
7348        tempbx -= tempax; /* lcdvdee */
7349     }
7350 
7351     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7352 
7353     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7354     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7355 
7356     temp = (tempbx >> 5) & 0x38;
7357     temp |= ((tempcx >> 8) & 0x07);
7358     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7359 
7360     tempax = SiS_Pr->SiS_VDE;
7361     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7362        tempax = SiS_Pr->PanelYRes;
7363     }
7364     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7365     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7366        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7367 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7368        }
7369     }
7370 
7371     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7372     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7373        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7374           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7375              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7376 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7377 	     else           { tempax >>= 2;           }
7378              tempbx -= (tempax - 1);
7379 	  } else {
7380 	     tempbx -= 10;
7381 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7382 	  }
7383        }
7384     }
7385     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7386        tempbx++;
7387        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7388           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7389 	     tempbx = 770;
7390 	     tempcx = 3;
7391 	  }
7392        }
7393     }
7394 
7395     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7396 
7397     if(SiS_Pr->UseCustomMode) {
7398        tempbx = SiS_Pr->CVSyncStart;
7399     }
7400 
7401     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7402 
7403     temp = (tempbx >> 4) & 0xF0;
7404     tempbx += (tempcx + 1);
7405     temp |= (tempbx & 0x0F);
7406 
7407     if(SiS_Pr->UseCustomMode) {
7408        temp &= 0xf0;
7409        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7410     }
7411 
7412     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7413 
7414 #ifdef CONFIG_FB_SIS_300
7415     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7416 #endif
7417 
7418     bridgeoffset = 7;
7419     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7420     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7421     if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7422     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7423     /* Higher bridgeoffset shifts to the LEFT */
7424 
7425     temp = 0;
7426     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7427        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7428 	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7429 	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7430        }
7431     }
7432     temp += bridgeoffset;
7433     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7434     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7435 
7436     tempcx = SiS_Pr->SiS_HT;
7437     tempax = tempbx = SiS_Pr->SiS_HDE;
7438     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7439        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7440           tempax = SiS_Pr->PanelXRes;
7441           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7442        }
7443     }
7444     if(SiS_IsDualLink(SiS_Pr)) {
7445        tempcx >>= 1;
7446        tempbx >>= 1;
7447        tempax >>= 1;
7448     }
7449 
7450     tempbx += bridgeoffset;
7451 
7452     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7453     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7454 
7455     tempcx = (tempcx - tempax) >> 2;
7456 
7457     tempbx += tempcx;
7458     push2 = tempbx;
7459 
7460     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7461        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7462           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7463              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7464 	  }
7465        }
7466     }
7467 
7468     if(SiS_Pr->UseCustomMode) {
7469        tempbx = SiS_Pr->CHSyncStart;
7470        if(modeflag & HalfDCLK) tempbx <<= 1;
7471        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7472        tempbx += bridgeoffset;
7473     }
7474 
7475     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7476     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7477 
7478     tempbx = push2;
7479 
7480     tempcx <<= 1;
7481     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7482        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7483     }
7484     tempbx += tempcx;
7485 
7486     if(SiS_Pr->UseCustomMode) {
7487        tempbx = SiS_Pr->CHSyncEnd;
7488        if(modeflag & HalfDCLK) tempbx <<= 1;
7489        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7490        tempbx += bridgeoffset;
7491     }
7492 
7493     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7494 
7495     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7496 
7497 #ifdef CONFIG_FB_SIS_300
7498     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7499 #endif
7500 #ifdef CONFIG_FB_SIS_315
7501   } /* CRT2-LCD from table */
7502 #endif
7503 }
7504 
7505 /*********************************************/
7506 /*         SET PART 3 REGISTER GROUP         */
7507 /*********************************************/
7508 
7509 static void
7510 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7511 {
7512   unsigned short i;
7513   const unsigned char *tempdi;
7514 
7515   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7516 
7517 #ifndef SIS_CP
7518   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7519 #else
7520   SIS_CP_INIT301_CP
7521 #endif
7522 
7523   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7524      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7525      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7526   } else {
7527      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7528      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7529   }
7530 
7531   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7532      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7533      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7534      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7535   }
7536 
7537   tempdi = NULL;
7538   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7539      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7540      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7541         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7542      }
7543   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7544      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7545         tempdi = SiS_HiTVGroup3_1;
7546         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7547      }
7548   }
7549   if(tempdi) {
7550      for(i=0; i<=0x3E; i++) {
7551         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7552      }
7553      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7554 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7555 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7556 	}
7557      }
7558   }
7559 
7560 #ifdef SIS_CP
7561   SIS_CP_INIT301_CP2
7562 #endif
7563 }
7564 
7565 /*********************************************/
7566 /*         SET PART 4 REGISTER GROUP         */
7567 /*********************************************/
7568 
7569 #ifdef CONFIG_FB_SIS_315
7570 #if 0
7571 static void
7572 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7573 {
7574    unsigned short temp, temp1, temp2;
7575 
7576    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7577    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7578    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7579    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7580    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7581    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7582    temp = (unsigned short)((int)(temp) + shift);
7583    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7584    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7585    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7586    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7587    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7588    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7589 }
7590 #endif
7591 
7592 static void
7593 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7594 {
7595    unsigned short temp, temp1;
7596    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7597 
7598    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7599    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7600 
7601    if(SiS_Pr->ChipType >= XGI_20) return;
7602 
7603    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7604       if(!(ROMAddr[0x61] & 0x04)) return;
7605    }
7606 
7607    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7608    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7609    if(!(temp & 0x01)) {
7610       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7611       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7612       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7613          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7614       }
7615       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7616       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7617       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7618       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7619       else					   temp = 0x0402;
7620       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7621          temp1 = 0;
7622 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7623 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7624 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7625 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7626 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7627 	 if(ModeNo > 0x13) {
7628             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7629          }
7630       } else {
7631          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7632 	 if(temp1 == 0x01) temp |= 0x01;
7633 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7634 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7635 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7636 	 if(ModeNo > 0x13) {
7637             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7638          }
7639       }
7640 
7641 #if 0
7642       if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7643          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7644             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7645 	       if(resinfo == SIS_RI_1024x768) {
7646 	          SiS_ShiftXPos(SiS_Pr, 97);
7647 	       } else {
7648 	          SiS_ShiftXPos(SiS_Pr, 111);
7649 	       }
7650 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7651 	       SiS_ShiftXPos(SiS_Pr, 136);
7652 	    }
7653          }
7654       }
7655 #endif
7656 
7657    }
7658 
7659 }
7660 #endif
7661 
7662 static void
7663 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7664                  unsigned short RefreshRateTableIndex)
7665 {
7666   unsigned short vclkindex, temp, reg1, reg2;
7667 
7668   if(SiS_Pr->UseCustomMode) {
7669      reg1 = SiS_Pr->CSR2B;
7670      reg2 = SiS_Pr->CSR2C;
7671   } else {
7672      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7673      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7674      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7675   }
7676 
7677   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7678      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7679         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7680  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7681 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7682      } else {
7683         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7684         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7685      }
7686   } else {
7687      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7688      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7689      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7690   }
7691   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7692   temp = 0x08;
7693   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7694   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7695 }
7696 
7697 static void
7698 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7699 {
7700   if(SiS_Pr->ChipType >= SIS_315H) {
7701      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7702 	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7703 	   (SiS_IsVAMode(SiS_Pr))) {
7704 	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7705 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7706 	   } else {
7707 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7708 	   }
7709 	}
7710      }
7711   }
7712   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7713      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7714 #ifdef SET_EMI
7715      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7716 #endif
7717      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7718   }
7719 }
7720 
7721 static void
7722 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7723 		unsigned short RefreshRateTableIndex)
7724 {
7725   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7726   unsigned int   tempebx, tempeax, templong;
7727 
7728   if(ModeNo <= 0x13) {
7729      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7730      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7731   } else if(SiS_Pr->UseCustomMode) {
7732      modeflag = SiS_Pr->CModeFlag;
7733      resinfo = 0;
7734   } else {
7735      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7736      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7737   }
7738 
7739   if(SiS_Pr->ChipType >= SIS_315H) {
7740      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7741 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7742 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7743 	}
7744      }
7745   }
7746 
7747   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7748      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7749 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7750      }
7751   }
7752 
7753   if(SiS_Pr->ChipType >= SIS_315H) {
7754      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7755 	SiS_SetDualLinkEtc(SiS_Pr);
7756 	return;
7757      }
7758   }
7759 
7760   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7761 
7762   tempbx = SiS_Pr->SiS_RVBHCMAX;
7763   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7764 
7765   temp = (tempbx >> 1) & 0x80;
7766 
7767   tempcx = SiS_Pr->SiS_VGAHT - 1;
7768   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7769 
7770   temp |= ((tempcx >> 5) & 0x78);
7771 
7772   tempcx = SiS_Pr->SiS_VGAVT - 1;
7773   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7774   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7775 
7776   temp |= ((tempcx >> 8) & 0x07);
7777   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7778 
7779   tempbx = SiS_Pr->SiS_VGAHDE;
7780   if(modeflag & HalfDCLK)    tempbx >>= 1;
7781   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7782 
7783   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7784      temp = 0;
7785      if(tempbx > 800)        temp = 0x60;
7786   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7787      temp = 0;
7788      if(tempbx > 1024)       temp = 0xC0;
7789      else if(tempbx >= 960)  temp = 0xA0;
7790   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7791      temp = 0;
7792      if(tempbx >= 1280)      temp = 0x40;
7793      else if(tempbx >= 1024) temp = 0x20;
7794   } else {
7795      temp = 0x80;
7796      if(tempbx >= 1024)      temp = 0xA0;
7797   }
7798 
7799   temp |= SiS_Pr->Init_P4_0E;
7800 
7801   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7802      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7803         temp &= 0xf0;
7804         temp |= 0x0A;
7805      }
7806   }
7807 
7808   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7809 
7810   tempeax = SiS_Pr->SiS_VGAVDE;
7811   tempebx = SiS_Pr->SiS_VDE;
7812   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7813      if(!(temp & 0xE0)) tempebx >>=1;
7814   }
7815 
7816   tempcx = SiS_Pr->SiS_RVBHRS;
7817   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7818   tempcx >>= 8;
7819   tempcx |= 0x40;
7820 
7821   if(tempeax <= tempebx) {
7822      tempcx ^= 0x40;
7823   } else {
7824      tempeax -= tempebx;
7825   }
7826 
7827   tempeax *= (256 * 1024);
7828   templong = tempeax % tempebx;
7829   tempeax /= tempebx;
7830   if(templong) tempeax++;
7831 
7832   temp = (unsigned short)(tempeax & 0x000000FF);
7833   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7834   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7835   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7836   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7837   temp |= (tempcx & 0x4F);
7838   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7839 
7840   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7841 
7842      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7843 
7844      /* Calc Linebuffer max address and set/clear decimode */
7845      tempbx = 0;
7846      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7847      tempax = SiS_Pr->SiS_VGAHDE;
7848      if(modeflag & HalfDCLK)    tempax >>= 1;
7849      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7850      if(tempax > 800) {
7851         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7852 	   tempax -= 800;
7853 	} else {
7854 	   tempbx = 0x08;
7855 	   if(tempax == 960)	   tempax *= 25; /* Correct */
7856            else if(tempax == 1024) tempax *= 25;
7857            else			   tempax *= 20;
7858 	   temp = tempax % 32;
7859 	   tempax /= 32;
7860 	   if(temp) tempax++;
7861 	   tempax++;
7862 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7863 	      if(resinfo == SIS_RI_1024x768 ||
7864 	         resinfo == SIS_RI_1024x576 ||
7865 		 resinfo == SIS_RI_1280x1024 ||
7866 		 resinfo == SIS_RI_1280x720) {
7867 	         /* Otherwise white line or garbage at right edge */
7868 	         tempax = (tempax & 0xff00) | 0x20;
7869 	      }
7870 	   }
7871 	}
7872      }
7873      tempax--;
7874      temp = ((tempax >> 4) & 0x30) | tempbx;
7875      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7876      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7877 
7878      temp = 0x0036; tempbx = 0xD0;
7879      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7880 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7881      }
7882      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7883         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7884 	   temp |= 0x01;
7885 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7886 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7887   	         temp &= ~0x01;
7888 	      }
7889 	   }
7890 	}
7891      }
7892      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7893 
7894      tempbx = SiS_Pr->SiS_HT >> 1;
7895      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7896      tempbx -= 2;
7897      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7898      temp = (tempbx >> 5) & 0x38;
7899      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7900 
7901      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7902 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7903            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7904 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7905 	}
7906      }
7907 
7908      SiS_SetDualLinkEtc(SiS_Pr);
7909 
7910   }  /* 301B */
7911 
7912   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7913 }
7914 
7915 /*********************************************/
7916 /*         SET PART 5 REGISTER GROUP         */
7917 /*********************************************/
7918 
7919 static void
7920 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7921 {
7922 
7923   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7924 
7925   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7926      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7927         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7928         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7929      }
7930   }
7931 }
7932 
7933 /*********************************************/
7934 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7935 /*********************************************/
7936 
7937 static bool
7938 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7939 		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7940 		   unsigned short *DisplayType)
7941  {
7942   unsigned short modeflag = 0;
7943   bool checkhd = true;
7944 
7945   /* Pass 1:1 not supported here */
7946 
7947   if(ModeNo <= 0x13) {
7948      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7949      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7950   } else {
7951      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7952      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7953   }
7954 
7955   (*ResIndex) &= 0x3F;
7956 
7957   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7958 
7959      (*DisplayType) = 80;
7960      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7961       	(*DisplayType) = 82;
7962 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7963 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7964 	}
7965      }
7966      if((*DisplayType) != 84) {
7967         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7968      }
7969 
7970   } else {
7971 
7972      (*DisplayType = 0);
7973      switch(SiS_Pr->SiS_LCDResInfo) {
7974      case Panel_320x240_1: (*DisplayType) = 50;
7975 			   checkhd = false;
7976 			   break;
7977      case Panel_320x240_2: (*DisplayType) = 14;
7978 			   break;
7979      case Panel_320x240_3: (*DisplayType) = 18;
7980 			   break;
7981      case Panel_640x480:   (*DisplayType) = 10;
7982 			   break;
7983      case Panel_1024x600:  (*DisplayType) = 26;
7984 			   break;
7985      default: return true;
7986      }
7987 
7988      if(checkhd) {
7989         if(modeflag & HalfDCLK) (*DisplayType)++;
7990      }
7991 
7992      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7993         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7994      }
7995 
7996   }
7997 
7998   return true;
7999 }
8000 
8001 static void
8002 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8003                 unsigned short RefreshRateTableIndex)
8004 {
8005   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8006   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8007   static const unsigned short CRIdx[] = {
8008 	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8009 	0x07, 0x10, 0x11, 0x15, 0x16
8010   };
8011 
8012   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8013      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8014      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
8015      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8016      return;
8017 
8018   if(SiS_Pr->SiS_IF_DEF_LVDS) {
8019      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8020         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8021      }
8022   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8023      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8024   } else return;
8025 
8026   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8027 
8028   if(SiS_Pr->ChipType < SIS_315H) {
8029      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8030   }
8031 
8032   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8033                           &ResIndex, &DisplayType))) {
8034      return;
8035   }
8036 
8037   switch(DisplayType) {
8038     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
8039     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
8040     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
8041     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
8042     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
8043     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
8044     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
8045 #if 0 /* Works better with calculated numbers */
8046     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
8047     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
8048     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
8049     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
8050 #endif
8051     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
8052     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
8053     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
8054     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
8055     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
8056   }
8057 
8058   if(LVDSCRT1Ptr) {
8059 
8060      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8061 
8062      for(i = 0; i <= 10; i++) {
8063         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8064         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8065      }
8066 
8067      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8068         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8069         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8070      }
8071 
8072      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8073      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8074 
8075      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8076      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8077 
8078      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8079      if(modeflag & DoubleScanMode) tempah |= 0x80;
8080      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8081 
8082   } else {
8083 
8084      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8085 
8086   }
8087 }
8088 
8089 /*********************************************/
8090 /*              SET CRT2 ECLK                */
8091 /*********************************************/
8092 
8093 static void
8094 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8095            unsigned short RefreshRateTableIndex)
8096 {
8097   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
8098   unsigned short clkbase, vclkindex = 0;
8099   unsigned char  sr2b, sr2c;
8100 
8101   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8102      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8103      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8104 	RefreshRateTableIndex--;
8105      }
8106      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8107                                     RefreshRateTableIndex);
8108      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8109   } else {
8110      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8111                                     RefreshRateTableIndex);
8112   }
8113 
8114   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8115   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8116 
8117   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8118      if(SiS_Pr->SiS_UseROM) {
8119 	if(ROMAddr[0x220] & 0x01) {
8120 	   sr2b = ROMAddr[0x227];
8121 	   sr2c = ROMAddr[0x228];
8122 	}
8123      }
8124   }
8125 
8126   clkbase = 0x02B;
8127   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8128      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8129 	clkbase += 3;
8130      }
8131   }
8132 
8133   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8134   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8135   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8136   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8137   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8138   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8139   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8140   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8141   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8142 }
8143 
8144 /*********************************************/
8145 /*           SET UP CHRONTEL CHIPS           */
8146 /*********************************************/
8147 
8148 static void
8149 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8150                unsigned short RefreshRateTableIndex)
8151 {
8152    unsigned short TVType, resindex;
8153    const struct SiS_CHTVRegData *CHTVRegData = NULL;
8154 
8155    if(ModeNo <= 0x13)
8156       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8157    else
8158       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8159 
8160    resindex &= 0x3F;
8161 
8162    TVType = 0;
8163    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8164    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8165       TVType += 2;
8166       if(SiS_Pr->SiS_ModeType > ModeVGA) {
8167 	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8168       }
8169       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8170 	 TVType = 4;
8171 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8172       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8173 	 TVType = 6;
8174 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8175       }
8176    }
8177 
8178    switch(TVType) {
8179       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8180       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8181       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8182       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8183       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8184       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8185       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8186       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8187       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8188       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8189    }
8190 
8191 
8192    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8193 
8194 #ifdef CONFIG_FB_SIS_300
8195 
8196       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8197 
8198       /* We don't support modes >800x600 */
8199       if (resindex > 5) return;
8200 
8201       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8202 	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8203 	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
8204       } else {
8205 	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8206 	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
8207       }
8208 
8209       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
8210       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
8211       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
8212       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
8213       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
8214 
8215       /* Set minimum flicker filter for Luma channel (SR1-0=00),
8216                 minimum text enhancement (S3-2=10),
8217    	        maximum flicker filter for Chroma channel (S5-4=10)
8218 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8219        */
8220       SiS_SetCH700x(SiS_Pr,0x01,0x28);
8221 
8222       /* Set video bandwidth
8223             High bandwidth Luma composite video filter(S0=1)
8224             low bandwidth Luma S-video filter (S2-1=00)
8225 	    disable peak filter in S-video channel (S3=0)
8226 	    high bandwidth Chroma Filter (S5-4=11)
8227 	    =00110001=0x31
8228       */
8229       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
8230 
8231       /* Register 0x3D does not exist in non-macrovision register map
8232             (Maybe this is a macrovision register?)
8233        */
8234 #ifndef SIS_CP
8235       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8236 #endif
8237 
8238       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8239              all other bits a read-only. Macrovision?
8240        */
8241       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8242 
8243       /* Register 0x11 only contains 3 writable bits (S0-S2) for
8244              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8245        */
8246       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8247 
8248       /* Clear DSEN
8249        */
8250       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8251 
8252       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
8253          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8254             if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
8255       	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8256                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
8257             } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
8258                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
8259                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8260                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8261                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8262                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8263                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8264                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8265                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8266                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
8267                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
8268             }
8269          } else {
8270             if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
8271                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8272                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8273             } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
8274 #if 0
8275                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8276                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
8277                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
8278                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8279                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8280                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8281                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8282                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8283                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
8284                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
8285 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8286 	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
8287                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8288             }
8289          }
8290       } else {						/* ---- PAL ---- */
8291 	/* We don't play around with FSCI in PAL mode */
8292 	SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
8293 	SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
8294       }
8295 
8296 #endif  /* 300 */
8297 
8298    } else {
8299 
8300       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8301 
8302 #ifdef CONFIG_FB_SIS_315
8303 
8304       unsigned short temp;
8305 
8306       /* We don't support modes >1024x768 */
8307       if (resindex > 6) return;
8308 
8309       temp = CHTVRegData[resindex].Reg[0];
8310       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8311       SiS_SetCH701x(SiS_Pr,0x00,temp);
8312 
8313       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8314       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8315       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8316       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8317       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8318       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8319 
8320       temp = CHTVRegData[resindex].Reg[7];
8321       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8322       SiS_SetCH701x(SiS_Pr,0x07,temp);
8323 
8324       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8325       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8326       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8327       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8328       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8329       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8330       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8331       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8332 
8333       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8334       /* D1 should be set for PAL, PAL-N and NTSC-J,
8335          but I won't do that for PAL unless somebody
8336 	 tells me to do so. Since the BIOS uses
8337 	 non-default CIV values and blacklevels,
8338 	 this might be compensated anyway.
8339        */
8340       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8341       SiS_SetCH701x(SiS_Pr,0x21,temp);
8342 
8343 #endif	/* 315 */
8344 
8345    }
8346 
8347 #ifdef SIS_CP
8348    SIS_CP_INIT301_CP3
8349 #endif
8350 
8351 }
8352 
8353 #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8354 
8355 void
8356 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8357 {
8358    unsigned short temp;
8359 
8360    /* Enable Chrontel 7019 LCD panel backlight */
8361    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8362       if(SiS_Pr->ChipType == SIS_740) {
8363 	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8364       } else {
8365 	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8366 	 temp |= 0x20;
8367 	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8368       }
8369    }
8370 }
8371 
8372 void
8373 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8374 {
8375    unsigned short temp;
8376 
8377    /* Disable Chrontel 7019 LCD panel backlight */
8378    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8379       temp = SiS_GetCH701x(SiS_Pr,0x66);
8380       temp &= 0xDF;
8381       SiS_SetCH701x(SiS_Pr,0x66,temp);
8382    }
8383 }
8384 
8385 static void
8386 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8387 {
8388   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8389   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8390   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8391   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8392   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8393   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8394   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8395   const unsigned char *tableptr = NULL;
8396   int i;
8397 
8398   /* Set up Power up/down timing */
8399 
8400   if(SiS_Pr->ChipType == SIS_740) {
8401      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8402 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8403 	else    			          tableptr = table1024_740;
8404      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8405 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8406 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8407 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8408         else					  tableptr = table1400_740;
8409      } else return;
8410   } else {
8411      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8412 	tableptr = table1024_650;
8413      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8414 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8415 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8416 	tableptr = table1400_650;
8417      } else return;
8418   }
8419 
8420   for(i=0; i<5; i++) {
8421      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8422   }
8423 }
8424 
8425 static void
8426 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8427 {
8428   const unsigned char *tableptr = NULL;
8429   unsigned short tempbh;
8430   int i;
8431   static const unsigned char regtable[] = {
8432 		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8433 		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8434   };
8435   static const unsigned char table1024_740[] = {
8436 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8437 		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8438   };
8439   static const unsigned char table1280_740[] = {
8440 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8441 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8442   };
8443   static const unsigned char table1400_740[] = {
8444 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8445 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8446   };
8447   static const unsigned char table1600_740[] = {
8448 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8449 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8450   };
8451   static const unsigned char table1024_650[] = {
8452 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8453 		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8454   };
8455   static const unsigned char table1280_650[] = {
8456 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8457 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8458   };
8459   static const unsigned char table1400_650[] = {
8460 		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8461 		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8462   };
8463   static const unsigned char table1600_650[] = {
8464 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8465 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8466   };
8467 
8468   if(SiS_Pr->ChipType == SIS_740) {
8469      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8470      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8471      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8472      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8473      else return;
8474   } else {
8475      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8476      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8477      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8478      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8479      else return;
8480   }
8481 
8482   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8483   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8484      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8485      if(tempbh == 0xc8) {
8486         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8487      } else if(tempbh == 0xdb) {
8488         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8489 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8490      } else if(tempbh == 0xde) {
8491         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8492      }
8493   }
8494 
8495   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8496   else     			  tempbh = 0x0c;
8497 
8498   for(i = 0; i < tempbh; i++) {
8499      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8500   }
8501   SiS_ChrontelPowerSequencing(SiS_Pr);
8502   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8503   tempbh |= 0xc0;
8504   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8505 
8506   if(SiS_Pr->ChipType == SIS_740) {
8507      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8508      tempbh &= 0xfb;
8509      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8510      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8511      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8512      tempbh |= 0x40;
8513      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8514      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8515      tempbh &= 0x3f;
8516      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8517   }
8518 }
8519 
8520 static void
8521 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8522 {
8523   unsigned char temp, temp1;
8524 
8525   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8526   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8527   temp = SiS_GetCH701x(SiS_Pr,0x47);
8528   temp &= 0x7f;	/* Use external VSYNC */
8529   SiS_SetCH701x(SiS_Pr,0x47,temp);
8530   SiS_LongDelay(SiS_Pr, 3);
8531   temp = SiS_GetCH701x(SiS_Pr,0x47);
8532   temp |= 0x80;	/* Use internal VSYNC */
8533   SiS_SetCH701x(SiS_Pr,0x47,temp);
8534   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8535 }
8536 
8537 static void
8538 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8539 {
8540   unsigned short temp;
8541 
8542   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8543      if(SiS_Pr->ChipType == SIS_740) {
8544         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8545         temp |= 0x04;	/* Invert XCLK phase */
8546         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8547      }
8548      if(SiS_IsYPbPr(SiS_Pr)) {
8549         temp = SiS_GetCH701x(SiS_Pr,0x01);
8550 	temp &= 0x3f;
8551 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8552 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8553      }
8554      if(SiS_IsChScart(SiS_Pr)) {
8555         temp = SiS_GetCH701x(SiS_Pr,0x01);
8556 	temp &= 0x3f;
8557 	temp |= 0xc0;	/* Enable SCART + CVBS */
8558 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8559      }
8560      if(SiS_Pr->ChipType == SIS_740) {
8561         SiS_ChrontelResetVSync(SiS_Pr);
8562         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8563      } else {
8564         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8565         temp = SiS_GetCH701x(SiS_Pr,0x49);
8566         if(SiS_IsYPbPr(SiS_Pr)) {
8567            temp = SiS_GetCH701x(SiS_Pr,0x73);
8568 	   temp |= 0x60;
8569 	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8570         }
8571         temp = SiS_GetCH701x(SiS_Pr,0x47);
8572         temp &= 0x7f;
8573         SiS_SetCH701x(SiS_Pr,0x47,temp);
8574         SiS_LongDelay(SiS_Pr, 2);
8575         temp = SiS_GetCH701x(SiS_Pr,0x47);
8576         temp |= 0x80;
8577         SiS_SetCH701x(SiS_Pr,0x47,temp);
8578      }
8579   }
8580 }
8581 
8582 static void
8583 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8584 {
8585   unsigned short temp;
8586 
8587   /* Complete power down of LVDS */
8588   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8589      if(SiS_Pr->ChipType == SIS_740) {
8590         SiS_LongDelay(SiS_Pr, 1);
8591 	SiS_GenericDelay(SiS_Pr, 5887);
8592 	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8593 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8594      } else {
8595         SiS_LongDelay(SiS_Pr, 2);
8596 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8597 	temp &= 0xfc;
8598 	SiS_SetCH701x(SiS_Pr,0x76,temp);
8599 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8600      }
8601   }
8602 }
8603 
8604 static void
8605 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8606 {
8607      unsigned short temp;
8608 
8609      if(SiS_Pr->ChipType == SIS_740) {
8610 
8611         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8612         temp &= 0x01;
8613         if(!temp) {
8614 
8615            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8616 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8617 	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8618 	   }
8619 
8620 	   /* Reset Chrontel 7019 datapath */
8621            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8622            SiS_LongDelay(SiS_Pr, 1);
8623            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8624 
8625 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8626 	      SiS_ChrontelResetVSync(SiS_Pr);
8627 	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8628 	   }
8629 
8630         } else {
8631 
8632 	   /* Clear/set/clear GPIO */
8633            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8634 	   temp &= 0xef;
8635 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8636 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8637 	   temp |= 0x10;
8638 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8639 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8640 	   temp &= 0xef;
8641 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8642 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8643 	   if(!temp) {
8644 	      SiS_SetCH701xForLCD(SiS_Pr);
8645 	   }
8646         }
8647 
8648      } else { /* 650 */
8649         /* Reset Chrontel 7019 datapath */
8650         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8651         SiS_LongDelay(SiS_Pr, 1);
8652         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8653      }
8654 }
8655 
8656 static void
8657 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8658 {
8659      unsigned short temp;
8660 
8661      if(SiS_Pr->ChipType == SIS_740) {
8662 
8663         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8664            SiS_ChrontelResetVSync(SiS_Pr);
8665         }
8666 
8667      } else {
8668 
8669         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8670         temp = SiS_GetCH701x(SiS_Pr,0x49);
8671         temp &= 1;
8672         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8673 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8674 	   temp &= 0x70;
8675 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8676 	   SiS_LongDelay(SiS_Pr, 3);
8677 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8678 	   temp |= 0x80;
8679 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8680         }
8681 
8682      }
8683 }
8684 
8685 static void
8686 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8687 {
8688      unsigned short temp,temp1;
8689 
8690      if(SiS_Pr->ChipType == SIS_740) {
8691 
8692         temp = SiS_GetCH701x(SiS_Pr,0x61);
8693         if(temp < 1) {
8694            temp++;
8695 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8696         }
8697         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8698         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8699         SiS_LongDelay(SiS_Pr, 1);
8700         SiS_GenericDelay(SiS_Pr, 5887);
8701 
8702      } else {  /* 650 */
8703 
8704         temp1 = 0;
8705         temp = SiS_GetCH701x(SiS_Pr,0x61);
8706         if(temp < 2) {
8707            temp++;
8708 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8709 	   temp1 = 1;
8710         }
8711         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8712         temp = SiS_GetCH701x(SiS_Pr,0x66);
8713         temp |= 0x5f;
8714         SiS_SetCH701x(SiS_Pr,0x66,temp);
8715         if(ModeNo > 0x13) {
8716            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8717 	      SiS_GenericDelay(SiS_Pr, 1023);
8718 	   } else {
8719 	      SiS_GenericDelay(SiS_Pr, 767);
8720 	   }
8721         } else {
8722            if(!temp1)
8723 	      SiS_GenericDelay(SiS_Pr, 767);
8724         }
8725         temp = SiS_GetCH701x(SiS_Pr,0x76);
8726         temp |= 0x03;
8727         SiS_SetCH701x(SiS_Pr,0x76,temp);
8728         temp = SiS_GetCH701x(SiS_Pr,0x66);
8729         temp &= 0x7f;
8730         SiS_SetCH701x(SiS_Pr,0x66,temp);
8731         SiS_LongDelay(SiS_Pr, 1);
8732 
8733      }
8734 }
8735 
8736 static void
8737 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8738 {
8739      unsigned short temp;
8740 
8741      SiS_LongDelay(SiS_Pr, 1);
8742 
8743      do {
8744        temp = SiS_GetCH701x(SiS_Pr,0x66);
8745        temp &= 0x04;  /* PLL stable? -> bail out */
8746        if(temp == 0x04) break;
8747 
8748        if(SiS_Pr->ChipType == SIS_740) {
8749           /* Power down LVDS output, PLL normal operation */
8750           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8751        }
8752 
8753        SiS_SetCH701xForLCD(SiS_Pr);
8754 
8755        temp = SiS_GetCH701x(SiS_Pr,0x76);
8756        temp &= 0xfb;  /* Reset PLL */
8757        SiS_SetCH701x(SiS_Pr,0x76,temp);
8758        SiS_LongDelay(SiS_Pr, 2);
8759        temp = SiS_GetCH701x(SiS_Pr,0x76);
8760        temp |= 0x04;  /* PLL normal operation */
8761        SiS_SetCH701x(SiS_Pr,0x76,temp);
8762        if(SiS_Pr->ChipType == SIS_740) {
8763           SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8764        } else {
8765           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8766        }
8767        SiS_LongDelay(SiS_Pr, 2);
8768     } while(0);
8769 
8770     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8771 }
8772 
8773 static void
8774 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8775 {
8776      unsigned short temp;
8777 
8778      temp = SiS_GetCH701x(SiS_Pr,0x03);
8779      temp |= 0x80;	/* Set datapath 1 to TV   */
8780      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8781      SiS_SetCH701x(SiS_Pr,0x03,temp);
8782 
8783      if(SiS_Pr->ChipType == SIS_740) {
8784 
8785         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8786         temp &= 0xfb;	/* Normal XCLK phase */
8787         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8788 
8789         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8790 
8791         temp = SiS_GetCH701x(SiS_Pr,0x64);
8792         temp |= 0x40;	/* ? Bit not defined */
8793         SiS_SetCH701x(SiS_Pr,0x64,temp);
8794 
8795         temp = SiS_GetCH701x(SiS_Pr,0x03);
8796         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8797         SiS_SetCH701x(SiS_Pr,0x03,temp);
8798 
8799 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8800 	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8801 	   SiS_LongDelay(SiS_Pr, 1);
8802 	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8803 	   SiS_ChrontelResetDB(SiS_Pr);
8804 	   SiS_ChrontelDoSomething2(SiS_Pr);
8805 	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8806 	} else {
8807            temp = SiS_GetCH701x(SiS_Pr,0x66);
8808            if(temp != 0x45) {
8809               SiS_ChrontelResetDB(SiS_Pr);
8810               SiS_ChrontelDoSomething2(SiS_Pr);
8811               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8812            }
8813 	}
8814 
8815      } else { /* 650 */
8816 
8817         SiS_ChrontelResetDB(SiS_Pr);
8818         SiS_ChrontelDoSomething2(SiS_Pr);
8819         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8820         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8821         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8822 
8823      }
8824 
8825 }
8826 #endif  /* 315 series  */
8827 
8828 /*********************************************/
8829 /*      MAIN: SET CRT2 REGISTER GROUP        */
8830 /*********************************************/
8831 
8832 bool
8833 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8834 {
8835 #ifdef CONFIG_FB_SIS_300
8836    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8837 #endif
8838    unsigned short ModeIdIndex, RefreshRateTableIndex;
8839 
8840    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8841 
8842    if(!SiS_Pr->UseCustomMode) {
8843       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8844    } else {
8845       ModeIdIndex = 0;
8846    }
8847 
8848    /* Used for shifting CR33 */
8849    SiS_Pr->SiS_SelectCRT2Rate = 4;
8850 
8851    SiS_UnLockCRT2(SiS_Pr);
8852 
8853    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8854 
8855    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8856 
8857    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8858       SiS_DisableBridge(SiS_Pr);
8859       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8860          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8861       }
8862       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8863    }
8864 
8865    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8866       SiS_LockCRT2(SiS_Pr);
8867       SiS_DisplayOn(SiS_Pr);
8868       return true;
8869    }
8870 
8871    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8872 
8873    /* Set up Panel Link for LVDS and LCDA */
8874    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8875    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8876        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8877        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8878       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8879    }
8880 
8881    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8882       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8883    }
8884 
8885    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8886 
8887       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8888 
8889 	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890 #ifdef CONFIG_FB_SIS_315
8891 	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8892 #endif
8893 	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8894 	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8895 #ifdef CONFIG_FB_SIS_315
8896 	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8897 #endif
8898 	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8899 
8900 	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8901 
8902 	 /* For 301BDH (Panel link initialization): */
8903 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8904 
8905 	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8906 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8907 		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8908 	       }
8909             }
8910 	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8911 	 }
8912       }
8913 
8914    } else {
8915 
8916       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8917 
8918       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8919 
8920       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8921 
8922       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8923 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8924 	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8925 	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8926 #ifdef CONFIG_FB_SIS_315
8927 		  SiS_SetCH701xForLCD(SiS_Pr);
8928 #endif
8929 	       }
8930 	    }
8931 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8932 	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8933 	    }
8934 	 }
8935       }
8936 
8937    }
8938 
8939 #ifdef CONFIG_FB_SIS_300
8940    if(SiS_Pr->ChipType < SIS_315H) {
8941       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8942 	 if(SiS_Pr->SiS_UseOEM) {
8943 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8944 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8945 		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8946 	       }
8947 	    } else {
8948 	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8949 	    }
8950 	 }
8951 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8952 	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8953 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8954 	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8955 	    }
8956 	    SiS_DisplayOn(SiS_Pr);
8957          }
8958       }
8959    }
8960 #endif
8961 
8962 #ifdef CONFIG_FB_SIS_315
8963    if(SiS_Pr->ChipType >= SIS_315H) {
8964       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8965 	 if(SiS_Pr->ChipType < SIS_661) {
8966 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8967 	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8968 	 } else {
8969 	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8970 	 }
8971 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8972       }
8973    }
8974 #endif
8975 
8976    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8977       SiS_EnableBridge(SiS_Pr);
8978    }
8979 
8980    SiS_DisplayOn(SiS_Pr);
8981 
8982    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8983       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8984 	 /* Disable LCD panel when using TV */
8985 	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8986       } else {
8987 	 /* Disable TV when using LCD */
8988 	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8989       }
8990    }
8991 
8992    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8993       SiS_LockCRT2(SiS_Pr);
8994    }
8995 
8996    return true;
8997 }
8998 
8999 
9000 /*********************************************/
9001 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
9002 /*********************************************/
9003 
9004 void
9005 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9006 {
9007   /* Switch on LCD backlight on SiS30xLV */
9008   SiS_DDC2Delay(SiS_Pr,0xff00);
9009   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9010      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9011      SiS_WaitVBRetrace(SiS_Pr);
9012   }
9013   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9014      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9015   }
9016 }
9017 
9018 void
9019 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9020 {
9021   /* Switch off LCD backlight on SiS30xLV */
9022   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9023   SiS_DDC2Delay(SiS_Pr,0xff00);
9024 }
9025 
9026 /*********************************************/
9027 /*          DDC RELATED FUNCTIONS            */
9028 /*********************************************/
9029 
9030 static void
9031 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9032 {
9033   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9034   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
9035   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9036      SiS_Pr->SiS_DDC_NData &= 0x0f;
9037      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
9038   }
9039 }
9040 
9041 #ifdef CONFIG_FB_SIS_300
9042 static unsigned char *
9043 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9044 {
9045   int i, j, num;
9046   unsigned short tempah,temp;
9047   unsigned char *mydataptr;
9048 
9049   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9050      mydataptr = dataptr;
9051      num = *mydataptr++;
9052      if(!num) return mydataptr;
9053      if(i) {
9054         SiS_SetStop(SiS_Pr);
9055 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9056      }
9057      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
9058      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9059      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
9060      if(temp) continue;				/*    (ERROR: no ack) */
9061      tempah = *mydataptr++;
9062      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
9063      if(temp) continue;				/*    (ERROR: no ack) */
9064      for(j=0; j<num; j++) {
9065         tempah = *mydataptr++;
9066         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9067 	if(temp) break;
9068      }
9069      if(temp) continue;
9070      if(SiS_SetStop(SiS_Pr)) continue;
9071      return mydataptr;
9072   }
9073   return NULL;
9074 }
9075 
9076 static bool
9077 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9078 {
9079   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
9080   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9081   SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
9082   SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
9083   SiS_SetupDDCN(SiS_Pr);
9084 
9085   SiS_SetSwitchDDC2(SiS_Pr);
9086 
9087   while(*dataptr) {
9088      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9089      if(!dataptr) return false;
9090   }
9091   return true;
9092 }
9093 #endif
9094 
9095 /* The Chrontel 700x is connected to the 630/730 via
9096  * the 630/730's DDC/I2C port.
9097  *
9098  * On 630(S)T chipset, the index changed from 0x11 to
9099  * 0x0a, possibly for working around the DDC problems
9100  */
9101 
9102 static bool
9103 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9104 {
9105   unsigned short temp, i;
9106 
9107   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9108      if(i) {
9109 	SiS_SetStop(SiS_Pr);
9110 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9111      }
9112      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9113      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9114      if(temp) continue;							/*    (ERROR: no ack) */
9115      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
9116      if(temp) continue;							/*    (ERROR: no ack) */
9117      temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
9118      if(temp) continue;							/*    (ERROR: no ack) */
9119      if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
9120      SiS_Pr->SiS_ChrontelInit = 1;
9121      return true;
9122   }
9123   return false;
9124 }
9125 
9126 /* Write to Chrontel 700x */
9127 void
9128 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9129 {
9130   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9131 
9132   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9133 
9134   if(!(SiS_Pr->SiS_ChrontelInit)) {
9135      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9136      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9137      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9138      SiS_SetupDDCN(SiS_Pr);
9139   }
9140 
9141   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9142       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9143      SiS_Pr->SiS_DDC_Index = 0x0a;
9144      SiS_Pr->SiS_DDC_Data  = 0x80;
9145      SiS_Pr->SiS_DDC_Clk   = 0x40;
9146      SiS_SetupDDCN(SiS_Pr);
9147 
9148      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9149   }
9150 }
9151 
9152 /* Write to Chrontel 701x */
9153 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9154 void
9155 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9156 {
9157   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9158   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9159   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9160   SiS_SetupDDCN(SiS_Pr);
9161   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
9162   SiS_SetChReg(SiS_Pr, reg, val, 0);
9163 }
9164 
9165 static
9166 void
9167 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9168 {
9169   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9170      SiS_SetCH700x(SiS_Pr, reg, val);
9171   else
9172      SiS_SetCH701x(SiS_Pr, reg, val);
9173 }
9174 
9175 static unsigned short
9176 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9177 {
9178   unsigned short tempah, temp, i;
9179 
9180   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
9181      if(i) {
9182 	SiS_SetStop(SiS_Pr);
9183 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9184      }
9185      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9186      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9187      if(temp) continue;							/*        (ERROR: no ack) */
9188      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
9189      if(temp) continue;							/*        (ERROR: no ack) */
9190      if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
9191      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9192      if(temp) continue;							/*        (ERROR: no ack) */
9193      tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
9194      if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
9195      SiS_Pr->SiS_ChrontelInit = 1;
9196      return tempah;
9197   }
9198   return 0xFFFF;
9199 }
9200 
9201 /* Read from Chrontel 700x */
9202 /* Parameter is [Register no (S7-S0)] */
9203 unsigned short
9204 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9205 {
9206   unsigned short result;
9207 
9208   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9209 
9210   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9211 
9212   if(!(SiS_Pr->SiS_ChrontelInit)) {
9213      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9214      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9215      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9216      SiS_SetupDDCN(SiS_Pr);
9217   }
9218 
9219   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9220 
9221   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9222       (!SiS_Pr->SiS_ChrontelInit) ) {
9223 
9224      SiS_Pr->SiS_DDC_Index = 0x0a;
9225      SiS_Pr->SiS_DDC_Data  = 0x80;
9226      SiS_Pr->SiS_DDC_Clk   = 0x40;
9227      SiS_SetupDDCN(SiS_Pr);
9228 
9229      result = SiS_GetChReg(SiS_Pr,0x80);
9230   }
9231   return result;
9232 }
9233 
9234 /* Read from Chrontel 701x */
9235 /* Parameter is [Register no (S7-S0)] */
9236 unsigned short
9237 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9238 {
9239   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9240   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9241   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9242   SiS_SetupDDCN(SiS_Pr);
9243   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9244 
9245   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9246 
9247   return SiS_GetChReg(SiS_Pr,0);
9248 }
9249 
9250 /* Read from Chrontel 70xx */
9251 /* Parameter is [Register no (S7-S0)] */
9252 static
9253 unsigned short
9254 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9255 {
9256   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9257      return SiS_GetCH700x(SiS_Pr, tempbx);
9258   else
9259      return SiS_GetCH701x(SiS_Pr, tempbx);
9260 }
9261 
9262 void
9263 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9264 		unsigned char myor, unsigned short myand)
9265 {
9266   unsigned short tempbl;
9267 
9268   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9269   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9270 }
9271 
9272 /* Our own DDC functions */
9273 static
9274 unsigned short
9275 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9276                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9277 		unsigned int VBFlags2)
9278 {
9279      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9280      unsigned char flag, cr32;
9281      unsigned short        temp = 0, myadaptnum = adaptnum;
9282 
9283      if(adaptnum != 0) {
9284 	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9285 	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9286      }
9287 
9288      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9289 
9290      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9291 
9292      SiS_Pr->SiS_DDC_SecAddr = 0;
9293      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9294      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9295      SiS_Pr->SiS_DDC_Index = 0x11;
9296      flag = 0xff;
9297 
9298      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9299 
9300 #if 0
9301      if(VBFlags2 & VB2_SISBRIDGE) {
9302 	if(myadaptnum == 0) {
9303 	   if(!(cr32 & 0x20)) {
9304 	      myadaptnum = 2;
9305 	      if(!(cr32 & 0x10)) {
9306 	         myadaptnum = 1;
9307 		 if(!(cr32 & 0x08)) {
9308 		    myadaptnum = 0;
9309 		 }
9310 	      }
9311 	   }
9312         }
9313      }
9314 #endif
9315 
9316      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9317 
9318         if(myadaptnum != 0) {
9319 	   flag = 0;
9320 	   if(VBFlags2 & VB2_SISBRIDGE) {
9321 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9322               SiS_Pr->SiS_DDC_Index = 0x0f;
9323 	   }
9324         }
9325 
9326 	if(!(VBFlags2 & VB2_301)) {
9327 	   if((cr32 & 0x80) && (checkcr32)) {
9328               if(myadaptnum >= 1) {
9329 	         if(!(cr32 & 0x08)) {
9330 		     myadaptnum = 1;
9331 		     if(!(cr32 & 0x10)) return 0xFFFF;
9332                  }
9333 	      }
9334 	   }
9335 	}
9336 
9337 	temp = 4 - (myadaptnum * 2);
9338 	if(flag) temp = 0;
9339 
9340      } else {						/* 315/330 series */
9341 
9342 	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9343 
9344 	if(VBFlags2 & VB2_SISBRIDGE) {
9345 	   if(myadaptnum == 2) {
9346 	      myadaptnum = 1;
9347 	   }
9348 	}
9349 
9350         if(myadaptnum == 1) {
9351 	   flag = 0;
9352 	   if(VBFlags2 & VB2_SISBRIDGE) {
9353 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9354               SiS_Pr->SiS_DDC_Index = 0x0f;
9355 	   }
9356         }
9357 
9358         if((cr32 & 0x80) && (checkcr32)) {
9359            if(myadaptnum >= 1) {
9360 	      if(!(cr32 & 0x08)) {
9361 	         myadaptnum = 1;
9362 		 if(!(cr32 & 0x10)) return 0xFFFF;
9363 	      }
9364 	   }
9365         }
9366 
9367         temp = myadaptnum;
9368         if(myadaptnum == 1) {
9369            temp = 0;
9370 	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9371         }
9372 
9373 	if(flag) temp = 0;
9374     }
9375 
9376     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9377     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9378 
9379     SiS_SetupDDCN(SiS_Pr);
9380 
9381     return 0;
9382 }
9383 
9384 static unsigned short
9385 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9386 {
9387    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9388    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9389       return 0xFFFF;
9390    }
9391    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9392       return 0xFFFF;
9393    }
9394    return 0;
9395 }
9396 
9397 static unsigned short
9398 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9399 {
9400    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9401    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9402       return 0xFFFF;
9403    }
9404    return 0;
9405 }
9406 
9407 static unsigned short
9408 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9409 {
9410    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9411    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9412    return 0;
9413 }
9414 
9415 static void
9416 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9417 {
9418    SiS_SetSCLKLow(SiS_Pr);
9419    if(yesno) {
9420       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9421 		      SiS_Pr->SiS_DDC_Index,
9422 		      SiS_Pr->SiS_DDC_NData,
9423 		      SiS_Pr->SiS_DDC_Data);
9424    } else {
9425       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9426 		      SiS_Pr->SiS_DDC_Index,
9427 		      SiS_Pr->SiS_DDC_NData,
9428 		      0);
9429    }
9430    SiS_SetSCLKHigh(SiS_Pr);
9431 }
9432 
9433 static unsigned short
9434 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9435 {
9436     unsigned char mask, value;
9437     unsigned short  temp, ret=0;
9438     bool failed = false;
9439 
9440     SiS_SetSwitchDDC2(SiS_Pr);
9441     if(SiS_PrepareDDC(SiS_Pr)) {
9442          SiS_SetStop(SiS_Pr);
9443          return 0xFFFF;
9444     }
9445     mask = 0xf0;
9446     value = 0x20;
9447     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9448        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9449        SiS_SendACK(SiS_Pr, 0);
9450        if(temp == 0) {
9451            mask = 0xff;
9452 	   value = 0xff;
9453        } else {
9454            failed = true;
9455 	   ret = 0xFFFF;
9456        }
9457     }
9458     if(!failed) {
9459        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9460        SiS_SendACK(SiS_Pr, 1);
9461        temp &= mask;
9462        if(temp == value) ret = 0;
9463        else {
9464           ret = 0xFFFF;
9465           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9466              if(temp == 0x30) ret = 0;
9467           }
9468        }
9469     }
9470     SiS_SetStop(SiS_Pr);
9471     return ret;
9472 }
9473 
9474 static
9475 unsigned short
9476 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9477 {
9478    unsigned short flag;
9479 
9480    flag = 0x180;
9481    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9482    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9483    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9484    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9485    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9486    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9487    if(!(flag & 0x1a)) flag = 0;
9488    return flag;
9489 }
9490 
9491 static
9492 unsigned short
9493 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9494 {
9495    unsigned short flag, length, i;
9496    unsigned char chksum,gotcha;
9497 
9498    if(DDCdatatype > 4) return 0xFFFF;
9499 
9500    flag = 0;
9501    SiS_SetSwitchDDC2(SiS_Pr);
9502    if(!(SiS_PrepareDDC(SiS_Pr))) {
9503       length = 127;
9504       if(DDCdatatype != 1) length = 255;
9505       chksum = 0;
9506       gotcha = 0;
9507       for(i=0; i<length; i++) {
9508 	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9509 	 chksum += buffer[i];
9510 	 gotcha |= buffer[i];
9511 	 SiS_SendACK(SiS_Pr, 0);
9512       }
9513       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9514       chksum += buffer[i];
9515       SiS_SendACK(SiS_Pr, 1);
9516       if(gotcha) flag = (unsigned short)chksum;
9517       else flag = 0xFFFF;
9518    } else {
9519       flag = 0xFFFF;
9520    }
9521    SiS_SetStop(SiS_Pr);
9522    return flag;
9523 }
9524 
9525 /* Our private DDC functions
9526 
9527    It complies somewhat with the corresponding VESA function
9528    in arguments and return values.
9529 
9530    Since this is probably called before the mode is changed,
9531    we use our pre-detected pSiS-values instead of SiS_Pr as
9532    regards chipset and video bridge type.
9533 
9534    Arguments:
9535        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9536                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9537 		 LCDA is CRT1, but DDC is read from CRT2 port.
9538        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9539        buffer: ptr to 256 data bytes which will be filled with read data.
9540 
9541    Returns 0xFFFF if error, otherwise
9542        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9543        if DDCdatatype = 0:  Returns supported DDC modes
9544 
9545  */
9546 unsigned short
9547 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9548               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9549 	      unsigned int VBFlags2)
9550 {
9551    unsigned char  sr1f, cr17=1;
9552    unsigned short result;
9553 
9554    if(adaptnum > 2)
9555       return 0xFFFF;
9556 
9557    if(DDCdatatype > 4)
9558       return 0xFFFF;
9559 
9560    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9561       return 0xFFFF;
9562 
9563    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9564       return 0xFFFF;
9565 
9566    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9567    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9568    if(VGAEngine == SIS_300_VGA) {
9569       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9570       if(!cr17) {
9571          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9572          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9573          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9574       }
9575    }
9576    if((sr1f) || (!cr17)) {
9577       SiS_WaitRetrace1(SiS_Pr);
9578       SiS_WaitRetrace1(SiS_Pr);
9579       SiS_WaitRetrace1(SiS_Pr);
9580       SiS_WaitRetrace1(SiS_Pr);
9581    }
9582 
9583    if(DDCdatatype == 0) {
9584       result = SiS_ProbeDDC(SiS_Pr);
9585    } else {
9586       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9587       if((!result) && (DDCdatatype == 1)) {
9588          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9589 	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9590 	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9591 	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9592 	    (buffer[0x12] == 1)) {
9593 	    if(!SiS_Pr->DDCPortMixup) {
9594 	       if(adaptnum == 1) {
9595 	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9596 	       } else {
9597 	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9598 	       }
9599 	    }
9600 	 }
9601       }
9602    }
9603    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9604    if(VGAEngine == SIS_300_VGA) {
9605       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9606    }
9607    return result;
9608 }
9609 
9610 /* Generic I2C functions for Chrontel & DDC --------- */
9611 
9612 static void
9613 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9614 {
9615   SiS_SetSCLKHigh(SiS_Pr);
9616   SiS_WaitRetrace1(SiS_Pr);
9617 
9618   SiS_SetSCLKLow(SiS_Pr);
9619   SiS_WaitRetrace1(SiS_Pr);
9620 }
9621 
9622 unsigned short
9623 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9624 {
9625    SiS_WaitRetrace1(SiS_Pr);
9626    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9627 }
9628 
9629 /* Set I2C start condition */
9630 /* This is done by a SD high-to-low transition while SC is high */
9631 static unsigned short
9632 SiS_SetStart(struct SiS_Private *SiS_Pr)
9633 {
9634   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9635   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9636 		  SiS_Pr->SiS_DDC_Index,
9637 		  SiS_Pr->SiS_DDC_NData,
9638 		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9639   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9640   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9641 		  SiS_Pr->SiS_DDC_Index,
9642 		  SiS_Pr->SiS_DDC_NData,
9643 		  0x00);					/* SD->low = start condition */
9644   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9645   return 0;
9646 }
9647 
9648 /* Set I2C stop condition */
9649 /* This is done by a SD low-to-high transition while SC is high */
9650 static unsigned short
9651 SiS_SetStop(struct SiS_Private *SiS_Pr)
9652 {
9653   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9654   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9655 		  SiS_Pr->SiS_DDC_Index,
9656 		  SiS_Pr->SiS_DDC_NData,
9657 		  0x00);					/* SD->low   */
9658   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9659   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9660 		  SiS_Pr->SiS_DDC_Index,
9661 		  SiS_Pr->SiS_DDC_NData,
9662 		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9663   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9664   return 0;
9665 }
9666 
9667 /* Write 8 bits of data */
9668 static unsigned short
9669 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9670 {
9671   unsigned short i,flag,temp;
9672 
9673   flag = 0x80;
9674   for(i = 0; i < 8; i++) {
9675     SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9676     if(tempax & flag) {
9677       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9678 		      SiS_Pr->SiS_DDC_Index,
9679 		      SiS_Pr->SiS_DDC_NData,
9680 		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9681     } else {
9682       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9683 		      SiS_Pr->SiS_DDC_Index,
9684 		      SiS_Pr->SiS_DDC_NData,
9685 		      0x00);					/* Write bit (0) to SD */
9686     }
9687     SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9688     flag >>= 1;
9689   }
9690   temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9691   return temp;
9692 }
9693 
9694 static unsigned short
9695 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9696 {
9697   unsigned short i, temp, getdata;
9698 
9699   getdata = 0;
9700   for(i = 0; i < 8; i++) {
9701     getdata <<= 1;
9702     SiS_SetSCLKLow(SiS_Pr);
9703     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9704 		    SiS_Pr->SiS_DDC_Index,
9705 		    SiS_Pr->SiS_DDC_NData,
9706 		    SiS_Pr->SiS_DDC_Data);
9707     SiS_SetSCLKHigh(SiS_Pr);
9708     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9709     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9710   }
9711   return getdata;
9712 }
9713 
9714 static unsigned short
9715 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9716 {
9717   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9718 		  SiS_Pr->SiS_DDC_Index,
9719 		  SiS_Pr->SiS_DDC_NClk,
9720 		  0x00);					/* SetSCLKLow()  */
9721   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9722   return 0;
9723 }
9724 
9725 static unsigned short
9726 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9727 {
9728   unsigned short temp, watchdog=1000;
9729 
9730   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9731 		  SiS_Pr->SiS_DDC_Index,
9732 		  SiS_Pr->SiS_DDC_NClk,
9733 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9734   do {
9735     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9736   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9737   if (!watchdog) {
9738   	return 0xFFFF;
9739   }
9740   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9741   return 0;
9742 }
9743 
9744 /* Check I2C acknowledge */
9745 /* Returns 0 if ack ok, non-0 if ack not ok */
9746 static unsigned short
9747 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9748 {
9749   unsigned short tempah;
9750 
9751   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9752   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9753 		  SiS_Pr->SiS_DDC_Index,
9754 		  SiS_Pr->SiS_DDC_NData,
9755 		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9756   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9757   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9758   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9759   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9760   return 0;
9761 }
9762 
9763 /* End of I2C functions ----------------------- */
9764 
9765 
9766 /* =============== SiS 315/330 O.E.M. ================= */
9767 
9768 #ifdef CONFIG_FB_SIS_315
9769 
9770 static unsigned short
9771 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9772 {
9773   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9774   unsigned short romptr;
9775 
9776   if(SiS_Pr->ChipType < SIS_330) {
9777      romptr = SISGETROMW(0x128);
9778      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9779         romptr = SISGETROMW(0x12a);
9780   } else {
9781      romptr = SISGETROMW(0x1a8);
9782      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9783         romptr = SISGETROMW(0x1aa);
9784   }
9785   return romptr;
9786 }
9787 
9788 static unsigned short
9789 GetLCDromptr(struct SiS_Private *SiS_Pr)
9790 {
9791   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9792   unsigned short romptr;
9793 
9794   if(SiS_Pr->ChipType < SIS_330) {
9795      romptr = SISGETROMW(0x120);
9796      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9797         romptr = SISGETROMW(0x122);
9798   } else {
9799      romptr = SISGETROMW(0x1a0);
9800      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9801         romptr = SISGETROMW(0x1a2);
9802   }
9803   return romptr;
9804 }
9805 
9806 static unsigned short
9807 GetTVromptr(struct SiS_Private *SiS_Pr)
9808 {
9809   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9810   unsigned short romptr;
9811 
9812   if(SiS_Pr->ChipType < SIS_330) {
9813      romptr = SISGETROMW(0x114);
9814      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9815         romptr = SISGETROMW(0x11a);
9816   } else {
9817      romptr = SISGETROMW(0x194);
9818      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9819         romptr = SISGETROMW(0x19a);
9820   }
9821   return romptr;
9822 }
9823 
9824 static unsigned short
9825 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9826 {
9827   unsigned short index;
9828 
9829   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9830      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9831         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9832 	   index >>= 4;
9833 	   index *= 3;
9834 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9835            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9836            return index;
9837 	}
9838      }
9839   }
9840 
9841   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9842   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9843   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9844      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9845      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9846   } else {
9847      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9848   }
9849   index--;
9850   index *= 3;
9851   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9852   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9853   return index;
9854 }
9855 
9856 static unsigned short
9857 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9858 {
9859   unsigned short index;
9860 
9861   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9862   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9863   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9864   return index;
9865 }
9866 
9867 static unsigned short
9868 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9869 {
9870   unsigned short index;
9871 
9872   index = 0;
9873   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9874   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9875 
9876   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9877 
9878   index <<= 1;
9879 
9880   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9881      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9882      index++;
9883   }
9884 
9885   return index;
9886 }
9887 
9888 static unsigned int
9889 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9890 {
9891    unsigned short index = 0, temp = 0;
9892 
9893    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9894    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9895    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9896    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9897    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9898       index = 4;
9899       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9900       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9901    }
9902 
9903    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9904       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9905          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9906 	 index += addme;
9907 	 temp++;
9908       }
9909       temp += 0x0100;
9910    }
9911    return (unsigned int)(index | (temp << 16));
9912 }
9913 
9914 static unsigned int
9915 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9916 {
9917    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9918 }
9919 
9920 #if 0
9921 static unsigned int
9922 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9923 {
9924    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9925 }
9926 #endif
9927 
9928 static int
9929 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9930 {
9931    int index = 0;
9932 
9933    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9934    if(SiS_Pr->SiS_ROMNew) {
9935       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9936       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9937       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9938       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9939    } else {
9940       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9941       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9942       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9943       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9944    }
9945 
9946    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9947 
9948    return index;
9949 }
9950 
9951 static void
9952 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9953 {
9954   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9955   unsigned short delay=0,index,myindex,temp,romptr=0;
9956   bool dochiptest = true;
9957 
9958   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9959      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9960   } else {
9961      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9962   }
9963 
9964   /* Find delay (from ROM, internal tables, PCI subsystem) */
9965 
9966   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9967 
9968      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9969         romptr = GetRAMDACromptr(SiS_Pr);
9970      }
9971      if(romptr) delay = ROMAddr[romptr];
9972      else {
9973         delay = 0x04;
9974         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9975 	   if(IS_SIS650) {
9976 	      delay = 0x0a;
9977 	   } else if(IS_SIS740) {
9978 	      delay = 0x00;
9979 	   } else {
9980 	      delay = 0x0c;
9981 	   }
9982 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9983            delay = 0x00;
9984 	}
9985      }
9986 
9987   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9988 
9989      bool gotitfrompci = false;
9990 
9991      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9992 
9993      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9994 	if(SiS_Pr->PDC != -1) {
9995            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9996 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9997 	   return;
9998 	}
9999      } else {
10000 	if(SiS_Pr->PDCA != -1) {
10001 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10002 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10003 	   return;
10004 	}
10005      }
10006 
10007      /* Custom Panel? */
10008 
10009      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10010         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10011 	   delay = 0x00;
10012 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10013 	      delay = 0x20;
10014 	   }
10015 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10016 	} else {
10017 	   delay = 0x0c;
10018 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10019 	      delay = 0x03;
10020 	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10021 	         delay = 0x00;
10022 	      }
10023 	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10024 	      if(IS_SIS740) delay = 0x01;
10025 	      else          delay = 0x03;
10026 	   }
10027 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10028 	}
10029         return;
10030      }
10031 
10032      /* This is a piece of typical SiS crap: They code the OEM LCD
10033       * delay into the code, at no defined place in the BIOS.
10034       * We now have to start doing a PCI subsystem check here.
10035       */
10036 
10037      switch(SiS_Pr->SiS_CustomT) {
10038      case CUT_COMPAQ1280:
10039      case CUT_COMPAQ12802:
10040 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10041 	   gotitfrompci = true;
10042 	   dochiptest = false;
10043 	   delay = 0x03;
10044 	}
10045 	break;
10046      case CUT_CLEVO1400:
10047      case CUT_CLEVO14002:
10048 	gotitfrompci = true;
10049 	dochiptest = false;
10050 	delay = 0x02;
10051 	break;
10052      case CUT_CLEVO1024:
10053      case CUT_CLEVO10242:
10054         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10055 	   gotitfrompci = true;
10056 	   dochiptest = false;
10057 	   delay = 0x33;
10058 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10059 	   delay &= 0x0f;
10060 	}
10061 	break;
10062      }
10063 
10064      /* Could we find it through the PCI ID? If no, use ROM or table */
10065 
10066      if(!gotitfrompci) {
10067 
10068         index = GetLCDPtrIndexBIOS(SiS_Pr);
10069         myindex = GetLCDPtrIndex(SiS_Pr);
10070 
10071         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10072 
10073            if(SiS_IsNotM650orLater(SiS_Pr)) {
10074 
10075               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10076 	         /* Always use the second pointer on 650; some BIOSes */
10077                  /* still carry old 301 data at the first location    */
10078 	         /* romptr = SISGETROMW(0x120);                       */
10079 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10080 	         romptr = SISGETROMW(0x122);
10081 	         if(!romptr) return;
10082 	         delay = ROMAddr[(romptr + index)];
10083 	      } else {
10084                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10085 	      }
10086 
10087           } else {
10088 
10089              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10090 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10091 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10092 
10093           }
10094 
10095         } else if(SiS_Pr->SiS_UseROM 			      &&
10096 		  (!(SiS_Pr->SiS_ROMNew))		      &&
10097 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10098 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10099 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
10100 		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
10101 		  ((romptr = GetLCDromptr(SiS_Pr)))) {
10102 
10103 	   /* Data for 1280x1024 wrong in 301B BIOS */
10104 	   /* Data for 1600x1200 wrong in 301C BIOS */
10105 	   delay = ROMAddr[(romptr + index)];
10106 
10107         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10108 
10109 	   if(IS_SIS740) delay = 0x03;
10110 	   else          delay = 0x00;
10111 
10112 	} else {
10113 
10114            delay = SiS310_LCDDelayCompensation_301[myindex];
10115 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10116 	      if(IS_SIS740) delay = 0x01;
10117 	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10118 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10119 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10120 	      if(IS_SIS740) delay = 0x01;  /* ? */
10121 	      else          delay = 0x03;
10122 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10123 	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10124 	      if(IS_SIS740) delay = 0x01;
10125 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10126 	   }
10127 
10128         }
10129 
10130      }  /* got it from PCI */
10131 
10132      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10133 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10134 	dochiptest = false;
10135      }
10136 
10137   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
10138 
10139      index = GetTVPtrIndex(SiS_Pr);
10140 
10141      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10142 
10143         if(SiS_IsNotM650orLater(SiS_Pr)) {
10144 
10145            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10146 	      /* Always use the second pointer on 650; some BIOSes */
10147               /* still carry old 301 data at the first location    */
10148               /* romptr = SISGETROMW(0x114);			   */
10149 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10150 	      romptr = SISGETROMW(0x11a);
10151 	      if(!romptr) return;
10152 	      delay = ROMAddr[romptr + index];
10153 
10154 	   } else {
10155 
10156 	      delay = SiS310_TVDelayCompensation_301B[index];
10157 
10158 	   }
10159 
10160         } else {
10161 
10162            switch(SiS_Pr->SiS_CustomT) {
10163 	   case CUT_COMPAQ1280:
10164 	   case CUT_COMPAQ12802:
10165 	   case CUT_CLEVO1400:
10166 	   case CUT_CLEVO14002:
10167 	      delay = 0x02;
10168 	      dochiptest = false;
10169 	      break;
10170 	   case CUT_CLEVO1024:
10171 	   case CUT_CLEVO10242:
10172 	      delay = 0x03;
10173 	      dochiptest = false;
10174    	      break;
10175 	   default:
10176               delay = SiS310_TVDelayCompensation_651301LV[index];
10177 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10178 	         delay = SiS310_TVDelayCompensation_651302LV[index];
10179 	      }
10180 	   }
10181         }
10182 
10183      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10184 
10185         romptr = GetTVromptr(SiS_Pr);
10186 	if(!romptr) return;
10187 	delay = ROMAddr[romptr + index];
10188 
10189      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10190 
10191         delay = SiS310_TVDelayCompensation_LVDS[index];
10192 
10193      } else {
10194 
10195 	delay = SiS310_TVDelayCompensation_301[index];
10196         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10197 	   if(IS_SIS740) {
10198 	      delay = SiS310_TVDelayCompensation_740301B[index];
10199 	      /* LV: use 301 data? BIOS bug? */
10200 	   } else {
10201               delay = SiS310_TVDelayCompensation_301B[index];
10202 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10203 	   }
10204 	}
10205 
10206      }
10207 
10208      if(SiS_LCDAEnabled(SiS_Pr)) {
10209 	delay &= 0x0f;
10210 	dochiptest = false;
10211      }
10212 
10213   } else return;
10214 
10215   /* Write delay */
10216 
10217   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10218 
10219      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10220 
10221         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10222         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
10223 	   delay &= 0x0f;
10224 	   delay |= 0xb0;
10225         } else if(temp == 6) {
10226            delay &= 0x0f;
10227 	   delay |= 0xc0;
10228         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
10229 	   delay = 0x35;
10230         }
10231         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10232 
10233      } else {
10234 
10235         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10236 
10237      }
10238 
10239   } else {  /* LVDS */
10240 
10241      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10242         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10243      } else {
10244         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10245            delay <<= 4;
10246            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10247         } else {
10248            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10249         }
10250      }
10251 
10252   }
10253 
10254 }
10255 
10256 static void
10257 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10258 {
10259   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10260   unsigned short index,temp,temp1,romptr=0;
10261 
10262   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10263 
10264   if(ModeNo<=0x13)
10265      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10266   else
10267      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10268 
10269   temp = GetTVPtrIndex(SiS_Pr);
10270   temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10271   temp1 = temp;
10272 
10273   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10274      if(SiS_Pr->ChipType >= SIS_661) {
10275         temp1 = GetOEMTVPtr661(SiS_Pr);
10276         temp1 >>= 1;
10277         romptr = SISGETROMW(0x260);
10278         if(SiS_Pr->ChipType >= SIS_760) {
10279 	   romptr = SISGETROMW(0x360);
10280 	}
10281      } else if(SiS_Pr->ChipType >= SIS_330) {
10282         romptr = SISGETROMW(0x192);
10283      } else {
10284         romptr = SISGETROMW(0x112);
10285      }
10286   }
10287 
10288   if(romptr) {
10289      temp1 <<= 1;
10290      temp = ROMAddr[romptr + temp1 + index];
10291   } else {
10292      temp = SiS310_TVAntiFlick1[temp][index];
10293   }
10294   temp <<= 4;
10295 
10296   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10297 }
10298 
10299 static void
10300 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10301 {
10302   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10303   unsigned short index,temp,temp1,romptr=0;
10304 
10305   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10306 
10307   if(ModeNo <= 0x13)
10308      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10309   else
10310      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10311 
10312   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10313      if(SiS_Pr->ChipType >= SIS_661) {
10314         romptr = SISGETROMW(0x26c);
10315         if(SiS_Pr->ChipType >= SIS_760) {
10316 	   romptr = SISGETROMW(0x36c);
10317 	}
10318 	temp1 = GetOEMTVPtr661(SiS_Pr);
10319         temp1 >>= 1;
10320      } else if(SiS_Pr->ChipType >= SIS_330) {
10321         romptr = SISGETROMW(0x1a4);
10322      } else {
10323         romptr = SISGETROMW(0x124);
10324      }
10325   }
10326 
10327   if(romptr) {
10328      temp1 <<= 1;
10329      temp = ROMAddr[romptr + temp1 + index];
10330   } else {
10331      temp = SiS310_TVEdge1[temp][index];
10332   }
10333   temp <<= 5;
10334   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10335 }
10336 
10337 static void
10338 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10339 {
10340   unsigned short index, temp, i, j;
10341 
10342   if(ModeNo <= 0x13) {
10343      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10344   } else {
10345      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10346   }
10347 
10348   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10349 
10350   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10351   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10352   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10353   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10354 
10355   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10356      for(i=0x35, j=0; i<=0x38; i++, j++) {
10357         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10358      }
10359      for(i=0x48; i<=0x4A; i++, j++) {
10360         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10361      }
10362   } else {
10363      for(i=0x35, j=0; i<=0x38; i++, j++) {
10364         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10365      }
10366   }
10367 }
10368 
10369 static void
10370 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10371 {
10372   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10373   unsigned short index,temp,i,j,resinfo,romptr=0;
10374   unsigned int  lindex;
10375 
10376   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10377 
10378   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10379   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10380 
10381   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10382      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10383      lindex <<= 2;
10384      for(j=0, i=0x31; i<=0x34; i++, j++) {
10385         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10386      }
10387      return;
10388   }
10389 
10390   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10391   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10392 
10393   if(ModeNo<=0x13) {
10394      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10395   } else {
10396      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10397   }
10398 
10399   temp = GetTVPtrIndex(SiS_Pr);
10400   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10401    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10402    */
10403   if(SiS_Pr->SiS_UseROM) {
10404      romptr = SISGETROMW(0x116);
10405      if(SiS_Pr->ChipType >= SIS_330) {
10406         romptr = SISGETROMW(0x196);
10407      }
10408      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10409         romptr = SISGETROMW(0x11c);
10410 	if(SiS_Pr->ChipType >= SIS_330) {
10411 	   romptr = SISGETROMW(0x19c);
10412 	}
10413 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10414 	   romptr = SISGETROMW(0x116);
10415 	   if(SiS_Pr->ChipType >= SIS_330) {
10416               romptr = SISGETROMW(0x196);
10417            }
10418 	}
10419      }
10420   }
10421   if(romptr) {
10422      romptr += (temp << 2);
10423      for(j=0, i=0x31; i<=0x34; i++, j++) {
10424         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10425      }
10426   } else {
10427      index = temp % 2;
10428      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10429      for(j=0, i=0x31; i<=0x34; i++, j++) {
10430         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10431 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10432         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10433            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10434         else
10435            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10436      }
10437   }
10438 
10439   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10440      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10441         if((resinfo == SIS_RI_640x480) ||
10442 	   (resinfo == SIS_RI_800x600)) {
10443 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10444 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10445 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10446 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10447 	} else if(resinfo == SIS_RI_1024x768) {
10448 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10449 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10450 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10451 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10452 	}
10453      }
10454   }
10455 }
10456 
10457 static void
10458 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10459                 unsigned short ModeIdIndex, unsigned short RTI)
10460 {
10461    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10462    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10463 
10464    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10465       return;
10466 
10467    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10468    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10469 
10470    if(SiS_Pr->SiS_ROMNew) {
10471       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10472          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10473 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10474          index = 25;
10475          if(SiS_Pr->UseCustomMode) {
10476 	    index = SiS_Pr->CSRClock;
10477          } else if(ModeNo > 0x13) {
10478             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10479             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10480          }
10481 	 if(index < 25) index = 25;
10482          index = ((index / 25) - 1) << 1;
10483          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10484 	    index++;
10485 	 }
10486 	 romptr = SISGETROMW(0x104);
10487          delay = ROMAddr[romptr + index];
10488          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10489             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10490             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10491          } else {
10492             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10493 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10494          }
10495          return;
10496       }
10497    }
10498 
10499    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10500 
10501    if(SiS_Pr->UseCustomMode) delay = 0x04;
10502    else if(ModeNo <= 0x13)   delay = 0x04;
10503    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10504    delay |= (delay << 8);
10505 
10506    if(SiS_Pr->ChipType >= XGI_20) {
10507 
10508       delay = 0x0606;
10509       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10510 
10511 	 delay = 0x0404;
10512          if(SiS_Pr->SiS_XGIROM) {
10513 	     index = GetTVPtrIndex(SiS_Pr);
10514 	     if((romptr = SISGETROMW(0x35e))) {
10515 	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10516 		delay |= (delay << 8);
10517 	     }
10518 	 }
10519 
10520 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10521 	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10522 	       delay -= 0x0404;
10523 	    }
10524 	 }
10525       }
10526 
10527    } else if(SiS_Pr->ChipType >= SIS_340) {
10528 
10529       delay = 0x0606;
10530       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10531          delay = 0x0404;
10532       }
10533       /* TODO (eventually) */
10534 
10535    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10536 
10537       /* 3. TV */
10538 
10539       index = GetOEMTVPtr661(SiS_Pr);
10540       if(SiS_Pr->SiS_ROMNew) {
10541          romptr = SISGETROMW(0x106);
10542 	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10543          delay = ROMAddr[romptr + index];
10544       } else {
10545          delay = 0x04;
10546 	 if(index > 3) delay = 0;
10547       }
10548 
10549    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10550 
10551       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10552 
10553       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10554           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10555 
10556 	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10557 
10558 	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10559 	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10560 	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10561 
10562       } else {
10563 
10564          /* TMDS: Set our own, since BIOS has no idea */
10565 	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10566          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10567 	    switch(SiS_Pr->SiS_LCDResInfo) {
10568 	    case Panel_1024x768:  delay = 0x0008; break;
10569 	    case Panel_1280x720:  delay = 0x0004; break;
10570 	    case Panel_1280x768:
10571 	    case Panel_1280x768_2:delay = 0x0004; break;
10572 	    case Panel_1280x800:
10573 	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10574 	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10575 	    case Panel_1280x1024: delay = 0x1e04; break;
10576 	    case Panel_1400x1050: delay = 0x0004; break;
10577 	    case Panel_1600x1200: delay = 0x0400; break;
10578 	    case Panel_1680x1050: delay = 0x0e04; break;
10579 	    default:
10580                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10581 	          delay = 0x0008;
10582 	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10583 	          delay = 0x1e04;
10584                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10585 	          delay = 0x0004;
10586 	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10587 	          delay = 0x0400;
10588                } else
10589 	          delay = 0x0e04;
10590 	       break;
10591 	    }
10592          }
10593 
10594 	 /* Override by detected or user-set values */
10595 	 /* (but only if, for some reason, we can't read value from BIOS) */
10596          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10597             delay = SiS_Pr->PDC & 0x1f;
10598          }
10599          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10600             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10601          }
10602 
10603       }
10604 
10605    }
10606 
10607    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10608       delay >>= 8;
10609       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10610       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10611    } else {
10612       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10613       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10614    }
10615 }
10616 
10617 static void
10618 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10619 {
10620    unsigned short infoflag;
10621    unsigned char  temp;
10622 
10623    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10624 
10625       if(ModeNo <= 0x13) {
10626          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10627       } else if(SiS_Pr->UseCustomMode) {
10628          infoflag = SiS_Pr->CInfoFlag;
10629       } else {
10630          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10631       }
10632 
10633       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10634          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10635       }
10636 
10637       infoflag &= 0xc0;
10638 
10639       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10640          temp = (infoflag >> 6) | 0x0c;
10641          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10642 	    temp ^= 0x04;
10643 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10644 	 }
10645          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10646       } else {
10647          temp = 0x30;
10648          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10649          temp |= infoflag;
10650          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10651          temp = 0;
10652          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10653 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10654 	 }
10655          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10656       }
10657 
10658    }
10659 }
10660 
10661 static void
10662 SetPanelParms661(struct SiS_Private *SiS_Pr)
10663 {
10664    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10665    unsigned short romptr, temp1, temp2;
10666 
10667    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10668       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10669    }
10670 
10671    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10672       if(SiS_Pr->LVDSHL != -1) {
10673          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10674       }
10675    }
10676 
10677    if(SiS_Pr->SiS_ROMNew) {
10678 
10679       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10680          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10681             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10682 	    temp2 = 0xfc;
10683 	    if(SiS_Pr->LVDSHL != -1) {
10684 	      temp1 &= 0xfc;
10685 	      temp2 = 0xf3;
10686 	    }
10687 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10688          }
10689 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10690             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10691             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10692 	 }
10693       }
10694 
10695    }
10696 }
10697 
10698 static void
10699 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10700 {
10701    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10702       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10703       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10704          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10705          SetPanelParms661(SiS_Pr);
10706       }
10707    } else {
10708       SetDelayComp(SiS_Pr,ModeNo);
10709    }
10710 
10711    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10712       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10713       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10714       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10715       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10716          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10717       }
10718    }
10719 }
10720 
10721 static void
10722 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10723 			unsigned short ModeIdIndex, unsigned short RRTI)
10724 {
10725    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10726 
10727       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10728 
10729       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10730          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10731          SetPanelParms661(SiS_Pr);
10732       }
10733 
10734       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10735          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10736          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10737          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10738          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10739             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10740          }
10741       }
10742    }
10743 }
10744 
10745 /* FinalizeLCD
10746  * This finalizes some CRT2 registers for the very panel used.
10747  * If we have a backup if these registers, we use it; otherwise
10748  * we set the register according to most BIOSes. However, this
10749  * function looks quite different in every BIOS, so you better
10750  * pray that we have a backup...
10751  */
10752 static void
10753 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10754 {
10755   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10756   unsigned short resinfo,modeflag;
10757 
10758   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10759   if(SiS_Pr->SiS_ROMNew) return;
10760 
10761   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10762      if(SiS_Pr->LVDSHL != -1) {
10763         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10764      }
10765   }
10766 
10767   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10768   if(SiS_Pr->UseCustomMode) return;
10769 
10770   switch(SiS_Pr->SiS_CustomT) {
10771   case CUT_COMPAQ1280:
10772   case CUT_COMPAQ12802:
10773   case CUT_CLEVO1400:
10774   case CUT_CLEVO14002:
10775      return;
10776   }
10777 
10778   if(ModeNo <= 0x13) {
10779      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10780      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10781   } else {
10782      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10783      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10784   }
10785 
10786   if(IS_SIS650) {
10787      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10788         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10789 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10790 	} else {
10791            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10792 	}
10793      }
10794   }
10795 
10796   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10797      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10798         /* Maybe all panels? */
10799         if(SiS_Pr->LVDSHL == -1) {
10800            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10801 	}
10802 	return;
10803      }
10804   }
10805 
10806   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10807      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10808         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10809 	   if(SiS_Pr->LVDSHL == -1) {
10810 	      /* Maybe all panels? */
10811               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10812 	   }
10813 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10814 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10815 	      if(tempch == 3) {
10816 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10817 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10818 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10819 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10820 	      }
10821 	   }
10822 	   return;
10823 	}
10824      }
10825   }
10826 
10827   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10828      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10829 	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10830 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10831 #ifdef SET_EMI
10832 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10833 #endif
10834 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10835 	}
10836      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10837         if(SiS_Pr->LVDSHL == -1) {
10838            /* Maybe ACER only? */
10839            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10840 	}
10841      }
10842      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10843      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10844 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10845 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10846 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10847 	   if(tempch == 0x03) {
10848 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10849 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10850 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10851 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10852 	   }
10853 	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10854 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10855 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10856 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10857 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10858 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10859 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10860 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10861 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10862 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10863 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10864 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10865 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10866 	      if(ModeNo <= 0x13) {
10867 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10868 		 if((resinfo == 0) || (resinfo == 2)) return;
10869 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10870 		 if((resinfo == 1) || (resinfo == 3)) return;
10871 	      }
10872 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10873 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10874 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10875 #if 0
10876 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10877 		 tempbx--;
10878 		 temp = tempbx & 0xff;
10879 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10880 		 temp = (tempbx >> 8) & 0x03;
10881 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10882 #endif
10883 	      }
10884 	   } else if(ModeNo <= 0x13) {
10885 	      if(ModeNo <= 1) {
10886 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10887 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10888 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10889 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10890 	      }
10891 	      if(!(modeflag & HalfDCLK)) {
10892 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10893 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10894 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10895 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10896 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10897 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10898 		 if(ModeNo == 0x12) {
10899 		    switch(tempch) {
10900 		       case 0:
10901 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10902 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10903 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10904 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10905 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10906 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10907 			  break;
10908 		       case 2:
10909 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10910 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10911 			  break;
10912 		       case 3:
10913 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10914 			  break;
10915 		    }
10916 		 }
10917 	      }
10918 	   }
10919 	}
10920      } else {
10921         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10922 	tempcl &= 0x0f;
10923 	tempbh &= 0x70;
10924 	tempbh >>= 4;
10925 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10926 	tempbx = (tempbh << 8) | tempbl;
10927 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10928 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10929 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10930 	      	 tempbx = 770;
10931 	      } else {
10932 	         if(tempbx > 770) tempbx = 770;
10933 		 if(SiS_Pr->SiS_VGAVDE < 600) {
10934 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10935 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10936 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10937 		    tempbx -= tempax;
10938 		 }
10939 	      }
10940 	   } else return;
10941 	}
10942 	temp = tempbx & 0xff;
10943 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10944 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10945 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10946      }
10947   }
10948 }
10949 
10950 #endif
10951 
10952 /*  =================  SiS 300 O.E.M. ================== */
10953 
10954 #ifdef CONFIG_FB_SIS_300
10955 
10956 static void
10957 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10958 		unsigned short RefTabIndex)
10959 {
10960   unsigned short crt2crtc=0, modeflag, myindex=0;
10961   unsigned char  temp;
10962   int i;
10963 
10964   if(ModeNo <= 0x13) {
10965      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10966      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10967   } else {
10968      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10969      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10970   }
10971 
10972   crt2crtc &= 0x3f;
10973 
10974   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10975      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10976   }
10977 
10978   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10979      if(modeflag & HalfDCLK) myindex = 1;
10980 
10981      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10982         for(i=0; i<7; i++) {
10983            if(barco_p1[myindex][crt2crtc][i][0]) {
10984 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10985 	                      barco_p1[myindex][crt2crtc][i][0],
10986 	   	   	      barco_p1[myindex][crt2crtc][i][2],
10987 			      barco_p1[myindex][crt2crtc][i][1]);
10988 	   }
10989         }
10990      }
10991      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10992      if(temp & 0x80) {
10993         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10994         temp++;
10995         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10996      }
10997   }
10998 }
10999 
11000 static unsigned short
11001 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11002 {
11003   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11004   unsigned short tempbx=0,romptr=0;
11005   static const unsigned char customtable300[] = {
11006 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11007 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11008   };
11009   static const unsigned char customtable630[] = {
11010 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11011 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11012   };
11013 
11014   if(SiS_Pr->ChipType == SIS_300) {
11015 
11016     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11017     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11018     tempbx -= 2;
11019     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11020     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11021        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11022     }
11023     if(SiS_Pr->SiS_UseROM) {
11024        if(ROMAddr[0x235] & 0x80) {
11025           tempbx = SiS_Pr->SiS_LCDTypeInfo;
11026           if(Flag) {
11027 	     romptr = SISGETROMW(0x255);
11028 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11029 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11030              if(tempbx == 0xFF) return 0xFFFF;
11031           }
11032 	  tempbx <<= 1;
11033 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11034        }
11035     }
11036 
11037   } else {
11038 
11039     if(Flag) {
11040        if(SiS_Pr->SiS_UseROM) {
11041           romptr = SISGETROMW(0x255);
11042 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11043 	  else 	     tempbx = 0xff;
11044        } else {
11045           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11046        }
11047        if(tempbx == 0xFF) return 0xFFFF;
11048        tempbx <<= 2;
11049        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11050        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11051        return tempbx;
11052     }
11053     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11054     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11055     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11056 
11057   }
11058 
11059   return tempbx;
11060 }
11061 
11062 static void
11063 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11064 {
11065   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11066   unsigned short index,temp,romptr=0;
11067 
11068   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11069 
11070   if(SiS_Pr->SiS_UseROM) {
11071      if(!(ROMAddr[0x237] & 0x01)) return;
11072      if(!(ROMAddr[0x237] & 0x02)) return;
11073      romptr = SISGETROMW(0x24b);
11074   }
11075 
11076   /* The Panel Compensation Delay should be set according to tables
11077    * here. Unfortunately, various BIOS versions don't care about
11078    * a uniform way using eg. ROM byte 0x220, but use different
11079    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11080    * Thus we don't set this if the user selected a custom pdc or if
11081    * we otherwise detected a valid pdc.
11082    */
11083   if(SiS_Pr->PDC != -1) return;
11084 
11085   temp = GetOEMLCDPtr(SiS_Pr, 0);
11086 
11087   if(SiS_Pr->UseCustomMode)
11088      index = 0;
11089   else
11090      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11091 
11092   if(SiS_Pr->ChipType != SIS_300) {
11093      if(romptr) {
11094 	romptr += (temp * 2);
11095 	romptr = SISGETROMW(romptr);
11096 	romptr += index;
11097 	temp = ROMAddr[romptr];
11098      } else {
11099 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
11100     	   temp = SiS300_OEMLCDDelay2[temp][index];
11101 	} else {
11102            temp = SiS300_OEMLCDDelay3[temp][index];
11103         }
11104      }
11105   } else {
11106      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11107 	if(romptr) {
11108 	   romptr += (temp * 2);
11109 	   romptr = SISGETROMW(romptr);
11110 	   romptr += index;
11111 	   temp = ROMAddr[romptr];
11112 	} else {
11113 	   temp = SiS300_OEMLCDDelay5[temp][index];
11114 	}
11115      } else {
11116         if(SiS_Pr->SiS_UseROM) {
11117 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11118 	   if(romptr) {
11119 	      romptr += (temp * 2);
11120 	      romptr = SISGETROMW(romptr);
11121 	      romptr += index;
11122 	      temp = ROMAddr[romptr];
11123 	   } else {
11124 	      temp = SiS300_OEMLCDDelay4[temp][index];
11125 	   }
11126 	} else {
11127 	   temp = SiS300_OEMLCDDelay4[temp][index];
11128 	}
11129      }
11130   }
11131   temp &= 0x3c;
11132   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11133 }
11134 
11135 static void
11136 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11137 {
11138 #if 0  /* Unfinished; Data table missing */
11139   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11140   unsigned short index,temp;
11141 
11142   if((SiS_Pr->SiS_UseROM) {
11143      if(!(ROMAddr[0x237] & 0x01)) return;
11144      if(!(ROMAddr[0x237] & 0x04)) return;
11145      /* No rom pointer in BIOS header! */
11146   }
11147 
11148   temp = GetOEMLCDPtr(SiS_Pr, 1);
11149   if(temp == 0xFFFF) return;
11150 
11151   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11152   for(i=0x14, j=0; i<=0x17; i++, j++) {
11153       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11154   }
11155   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11156 
11157   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11158   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11159   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11160   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11161   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11162       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11163   }
11164 #endif
11165 }
11166 
11167 static unsigned short
11168 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11169 {
11170   unsigned short index;
11171 
11172   index = 0;
11173   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11174   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11175      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11176      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11177      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11178   } else {
11179      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11180      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11181   }
11182   return index;
11183 }
11184 
11185 static void
11186 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11187 {
11188   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11189   unsigned short index,temp,romptr=0;
11190 
11191   if(SiS_Pr->SiS_UseROM) {
11192      if(!(ROMAddr[0x238] & 0x01)) return;
11193      if(!(ROMAddr[0x238] & 0x02)) return;
11194      romptr = SISGETROMW(0x241);
11195   }
11196 
11197   temp = GetOEMTVPtr(SiS_Pr);
11198 
11199   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11200 
11201   if(romptr) {
11202      romptr += (temp * 2);
11203      romptr = SISGETROMW(romptr);
11204      romptr += index;
11205      temp = ROMAddr[romptr];
11206   } else {
11207      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11208         temp = SiS300_OEMTVDelay301[temp][index];
11209      } else {
11210         temp = SiS300_OEMTVDelayLVDS[temp][index];
11211      }
11212   }
11213   temp &= 0x3c;
11214   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11215 }
11216 
11217 static void
11218 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11219 {
11220   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11221   unsigned short index,temp,romptr=0;
11222 
11223   if(SiS_Pr->SiS_UseROM) {
11224      if(!(ROMAddr[0x238] & 0x01)) return;
11225      if(!(ROMAddr[0x238] & 0x04)) return;
11226      romptr = SISGETROMW(0x243);
11227   }
11228 
11229   temp = GetOEMTVPtr(SiS_Pr);
11230 
11231   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11232 
11233   if(romptr) {
11234      romptr += (temp * 2);
11235      romptr = SISGETROMW(romptr);
11236      romptr += index;
11237      temp = ROMAddr[romptr];
11238   } else {
11239      temp = SiS300_OEMTVFlicker[temp][index];
11240   }
11241   temp &= 0x70;
11242   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11243 }
11244 
11245 static void
11246 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11247 {
11248   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11249   unsigned short index,i,j,temp,romptr=0;
11250 
11251   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11252 
11253   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11254 
11255   if(SiS_Pr->SiS_UseROM) {
11256      if(!(ROMAddr[0x238] & 0x01)) return;
11257      if(!(ROMAddr[0x238] & 0x08)) return;
11258      romptr = SISGETROMW(0x245);
11259   }
11260 
11261   temp = GetOEMTVPtr(SiS_Pr);
11262 
11263   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11264 
11265   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11266      for(i=0x31, j=0; i<=0x34; i++, j++) {
11267         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11268      }
11269   } else {
11270      if(romptr) {
11271         romptr += (temp * 2);
11272 	romptr = SISGETROMW(romptr);
11273 	romptr += (index * 4);
11274         for(i=0x31, j=0; i<=0x34; i++, j++) {
11275 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11276 	}
11277      } else {
11278         for(i=0x31, j=0; i<=0x34; i++, j++) {
11279            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11280 	}
11281      }
11282   }
11283 }
11284 
11285 static void
11286 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11287 {
11288   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11289   unsigned short index,temp,i,j,romptr=0;
11290 
11291   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11292 
11293   if(SiS_Pr->SiS_UseROM) {
11294      if(!(ROMAddr[0x238] & 0x01)) return;
11295      if(!(ROMAddr[0x238] & 0x10)) return;
11296      romptr = SISGETROMW(0x247);
11297   }
11298 
11299   temp = GetOEMTVPtr(SiS_Pr);
11300 
11301   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11302   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11303   /* NTSCJ uses NTSC filters */
11304 
11305   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11306 
11307   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11308       for(i=0x35, j=0; i<=0x38; i++, j++) {
11309        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11310       }
11311       for(i=0x48; i<=0x4A; i++, j++) {
11312      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11313       }
11314   } else {
11315       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11316          romptr += (temp * 2);
11317 	 romptr = SISGETROMW(romptr);
11318 	 romptr += (index * 4);
11319 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11320        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11321          }
11322       } else {
11323          for(i=0x35, j=0; i<=0x38; i++, j++) {
11324        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11325          }
11326       }
11327   }
11328 }
11329 
11330 static unsigned short
11331 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11332 {
11333    unsigned short ModeIdIndex;
11334    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11335 
11336    if(*ModeNo <= 5) *ModeNo |= 1;
11337 
11338    for(ModeIdIndex=0; ; ModeIdIndex++) {
11339       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11340       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11341    }
11342 
11343    if(*ModeNo != 0x07) {
11344       if(*ModeNo > 0x03) return ModeIdIndex;
11345       if(VGAINFO & 0x80) return ModeIdIndex;
11346       ModeIdIndex++;
11347    }
11348 
11349    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11350 	                               /* else 350 lines */
11351    return ModeIdIndex;
11352 }
11353 
11354 static void
11355 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11356 		  unsigned short RefTableIndex)
11357 {
11358   unsigned short OEMModeIdIndex = 0;
11359 
11360   if(!SiS_Pr->UseCustomMode) {
11361      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11362      if(!(OEMModeIdIndex)) return;
11363   }
11364 
11365   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11366      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11367      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11368         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11369      }
11370   }
11371   if(SiS_Pr->UseCustomMode) return;
11372   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11373      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11374      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11375         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11376     	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11377        	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11378      }
11379   }
11380 }
11381 #endif
11382 
11383