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
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)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
SiS_LockCRT2(struct SiS_Private * SiS_Pr)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
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)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 *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)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
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)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
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)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
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)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
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)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
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)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
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)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
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)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
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)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
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)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
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)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
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)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
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)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
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)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
SiS_VBWait(struct SiS_Private * SiS_Pr)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
SiS_VBLongWait(struct SiS_Private * SiS_Pr)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
SiS_Is301B(struct SiS_Private * SiS_Pr)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
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)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
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)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
SiS_IsVAMode(struct SiS_Private * SiS_Pr)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
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)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
SiS_IsDualLink(struct SiS_Private * SiS_Pr)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
SiS_TVEnabled(struct SiS_Private * SiS_Pr)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
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)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
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)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
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)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
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)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
SiS_IsChScart(struct SiS_Private * SiS_Pr)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
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)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
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)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
SiS_HaveBridge(struct SiS_Private * SiS_Pr)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
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)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
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)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
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)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
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)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
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)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
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)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
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)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
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)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
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)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
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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 *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)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
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_HandlePWD(struct SiS_Private * SiS_Pr)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
SiS_DisableBridge(struct SiS_Private * SiS_Pr)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
SiS_EnableBridge(struct SiS_Private * SiS_Pr)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
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)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
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)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
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)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
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)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
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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 *
SiS_GetGroup2CLVXPtr(struct SiS_Private * SiS_Pr,int tabletype)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
SiS_SetGroup2_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)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
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)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
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)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
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)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
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)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
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)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
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)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
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)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
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)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
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)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
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)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
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)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
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)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
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)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
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)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
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)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
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)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
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)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
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)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
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)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 *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)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
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)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
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)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
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)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
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)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
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)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
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)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
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)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
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)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
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)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
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)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
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,bool checkcr32,unsigned int VBFlags2)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
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)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
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)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
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)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
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)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
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)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
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)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
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)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
SiS_HandleDDC(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,unsigned char * buffer,unsigned int VBFlags2)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
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)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
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)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
SiS_SetStart(struct SiS_Private * SiS_Pr)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
SiS_SetStop(struct SiS_Private * SiS_Pr)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
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)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
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)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
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)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
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)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
SiS_CheckACK(struct SiS_Private * SiS_Pr)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
GetRAMDACromptr(struct SiS_Private * SiS_Pr)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
GetLCDromptr(struct SiS_Private * SiS_Pr)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
GetTVromptr(struct SiS_Private * SiS_Pr)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
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)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
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)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
GetTVPtrIndex(struct SiS_Private * SiS_Pr)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
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)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
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)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
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)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
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)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
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)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
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)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
SetPanelParms661(struct SiS_Private * SiS_Pr)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
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)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
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)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
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)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
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)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
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
GetOEMTVPtr(struct SiS_Private * SiS_Pr)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
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)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
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)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
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)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 
11381