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