xref: /openbmc/linux/drivers/video/fbdev/sis/init301.c (revision be849454)
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 #ifdef CONFIG_FB_SIS_315
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 /* 661 et al LCD data structure (2.03.00) */
249 static const unsigned char SiS_LCDStruct661[] = {
250     /* 1024x768 */
251 /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
252     0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
253     0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
254     /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
255     /*					      VESA    non-VESA  noscale */
256     /* 1280x1024 */
257     0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
258     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
259     /* 1400x1050 */
260     0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
261     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
262     /* 1600x1200 */
263     0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
264     0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
265     /* 1280x768 (_2) */
266     0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
267     0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
268     /* 1280x720 */
269     0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
270     0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
271     /* 1280x800 (_2) */
272     0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
273     0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
274     /* 1680x1050 */
275     0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
276     0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
277     /* 1280x800_3 */
278     0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
279     0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
280     /* 800x600 */
281     0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
282     0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
283     /* 1280x854 */
284     0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
285     0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
286 };
287 #endif
288 
289 #ifdef CONFIG_FB_SIS_300
290 static unsigned char SiS300_TrumpionData[14][80] = {
291   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
292     0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
293     0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
294     0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
295     0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
296   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
297     0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
298     0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
299     0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
300     0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
301   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
302     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
303     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
304     0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
305     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
306   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
307     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
308     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
309     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
310     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
311   { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
312     0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
313     0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
314     0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
315     0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
316   { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
317     0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
318     0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
319     0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
320     0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
321   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
322     0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
323     0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
324     0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
325     0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
326   /* variant 2 */
327   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
328     0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
329     0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
330     0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
331     0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
332   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
333     0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
334     0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
335     0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
336     0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
337   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
338     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
339     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
340     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
341     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
342   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
343     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
344     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
345     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
346     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
347   { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
348     0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
349     0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
350     0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
351     0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
352   { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
353     0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
354     0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
355     0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
356     0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
357   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
358     0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
359     0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
360     0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
361     0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
362 };
363 #endif
364 
365 #ifdef CONFIG_FB_SIS_315
366 static void	SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
367 static void	SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
368 static void	SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
369 static void	SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
370 #endif /* 315 */
371 
372 #ifdef CONFIG_FB_SIS_300
373 static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
374 #endif
375 
376 static unsigned short	SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
377 				int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
378 				bool checkcr32, unsigned int VBFlags2);
379 static unsigned short	SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
380 static unsigned short	SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
381 				unsigned char *buffer);
382 static void		SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
383 static unsigned short	SiS_SetStart(struct SiS_Private *SiS_Pr);
384 static unsigned short	SiS_SetStop(struct SiS_Private *SiS_Pr);
385 static unsigned short	SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
386 static unsigned short	SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
387 static unsigned short	SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
388 static unsigned short	SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
389 static unsigned short	SiS_CheckACK(struct SiS_Private *SiS_Pr);
390 static unsigned short	SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
391 static unsigned short	SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
392 static unsigned short	SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
393 static void		SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
394 static unsigned short	SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
395 
396 #ifdef CONFIG_FB_SIS_300
397 static void		SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
398 				unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
399 static void		SetOEMLCDData2(struct SiS_Private *SiS_Pr,
400 				unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
401 #endif
402 #ifdef CONFIG_FB_SIS_315
403 static void		SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
404 				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
405 static void		SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
406 				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
407 static void		SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
408 #endif
409 
410 static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
411 static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
412 
413 /*********************************************/
414 /*         HELPER: Lock/Unlock CRT2          */
415 /*********************************************/
416 
417 void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)418 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
419 {
420    if(SiS_Pr->ChipType == XGI_20)
421       return;
422    else if(SiS_Pr->ChipType >= SIS_315H)
423       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
424    else
425       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
426 }
427 
428 static
429 void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)430 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
431 {
432    if(SiS_Pr->ChipType == XGI_20)
433       return;
434    else if(SiS_Pr->ChipType >= SIS_315H)
435       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
436    else
437       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
438 }
439 
440 /*********************************************/
441 /*            HELPER: Write SR11             */
442 /*********************************************/
443 
444 static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)445 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
446 {
447    if(SiS_Pr->ChipType >= SIS_661) {
448       DataAND &= 0x0f;
449       DataOR  &= 0x0f;
450    }
451    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
452 }
453 
454 /*********************************************/
455 /*    HELPER: Get Pointer to LCD structure   */
456 /*********************************************/
457 
458 #ifdef CONFIG_FB_SIS_315
459 static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)460 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
461 {
462    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
463    unsigned char  *myptr = NULL;
464    unsigned short romindex = 0, reg = 0, idx = 0;
465 
466    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
467     * due to the variaty of panels the BIOS doesn't know about.
468     * Exception: If the BIOS has better knowledge (such as in case
469     * of machines with a 301C and a panel that does not support DDC)
470     * use the BIOS data as well.
471     */
472 
473    if((SiS_Pr->SiS_ROMNew) &&
474       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
475 
476       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
477       else                           reg = 0x7d;
478 
479       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
480 
481       if(idx < (8*26)) {
482          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
483       }
484       romindex = SISGETROMW(0x100);
485       if(romindex) {
486          romindex += idx;
487          myptr = &ROMAddr[romindex];
488       }
489    }
490    return myptr;
491 }
492 
493 static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)494 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
495 {
496    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
497    unsigned short romptr = 0;
498 
499    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
500     * due to the variaty of panels the BIOS doesn't know about.
501     * Exception: If the BIOS has better knowledge (such as in case
502     * of machines with a 301C and a panel that does not support DDC)
503     * use the BIOS data as well.
504     */
505 
506    if((SiS_Pr->SiS_ROMNew) &&
507       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
508       romptr = SISGETROMW(0x102);
509       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
510    }
511 
512    return romptr;
513 }
514 #endif
515 
516 /*********************************************/
517 /*           Adjust Rate for CRT2            */
518 /*********************************************/
519 
520 static bool
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)521 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
522 		unsigned short RRTI, unsigned short *i)
523 {
524    unsigned short checkmask=0, modeid, infoflag;
525 
526    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
527 
528    if(SiS_Pr->SiS_VBType & VB_SISVB) {
529 
530       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
531 
532 	 checkmask |= SupportRAMDAC2;
533 	 if(SiS_Pr->ChipType >= SIS_315H) {
534 	    checkmask |= SupportRAMDAC2_135;
535 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
536 	       checkmask |= SupportRAMDAC2_162;
537 	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
538 		  checkmask |= SupportRAMDAC2_202;
539 	       }
540 	    }
541 	 }
542 
543       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
544 
545 	 checkmask |= SupportLCD;
546 	 if(SiS_Pr->ChipType >= SIS_315H) {
547 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
548 	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
549 	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
550 	       }
551 	    }
552 	 }
553 
554       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
555 
556 	 checkmask |= SupportHiVision;
557 
558       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
559 
560 	 checkmask |= SupportTV;
561 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
562 	    checkmask |= SupportTV1024;
563 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
564 	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
565 	          checkmask |= SupportYPbPr750p;
566 	       }
567 	    }
568 	 }
569 
570       }
571 
572    } else {	/* LVDS */
573 
574       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
575 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
576 	    checkmask |= SupportCHTV;
577 	 }
578       }
579 
580       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
581 	 checkmask |= SupportLCD;
582       }
583 
584    }
585 
586    /* Look backwards in table for matching CRT2 mode */
587    for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
588       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
589       if(infoflag & checkmask) return true;
590       if((*i) == 0) break;
591    }
592 
593    /* Look through the whole mode-section of the table from the beginning
594     * for a matching CRT2 mode if no mode was found yet.
595     */
596    for((*i) = 0; ; (*i)++) {
597       if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
598       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
599       if(infoflag & checkmask) return true;
600    }
601    return false;
602 }
603 
604 /*********************************************/
605 /*              Get rate index               */
606 /*********************************************/
607 
608 unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)609 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
610 {
611    unsigned short RRTI,i,backup_i;
612    unsigned short modeflag,index,temp,backupindex;
613    static const unsigned short LCDRefreshIndex[] = {
614 		0x00, 0x00, 0x01, 0x01,
615 		0x01, 0x01, 0x01, 0x01,
616 		0x01, 0x01, 0x01, 0x01,
617 		0x01, 0x01, 0x01, 0x01,
618 		0x00, 0x00, 0x00, 0x00
619    };
620 
621    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
622    if(ModeNo == 0xfe) return 0;
623 
624    if(ModeNo <= 0x13) {
625       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
626    } else {
627       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
628    }
629 
630    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
631       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
632 	 if(modeflag & HalfDCLK) return 0;
633       }
634    }
635 
636    if(ModeNo < 0x14) return 0xFFFF;
637 
638    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
639    backupindex = index;
640 
641    if(index > 0) index--;
642 
643    if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
644       if(SiS_Pr->SiS_VBType & VB_SISVB) {
645 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
646 	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
647 	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
648 	 }
649 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
650 	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
651 	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
652 	       if(index > temp) index = temp;
653 	    }
654 	 }
655       } else {
656 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
657 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
658 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
659 	 }
660       }
661    }
662 
663    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
664    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
665 
666    if(SiS_Pr->ChipType >= SIS_315H) {
667       if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
668 	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
669 	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
670 	    if(backupindex <= 1) RRTI++;
671 	 }
672       }
673    }
674 
675    i = 0;
676    do {
677       if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
678       temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
679       temp &= ModeTypeMask;
680       if(temp < SiS_Pr->SiS_ModeType) break;
681       i++;
682       index--;
683    } while(index != 0xFFFF);
684 
685    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
686       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
687 	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
688 	 if(temp & InterlaceMode) i++;
689       }
690    }
691 
692    i--;
693 
694    if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
695       backup_i = i;
696       if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
697 	 i = backup_i;
698       }
699    }
700 
701    return (RRTI + i);
702 }
703 
704 /*********************************************/
705 /*            STORE CRT2 INFO in CR34        */
706 /*********************************************/
707 
708 static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)709 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
710 {
711    unsigned short temp1, temp2;
712 
713    /* Store CRT1 ModeNo in CR34 */
714    SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
715    temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
716    temp2 = ~(SetInSlaveMode >> 8);
717    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
718 }
719 
720 /*********************************************/
721 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
722 /*********************************************/
723 
724 #ifdef CONFIG_FB_SIS_300
725 static bool
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)726 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
727 {
728    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
729    unsigned short temp,temp1;
730 
731    if(SiS_Pr->SiS_UseROM) {
732       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
733 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
734 	 temp1 = SISGETROMW(0x23b);
735 	 if(temp1 & temp) return true;
736       }
737    }
738    return false;
739 }
740 
741 static bool
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)742 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
743 {
744    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
745    unsigned short temp,temp1;
746 
747    if(SiS_Pr->SiS_UseROM) {
748       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
749 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
750 	 temp1 = SISGETROMW(0x23d);
751 	 if(temp1 & temp) return true;
752       }
753    }
754    return false;
755 }
756 #endif
757 
758 /*********************************************/
759 /*          HELPER: DELAY FUNCTIONS          */
760 /*********************************************/
761 
762 void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)763 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
764 {
765    while (delaytime-- > 0)
766       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
767 }
768 
769 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
770 static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)771 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
772 {
773    SiS_DDC2Delay(SiS_Pr, delay * 36);
774 }
775 #endif
776 
777 #ifdef CONFIG_FB_SIS_315
778 static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)779 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
780 {
781    while(delay--) {
782       SiS_GenericDelay(SiS_Pr, 6623);
783    }
784 }
785 #endif
786 
787 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
788 static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)789 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
790 {
791    while(delay--) {
792       SiS_GenericDelay(SiS_Pr, 66);
793    }
794 }
795 #endif
796 
797 static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)798 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
799 {
800 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
801    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
802    unsigned short PanelID, DelayIndex, Delay=0;
803 #endif
804 
805    if(SiS_Pr->ChipType < SIS_315H) {
806 
807 #ifdef CONFIG_FB_SIS_300
808 
809       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
810       if(SiS_Pr->SiS_VBType & VB_SISVB) {
811 	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
812 	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
813       }
814       DelayIndex = PanelID >> 4;
815       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
816 	 Delay = 3;
817       } else {
818 	 if(DelayTime >= 2) DelayTime -= 2;
819 	 if(!(DelayTime & 0x01)) {
820 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
821 	 } else {
822 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
823 	 }
824 	 if(SiS_Pr->SiS_UseROM) {
825 	    if(ROMAddr[0x220] & 0x40) {
826 	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
827 	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
828 	    }
829 	 }
830       }
831       SiS_ShortDelay(SiS_Pr, Delay);
832 
833 #endif  /* CONFIG_FB_SIS_300 */
834 
835    } else {
836 
837 #ifdef CONFIG_FB_SIS_315
838 
839       if((SiS_Pr->ChipType >= SIS_661)    ||
840 	 (SiS_Pr->ChipType <= SIS_315PRO) ||
841 	 (SiS_Pr->ChipType == SIS_330)    ||
842 	 (SiS_Pr->SiS_ROMNew)) {
843 
844 	 if(!(DelayTime & 0x01)) {
845 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
846 	 } else {
847 	    SiS_DDC2Delay(SiS_Pr, 0x4000);
848 	 }
849 
850       } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS; Special */
851 
852 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
853 	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
854 	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
855 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
856 	    }
857 	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
858 	       DelayIndex = PanelID & 0x0f;
859 	    } else {
860 	       DelayIndex = PanelID >> 4;
861 	    }
862 	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
863 	       Delay = 3;
864 	    } else {
865 	       if(DelayTime >= 2) DelayTime -= 2;
866 	       if(!(DelayTime & 0x01)) {
867 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
868 		} else {
869 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
870 	       }
871 	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
872 		  if(ROMAddr[0x13c] & 0x40) {
873 		     if(!(DelayTime & 0x01)) {
874 			Delay = (unsigned short)ROMAddr[0x17e];
875 		     } else {
876 			Delay = (unsigned short)ROMAddr[0x17f];
877 		     }
878 		  }
879 	       }
880 	    }
881 	    SiS_ShortDelay(SiS_Pr, Delay);
882 	 }
883 
884       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
885 
886 	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
887 	 if(!(DelayTime & 0x01)) {
888 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
889 	 } else {
890 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
891 	 }
892 	 Delay <<= 8;
893 	 SiS_DDC2Delay(SiS_Pr, Delay);
894 
895       }
896 
897 #endif /* CONFIG_FB_SIS_315 */
898 
899    }
900 }
901 
902 #ifdef CONFIG_FB_SIS_315
903 static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)904 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
905 {
906    int i;
907    for(i = 0; i < DelayLoop; i++) {
908       SiS_PanelDelay(SiS_Pr, DelayTime);
909    }
910 }
911 #endif
912 
913 /*********************************************/
914 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
915 /*********************************************/
916 
917 void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)918 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
919 {
920    unsigned short watchdog;
921 
922    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
923    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
924 
925    watchdog = 65535;
926    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
927    watchdog = 65535;
928    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
929 }
930 
931 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
932 static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)933 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
934 {
935    unsigned short watchdog;
936 
937    watchdog = 65535;
938    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
939    watchdog = 65535;
940    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
941 }
942 #endif
943 
944 static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)945 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
946 {
947    if(SiS_Pr->ChipType < SIS_315H) {
948 #ifdef CONFIG_FB_SIS_300
949       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
950 	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
951       }
952       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
953 	 SiS_WaitRetrace1(SiS_Pr);
954       } else {
955 	 SiS_WaitRetrace2(SiS_Pr, 0x25);
956       }
957 #endif
958    } else {
959 #ifdef CONFIG_FB_SIS_315
960       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
961 	 SiS_WaitRetrace1(SiS_Pr);
962       } else {
963 	 SiS_WaitRetrace2(SiS_Pr, 0x30);
964       }
965 #endif
966    }
967 }
968 
969 static void
SiS_VBWait(struct SiS_Private * SiS_Pr)970 SiS_VBWait(struct SiS_Private *SiS_Pr)
971 {
972    unsigned short tempal,temp,i,j;
973 
974    temp = 0;
975    for(i = 0; i < 3; i++) {
976      for(j = 0; j < 100; j++) {
977         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
978         if(temp & 0x01) {
979 	   if((tempal & 0x08))  continue;
980 	   else break;
981         } else {
982 	   if(!(tempal & 0x08)) continue;
983 	   else break;
984         }
985      }
986      temp ^= 0x01;
987    }
988 }
989 
990 static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)991 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
992 {
993    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
994       SiS_VBWait(SiS_Pr);
995    } else {
996       SiS_WaitRetrace1(SiS_Pr);
997    }
998 }
999 
1000 /*********************************************/
1001 /*               HELPER: MISC                */
1002 /*********************************************/
1003 
1004 #ifdef CONFIG_FB_SIS_300
1005 static bool
SiS_Is301B(struct SiS_Private * SiS_Pr)1006 SiS_Is301B(struct SiS_Private *SiS_Pr)
1007 {
1008    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1009    return false;
1010 }
1011 #endif
1012 
1013 static bool
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)1014 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1015 {
1016    if(SiS_Pr->ChipType == SIS_730) {
1017       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1018    }
1019    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1020    return false;
1021 }
1022 
1023 bool
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)1024 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1025 {
1026 #ifdef CONFIG_FB_SIS_315
1027    if(SiS_Pr->ChipType >= SIS_315H) {
1028       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1029 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1030       }
1031    }
1032 #endif
1033    return false;
1034 }
1035 
1036 bool
SiS_IsVAMode(struct SiS_Private * SiS_Pr)1037 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1038 {
1039 #ifdef CONFIG_FB_SIS_315
1040    unsigned short flag;
1041 
1042    if(SiS_Pr->ChipType >= SIS_315H) {
1043       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1044       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1045    }
1046 #endif
1047    return false;
1048 }
1049 
1050 #ifdef CONFIG_FB_SIS_315
1051 static bool
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)1052 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1053 {
1054    if(SiS_IsVAMode(SiS_Pr))  return true;
1055    if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1056    return false;
1057 }
1058 #endif
1059 
1060 static bool
SiS_IsDualLink(struct SiS_Private * SiS_Pr)1061 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1062 {
1063 #ifdef CONFIG_FB_SIS_315
1064    if(SiS_Pr->ChipType >= SIS_315H) {
1065       if((SiS_CRT2IsLCD(SiS_Pr)) ||
1066          (SiS_IsVAMode(SiS_Pr))) {
1067 	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1068       }
1069    }
1070 #endif
1071    return false;
1072 }
1073 
1074 #ifdef CONFIG_FB_SIS_315
1075 static bool
SiS_TVEnabled(struct SiS_Private * SiS_Pr)1076 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1077 {
1078    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1079    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1080       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1081    }
1082    return false;
1083 }
1084 #endif
1085 
1086 #ifdef CONFIG_FB_SIS_315
1087 static bool
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)1088 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1089 {
1090    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1091    return false;
1092 }
1093 #endif
1094 
1095 #ifdef CONFIG_FB_SIS_315
1096 static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)1097 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1098 {
1099    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1100       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1101    }
1102    return false;
1103 }
1104 #endif
1105 
1106 #ifdef CONFIG_FB_SIS_315
1107 static bool
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)1108 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1109 {
1110    unsigned short flag;
1111 
1112    if(SiS_Pr->ChipType == SIS_650) {
1113       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1114       /* Check for revision != A0 only */
1115       if((flag == 0xe0) || (flag == 0xc0) ||
1116          (flag == 0xb0) || (flag == 0x90)) return false;
1117    } else if(SiS_Pr->ChipType >= SIS_661) return false;
1118    return true;
1119 }
1120 #endif
1121 
1122 #ifdef CONFIG_FB_SIS_315
1123 static bool
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)1124 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1125 {
1126    if(SiS_Pr->ChipType >= SIS_315H) {
1127       /* YPrPb = 0x08 */
1128       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1129    }
1130    return false;
1131 }
1132 #endif
1133 
1134 #ifdef CONFIG_FB_SIS_315
1135 static bool
SiS_IsChScart(struct SiS_Private * SiS_Pr)1136 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1137 {
1138    if(SiS_Pr->ChipType >= SIS_315H) {
1139       /* Scart = 0x04 */
1140       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1141    }
1142    return false;
1143 }
1144 #endif
1145 
1146 #ifdef CONFIG_FB_SIS_315
1147 static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)1148 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1149 {
1150    unsigned short flag;
1151 
1152    if(SiS_Pr->ChipType >= SIS_315H) {
1153       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1154       if(flag & SetCRT2ToTV)        return true;
1155       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1156       if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
1157       if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
1158    } else {
1159       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1160       if(flag & SetCRT2ToTV)        return true;
1161    }
1162    return false;
1163 }
1164 #endif
1165 
1166 #ifdef CONFIG_FB_SIS_315
1167 static bool
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)1168 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1169 {
1170    unsigned short flag;
1171 
1172    if(SiS_Pr->ChipType >= SIS_315H) {
1173       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1174       if(flag & SetCRT2ToLCD) return true;
1175       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1176       if(flag & SetToLCDA)    return true;
1177    } else {
1178       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1179       if(flag & SetCRT2ToLCD) return true;
1180    }
1181    return false;
1182 }
1183 #endif
1184 
1185 static bool
SiS_HaveBridge(struct SiS_Private * SiS_Pr)1186 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1187 {
1188    unsigned short flag;
1189 
1190    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1191       return true;
1192    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1193       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1194       if((flag == 1) || (flag == 2)) return true;
1195    }
1196    return false;
1197 }
1198 
1199 static bool
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)1200 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1201 {
1202    unsigned short flag;
1203 
1204    if(SiS_HaveBridge(SiS_Pr)) {
1205       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1206       if(SiS_Pr->ChipType < SIS_315H) {
1207 	flag &= 0xa0;
1208 	if((flag == 0x80) || (flag == 0x20)) return true;
1209       } else {
1210 	flag &= 0x50;
1211 	if((flag == 0x40) || (flag == 0x10)) return true;
1212       }
1213    }
1214    return false;
1215 }
1216 
1217 static bool
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)1218 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1219 {
1220    unsigned short flag1;
1221 
1222    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1223    if(flag1 & (SetInSlaveMode >> 8)) return true;
1224    return false;
1225 }
1226 
1227 /*********************************************/
1228 /*       GET VIDEO BRIDGE CONFIG INFO        */
1229 /*********************************************/
1230 
1231 /* Setup general purpose IO for Chrontel communication */
1232 #ifdef CONFIG_FB_SIS_300
1233 void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)1234 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1235 {
1236    unsigned int   acpibase;
1237    unsigned short temp;
1238 
1239    if(!(SiS_Pr->SiS_ChSW)) return;
1240 
1241    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1242    acpibase &= 0xFFFF;
1243    if(!acpibase) return;
1244    temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
1245    temp &= 0xFEFF;
1246    SiS_SetRegShort((acpibase + 0x3c), temp);
1247    temp = SiS_GetRegShort((acpibase + 0x3c));
1248    temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
1249    temp &= 0xFEFF;
1250    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1251    SiS_SetRegShort((acpibase + 0x3a), temp);
1252    temp = SiS_GetRegShort((acpibase + 0x3a));
1253 }
1254 #endif
1255 
1256 void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)1257 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1258 		unsigned short ModeIdIndex, int checkcrt2mode)
1259 {
1260    unsigned short tempax, tempbx, temp;
1261    unsigned short modeflag, resinfo = 0;
1262 
1263    SiS_Pr->SiS_SetFlag = 0;
1264 
1265    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1266 
1267    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1268 
1269    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1270       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1271    }
1272 
1273    tempbx = 0;
1274 
1275    if(SiS_HaveBridge(SiS_Pr)) {
1276 
1277 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1278 	tempbx |= temp;
1279 	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1280 	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1281 	tempbx |= tempax;
1282 
1283 #ifdef CONFIG_FB_SIS_315
1284 	if(SiS_Pr->ChipType >= SIS_315H) {
1285 	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1286 	      if(ModeNo == 0x03) {
1287 		 /* Mode 0x03 is never in driver mode */
1288 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1289 	      }
1290 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1291 		 /* Reset LCDA setting if not driver mode */
1292 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1293 	      }
1294 	      if(IS_SIS650) {
1295 		 if(SiS_Pr->SiS_UseLCDA) {
1296 		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1297 		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1298 			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1299 		       }
1300 		    }
1301 		 }
1302 	      }
1303 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1304 	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1305 		 tempbx |= SetCRT2ToLCDA;
1306 	      }
1307 	   }
1308 
1309 	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1310 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1311 	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1312 		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1313 		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1314 		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1315 		    tempbx |= SetCRT2ToYPbPr525750;
1316 		 }
1317 	      }
1318 	   }
1319 
1320 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1321 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1322 	      if(temp & SetToLCDA) {
1323 		 tempbx |= SetCRT2ToLCDA;
1324 	      }
1325 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1326 		 if(temp & EnableCHYPbPr) {
1327 		    tempbx |= SetCRT2ToCHYPbPr;
1328 		 }
1329 	      }
1330 	   }
1331 	}
1332 
1333 #endif  /* CONFIG_FB_SIS_315 */
1334 
1335         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1336 	   tempbx &= ~(SetCRT2ToRAMDAC);
1337 	}
1338 
1339 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1340 	   temp = SetCRT2ToSVIDEO   |
1341 		  SetCRT2ToAVIDEO   |
1342 		  SetCRT2ToSCART    |
1343 		  SetCRT2ToLCDA     |
1344 		  SetCRT2ToLCD      |
1345 		  SetCRT2ToRAMDAC   |
1346 		  SetCRT2ToHiVision |
1347 		  SetCRT2ToYPbPr525750;
1348 	} else {
1349 	   if(SiS_Pr->ChipType >= SIS_315H) {
1350 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1351 		 temp = SetCRT2ToAVIDEO |
1352 		        SetCRT2ToSVIDEO |
1353 		        SetCRT2ToSCART  |
1354 		        SetCRT2ToLCDA   |
1355 		        SetCRT2ToLCD    |
1356 		        SetCRT2ToCHYPbPr;
1357 	      } else {
1358 		 temp = SetCRT2ToLCDA   |
1359 		        SetCRT2ToLCD;
1360 	      }
1361 	   } else {
1362 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1363 		 temp = SetCRT2ToTV | SetCRT2ToLCD;
1364 	      } else {
1365 		 temp = SetCRT2ToLCD;
1366 	      }
1367 	   }
1368 	}
1369 
1370 	if(!(tempbx & temp)) {
1371 	   tempax = DisableCRT2Display;
1372 	   tempbx = 0;
1373 	}
1374 
1375 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1376 
1377 	   unsigned short clearmask = ( DriverMode |
1378 				DisableCRT2Display |
1379 				LoadDACFlag 	   |
1380 				SetNotSimuMode 	   |
1381 				SetInSlaveMode 	   |
1382 				SetPALTV 	   |
1383 				SwitchCRT2	   |
1384 				SetSimuScanMode );
1385 
1386 	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1387 	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1388 	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1389 	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1390 	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1391 	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1392 
1393 	} else {
1394 
1395 	   if(SiS_Pr->ChipType >= SIS_315H) {
1396 	      if(tempbx & SetCRT2ToLCDA) {
1397 		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1398 	      }
1399 	   }
1400 	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1401 	      if(tempbx & SetCRT2ToTV) {
1402 		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1403 	      }
1404 	   }
1405 	   if(tempbx & SetCRT2ToLCD) {
1406 	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1407 	   }
1408 	   if(SiS_Pr->ChipType >= SIS_315H) {
1409 	      if(tempbx & SetCRT2ToLCDA) {
1410 	         tempbx |= SetCRT2ToLCD;
1411 	      }
1412 	   }
1413 
1414 	}
1415 
1416 	if(tempax & DisableCRT2Display) {
1417 	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1418 	      tempbx = SetSimuScanMode | DisableCRT2Display;
1419 	   }
1420 	}
1421 
1422 	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1423 
1424 	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1425 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1426 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1427 	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1428 	      modeflag &= (~CRT2Mode);
1429 	   }
1430 	}
1431 
1432 	if(!(tempbx & SetSimuScanMode)) {
1433 	   if(tempbx & SwitchCRT2) {
1434 	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1435 		 if(resinfo != SIS_RI_1600x1200) {
1436 		    tempbx |= SetSimuScanMode;
1437 		 }
1438               }
1439 	   } else {
1440 	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
1441 		 if(!(tempbx & DriverMode)) {
1442 		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1443 		       tempbx |= SetSimuScanMode;
1444 		    }
1445 		 }
1446 	      }
1447 	   }
1448 	}
1449 
1450 	if(!(tempbx & DisableCRT2Display)) {
1451 	   if(tempbx & DriverMode) {
1452 	      if(tempbx & SetSimuScanMode) {
1453 		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1454 		    if(resinfo != SIS_RI_1600x1200) {
1455 		       tempbx |= SetInSlaveMode;
1456 		    }
1457 		 }
1458 	      }
1459 	   } else {
1460 	      tempbx |= SetInSlaveMode;
1461 	   }
1462 	}
1463 
1464    }
1465 
1466    SiS_Pr->SiS_VBInfo = tempbx;
1467 
1468 #ifdef CONFIG_FB_SIS_300
1469    if(SiS_Pr->ChipType == SIS_630) {
1470       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1471    }
1472 #endif
1473 
1474 #if 0
1475    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1476       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1477 #endif
1478 }
1479 
1480 /*********************************************/
1481 /*           DETERMINE YPbPr MODE            */
1482 /*********************************************/
1483 
1484 void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1485 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1486 {
1487 
1488    unsigned char temp;
1489 
1490    /* Note: This variable is only used on 30xLV systems.
1491     * CR38 has a different meaning on LVDS/CH7019 systems.
1492     * On 661 and later, these bits moved to CR35.
1493     *
1494     * On 301, 301B, only HiVision 1080i is supported.
1495     * On 30xLV, 301C, only YPbPr 1080i is supported.
1496     */
1497 
1498    SiS_Pr->SiS_YPbPr = 0;
1499    if(SiS_Pr->ChipType >= SIS_661) return;
1500 
1501    if(SiS_Pr->SiS_VBType) {
1502       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1503 	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1504       }
1505    }
1506 
1507    if(SiS_Pr->ChipType >= SIS_315H) {
1508       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1509 	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1510 	 if(temp & 0x08) {
1511 	    switch((temp >> 4)) {
1512 	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1513 	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1514 	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1515 	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1516 	    }
1517 	 }
1518       }
1519    }
1520 
1521 }
1522 
1523 /*********************************************/
1524 /*           DETERMINE TVMode flag           */
1525 /*********************************************/
1526 
1527 void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1528 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1529 {
1530    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1531    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1532    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1533 
1534    SiS_Pr->SiS_TVMode = 0;
1535 
1536    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1537    if(SiS_Pr->UseCustomMode) return;
1538 
1539    if(ModeNo > 0x13) {
1540       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1541    }
1542 
1543    if(SiS_Pr->ChipType < SIS_661) {
1544 
1545       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1546 
1547       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1548 	 temp = 0;
1549 	 if((SiS_Pr->ChipType == SIS_630) ||
1550 	    (SiS_Pr->ChipType == SIS_730)) {
1551 	    temp = 0x35;
1552 	    romindex = 0xfe;
1553 	 } else if(SiS_Pr->ChipType >= SIS_315H) {
1554 	    temp = 0x38;
1555 	    if(SiS_Pr->ChipType < XGI_20) {
1556 	       romindex = 0xf3;
1557 	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1558 	    }
1559 	 }
1560 	 if(temp) {
1561 	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1562 	       OutputSelect = ROMAddr[romindex];
1563 	       if(!(OutputSelect & EnablePALMN)) {
1564 		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1565 	       }
1566 	    }
1567 	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1568 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1569 	       if(temp1 & EnablePALM) {		/* 0x40 */
1570 		  SiS_Pr->SiS_TVMode |= TVSetPALM;
1571 		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1572 	       } else if(temp1 & EnablePALN) {	/* 0x80 */
1573 		  SiS_Pr->SiS_TVMode |= TVSetPALN;
1574 	       }
1575 	    } else {
1576 	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
1577 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1578 	       }
1579 	    }
1580 	 }
1581 	 /* Translate HiVision/YPbPr to our new flags */
1582 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1583 	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1584 	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1585 	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1586 	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1587 	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1588 	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1589 	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1590 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1591 	       SiS_Pr->SiS_TVMode |= TVSetPAL;
1592 	    }
1593 	 }
1594       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1595 	 if(SiS_Pr->SiS_CHOverScan) {
1596 	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1597 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1598 	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1599 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1600 	       }
1601 	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1602 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1603 	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1604 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1605 	       }
1606 	    }
1607 	    if(SiS_Pr->SiS_CHSOverScan) {
1608 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1609 	    }
1610 	 }
1611 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1612 	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1613 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1614 	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1615 	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1616 	    } else {
1617 	       if(temp & EnableNTSCJ) {
1618 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1619 	       }
1620 	    }
1621 	 }
1622       }
1623 
1624    } else {  /* 661 and later */
1625 
1626       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1627       if(temp1 & 0x01) {
1628 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1629 	 if(temp1 & 0x08) {
1630 	    SiS_Pr->SiS_TVMode |= TVSetPALN;
1631 	 } else if(temp1 & 0x04) {
1632 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1633 	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1634 	    }
1635 	    SiS_Pr->SiS_TVMode |= TVSetPALM;
1636 	 }
1637       } else {
1638 	 if(temp1 & 0x02) {
1639 	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1640 	 }
1641       }
1642       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1643 	 if(SiS_Pr->SiS_CHOverScan) {
1644 	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1645 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1646 	    }
1647 	 }
1648       }
1649       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1650 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1651 	    temp1 &= 0xe0;
1652 	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1653 	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1654 	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1655 	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1656 	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1657 	 }
1658 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1659 	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1660 	       SiS_Pr->SiS_TVMode |= TVAspect169;
1661 	    } else {
1662 	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1663 	       if(temp1 & 0x02) {
1664 		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1665 		     SiS_Pr->SiS_TVMode |= TVAspect169;
1666 		  } else {
1667 		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1668 		  }
1669 	       } else {
1670 		  SiS_Pr->SiS_TVMode |= TVAspect43;
1671 	       }
1672 	    }
1673 	 }
1674       }
1675    }
1676 
1677    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1678 
1679    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1680 
1681       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1682 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1683 	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1684       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1685 	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1686 	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1687 	 }
1688       }
1689 
1690       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1691 	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1692 	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1693 	 }
1694       }
1695 
1696       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1697 	 if(resinfo == SIS_RI_1024x768) {
1698 	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1699 	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
1700 	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1701 	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1702 	    }
1703 	 }
1704       }
1705 
1706       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1707       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1708 	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1709 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1710       } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1711 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1712       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1713 	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1714 	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1715 	 }
1716       }
1717 
1718    }
1719 
1720    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1721 }
1722 
1723 /*********************************************/
1724 /*               GET LCD INFO                */
1725 /*********************************************/
1726 
1727 static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1728 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1729 {
1730    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1731    /* Translate my LCDResInfo to BIOS value */
1732    switch(temp) {
1733    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1734    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1735    case Panel_1280x854:   temp = Panel661_1280x854; break;
1736    }
1737    return temp;
1738 }
1739 
1740 static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1741 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1742 {
1743 #ifdef CONFIG_FB_SIS_315
1744    unsigned char  *ROMAddr;
1745    unsigned short temp;
1746 
1747    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1748       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1749 	 SiS_Pr->SiS_NeedRomModeData = true;
1750 	 SiS_Pr->PanelHT  = temp;
1751       }
1752       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1753 	 SiS_Pr->SiS_NeedRomModeData = true;
1754 	 SiS_Pr->PanelVT  = temp;
1755       }
1756       SiS_Pr->PanelHRS = SISGETROMW(10);
1757       SiS_Pr->PanelHRE = SISGETROMW(12);
1758       SiS_Pr->PanelVRS = SISGETROMW(14);
1759       SiS_Pr->PanelVRE = SISGETROMW(16);
1760       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1761       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1762 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1763       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1764 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1765       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1766 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1767 
1768    }
1769 #endif
1770 }
1771 
1772 static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1773 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1774 			const unsigned char *nonscalingmodes)
1775 {
1776    int i = 0;
1777    while(nonscalingmodes[i] != 0xff) {
1778       if(nonscalingmodes[i++] == resinfo) {
1779 	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1780 	    (SiS_Pr->UsePanelScaler == -1)) {
1781 	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1782 	 }
1783 	 break;
1784       }
1785    }
1786 }
1787 
1788 void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1789 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1790 {
1791   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1792   bool panelcanscale = false;
1793 #ifdef CONFIG_FB_SIS_300
1794   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1795   static const unsigned char SiS300SeriesLCDRes[] =
1796           { 0,  1,  2,  3,  7,  4,  5,  8,
1797 	    0,  0, 10,  0,  0,  0,  0, 15 };
1798 #endif
1799 #ifdef CONFIG_FB_SIS_315
1800   unsigned char   *myptr = NULL;
1801 #endif
1802 
1803   SiS_Pr->SiS_LCDResInfo  = 0;
1804   SiS_Pr->SiS_LCDTypeInfo = 0;
1805   SiS_Pr->SiS_LCDInfo     = 0;
1806   SiS_Pr->PanelHRS        = 999; /* HSync start */
1807   SiS_Pr->PanelHRE        = 999; /* HSync end */
1808   SiS_Pr->PanelVRS        = 999; /* VSync start */
1809   SiS_Pr->PanelVRE        = 999; /* VSync end */
1810   SiS_Pr->SiS_NeedRomModeData = false;
1811 
1812   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1813   SiS_Pr->Alternate1600x1200 = false;
1814 
1815   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1816 
1817   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1818 
1819   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1820      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1821      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1822      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1823   }
1824 
1825   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1826 
1827   /* For broken BIOSes: Assume 1024x768 */
1828   if(temp == 0) temp = 0x02;
1829 
1830   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1831      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1832   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1833      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1834   } else {
1835      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1836   }
1837   temp &= 0x0f;
1838 #ifdef CONFIG_FB_SIS_300
1839   if(SiS_Pr->ChipType < SIS_315H) {
1840      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1841      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1842         if(temp < 0x0f) temp &= 0x07;
1843      }
1844      /* Translate 300 series LCDRes to 315 series for unified usage */
1845      temp = SiS300SeriesLCDRes[temp];
1846   }
1847 #endif
1848 
1849   /* Translate to our internal types */
1850 #ifdef CONFIG_FB_SIS_315
1851   if(SiS_Pr->ChipType == SIS_550) {
1852      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1853      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1854      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1855   } else if(SiS_Pr->ChipType >= SIS_661) {
1856      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1857   }
1858 #endif
1859 
1860   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
1861      if(temp == Panel310_1280x768) {
1862         temp = Panel_1280x768_2;
1863      }
1864      if(SiS_Pr->SiS_ROMNew) {
1865 	if(temp == Panel661_1280x800) {
1866 	   temp = Panel_1280x800_2;
1867 	}
1868      }
1869   }
1870 
1871   SiS_Pr->SiS_LCDResInfo = temp;
1872 
1873 #ifdef CONFIG_FB_SIS_300
1874   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1875      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1876 	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1877      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1878 	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1879      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1880 	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1881      }
1882   }
1883 #endif
1884 
1885   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1886      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1887 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1888   } else {
1889      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1890 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1891   }
1892 
1893   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1894   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1895   /* Need temp below! */
1896 
1897   /* These must/can't scale no matter what */
1898   switch(SiS_Pr->SiS_LCDResInfo) {
1899   case Panel_320x240_1:
1900   case Panel_320x240_2:
1901   case Panel_320x240_3:
1902   case Panel_1280x960:
1903       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1904       break;
1905   case Panel_640x480:
1906       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1907   }
1908 
1909   panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1910 
1911   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1912   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1913 
1914   /* Dual link, Pass 1:1 BIOS default, etc. */
1915 #ifdef CONFIG_FB_SIS_315
1916   if(SiS_Pr->ChipType >= SIS_661) {
1917      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1918 	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1919      }
1920      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1921 	if(SiS_Pr->SiS_ROMNew) {
1922 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1923 	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1924 	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1925 	}
1926      }
1927   } else if(SiS_Pr->ChipType >= SIS_315H) {
1928      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1929 	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1930      }
1931      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1932 	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1933 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1934 	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1935 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1936 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1937 	}
1938      } else if(!(SiS_Pr->SiS_ROMNew)) {
1939 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1940 	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1941 	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1942 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1943 	   }
1944 	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1945 	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1946 	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1947 	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1948 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1949 	   }
1950 	}
1951      }
1952   }
1953 #endif
1954 
1955   /* Pass 1:1 */
1956   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1957      /* Always center screen on LVDS (if scaling is disabled) */
1958      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1959   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1960      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1961 	/* Always center screen on SiS LVDS (if scaling is disabled) */
1962 	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1963      } else {
1964 	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1965 	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1966 	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1967      }
1968   }
1969 
1970   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1971   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1972 
1973   switch(SiS_Pr->SiS_LCDResInfo) {
1974      case Panel_320x240_1:
1975      case Panel_320x240_2:
1976      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1977 			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1978 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1979 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1980 			    break;
1981      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1982 						      SiS_Pr->PanelVRE  =    3;
1983 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1984 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1985 			    break;
1986      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1987      			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1988 			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1989 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1990 			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1991 			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1992 			    break;
1993      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1994 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1995 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1996 			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1997 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1998 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1999 			    break;
2000      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2001 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2002 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2003 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2004 			    if(SiS_Pr->ChipType < SIS_315H) {
2005 			       SiS_Pr->PanelHRS = 23;
2006 						      SiS_Pr->PanelVRE  =    5;
2007 			    }
2008 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2009 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2010 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2011 			    break;
2012      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
2013 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2014 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2015 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2016 			    if(SiS_Pr->ChipType < SIS_315H) {
2017 			       SiS_Pr->PanelHRS = 23;
2018 						      SiS_Pr->PanelVRE  =    5;
2019 			    }
2020 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2021 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2022 			    break;
2023      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
2024 			    break;
2025      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
2026 			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
2027 			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
2028 			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
2029 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2030 			    /* Data above for TMDS (projector); get from BIOS for LVDS */
2031 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2032 			    break;
2033      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2034 			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2035 			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
2036 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2037 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2038 			    } else {
2039 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
2040 			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2041 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2042 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2043 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2044 			    }
2045 			    break;
2046      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2047 			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
2048 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2049 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2050 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2051 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2052 			    break;
2053      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2054 			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
2055 			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
2056 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2057 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2058 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2059 			    break;
2060      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2061 			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
2062 			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
2063 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2064 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2065 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2066 			    break;
2067      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
2068 			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
2069 			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
2070 			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
2071 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2072 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2073 			    break;
2074      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
2075 			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
2076 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2077 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2078 			    if(resinfo == SIS_RI_1280x1024) {
2079 			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2080 			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2081 			    }
2082 			    break;
2083      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2084 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2085 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2086 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2087 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2088 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2089 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2090 			    break;
2091      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2092 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2093 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2094 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2095 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2096 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2097 			    break;
2098      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2099 			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
2100 			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
2101 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2102 			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2103 			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2104 			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2105 				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
2106 				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
2107 				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
2108 				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2109 				  SiS_Pr->Alternate1600x1200 = true;
2110 			       }
2111 			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2112 			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
2113 			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2114 			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2115 			    }
2116 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2117 			    break;
2118      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2119 			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
2120 			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
2121 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2122 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2123 			    SiS_GetLCDInfoBIOS(SiS_Pr);
2124 			    break;
2125      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2126 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2127 			    break;
2128      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
2129 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2130 			    break;
2131      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
2132 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2133 			    break;
2134      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2135 			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2136 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
2137 			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
2138 			    if(SiS_Pr->CP_PreferredIndex != -1) {
2139 			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2140 			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2141 			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2142 			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2143 			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2144 			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2145 			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2146 			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2147 			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2148 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2149 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2150 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2151 			       if(SiS_Pr->CP_PrefClock) {
2152 				  int idx;
2153 				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2154 				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2155 				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2156 				  else				   idx = VCLK_CUSTOM_315;
2157 				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
2158 				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2159 				  SiS_Pr->SiS_VCLKData[idx].SR2B =
2160 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2161 				  SiS_Pr->SiS_VCLKData[idx].SR2C =
2162 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2163 			       }
2164 			    }
2165 			    break;
2166      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2167 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2168 			    break;
2169   }
2170 
2171   /* Special cases */
2172   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
2173       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
2174       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2175       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2176       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2177       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2178      SiS_Pr->PanelHRS = 999;
2179      SiS_Pr->PanelHRE = 999;
2180   }
2181 
2182   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2183       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2184       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2185       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2186      SiS_Pr->PanelVRS = 999;
2187      SiS_Pr->PanelVRE = 999;
2188   }
2189 
2190   /* DontExpand overrule */
2191   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2192 
2193      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2194 	/* No scaling for this mode on any panel (LCD=CRT2)*/
2195 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2196      }
2197 
2198      switch(SiS_Pr->SiS_LCDResInfo) {
2199 
2200      case Panel_Custom:
2201      case Panel_1152x864:
2202      case Panel_1280x768:	/* TMDS only */
2203 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2204 	break;
2205 
2206      case Panel_800x600: {
2207 	static const unsigned char nonscalingmodes[] = {
2208 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2209 	};
2210 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2211 	break;
2212      }
2213      case Panel_1024x768: {
2214 	static const unsigned char nonscalingmodes[] = {
2215 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2216 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2217 	   0xff
2218 	};
2219 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2220 	break;
2221      }
2222      case Panel_1280x720: {
2223 	static const unsigned char nonscalingmodes[] = {
2224 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2225 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2226 	   0xff
2227 	};
2228 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2229 	if(SiS_Pr->PanelHT == 1650) {
2230 	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2231 	}
2232 	break;
2233      }
2234      case Panel_1280x768_2: {  /* LVDS only */
2235 	static const unsigned char nonscalingmodes[] = {
2236 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2237 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2238 	   SIS_RI_1152x768,0xff
2239 	};
2240 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2241 	switch(resinfo) {
2242 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2243 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2244 			       }
2245 			       break;
2246 	}
2247 	break;
2248      }
2249      case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
2250 	static const unsigned char nonscalingmodes[] = {
2251 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2252 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2253 	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2254 	};
2255 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2256 	break;
2257      }
2258      case Panel_1280x800_2:  { 	/* SiS LVDS */
2259 	static const unsigned char nonscalingmodes[] = {
2260 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2261 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2262 	   SIS_RI_1152x768,0xff
2263 	};
2264 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2265 	switch(resinfo) {
2266 	case SIS_RI_1280x720:
2267 	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
2268 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2269 			       }
2270 			       break;
2271 	}
2272 	break;
2273      }
2274      case Panel_1280x854: {  	/* SiS LVDS */
2275 	static const unsigned char nonscalingmodes[] = {
2276 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2277 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2278 	   SIS_RI_1152x768,0xff
2279 	};
2280 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2281 	switch(resinfo) {
2282 	case SIS_RI_1280x720:
2283 	case SIS_RI_1280x768:
2284 	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2285 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2286 			       }
2287 			       break;
2288 	}
2289 	break;
2290      }
2291      case Panel_1280x960: {
2292 	static const unsigned char nonscalingmodes[] = {
2293 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2294 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2295 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2296 	   SIS_RI_1280x854,0xff
2297 	};
2298 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2299 	break;
2300      }
2301      case Panel_1280x1024: {
2302 	static const unsigned char nonscalingmodes[] = {
2303 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2304 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2305 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2306 	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
2307 	};
2308 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2309 	break;
2310      }
2311      case Panel_1400x1050: {
2312 	static const unsigned char nonscalingmodes[] = {
2313 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2314 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2315 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2316 	     SIS_RI_1280x960,0xff
2317 	};
2318 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2319 	switch(resinfo) {
2320 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2321 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2322 			       }
2323 			       break;
2324 	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2325 			       break;
2326 	}
2327 	break;
2328      }
2329      case Panel_1600x1200: {
2330 	static const unsigned char nonscalingmodes[] = {
2331 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2332 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2333 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2334 	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2335 	};
2336 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2337 	break;
2338      }
2339      case Panel_1680x1050: {
2340 	static const unsigned char nonscalingmodes[] = {
2341 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2342 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2343 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2344 	     SIS_RI_1360x1024,0xff
2345 	};
2346 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2347 	break;
2348      }
2349      }
2350   }
2351 
2352 #ifdef CONFIG_FB_SIS_300
2353   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2354      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2355 	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2356      }
2357   }
2358 
2359   if(SiS_Pr->ChipType < SIS_315H) {
2360      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2361 	if(SiS_Pr->SiS_UseROM) {
2362 	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2363 	      if(!(ROMAddr[0x235] & 0x02)) {
2364 		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2365 	      }
2366 	   }
2367 	}
2368      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2369 	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2370 	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2371 	}
2372      }
2373   }
2374 #endif
2375 
2376   /* Special cases */
2377 
2378   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2379      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2380   }
2381 
2382   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2383      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2384   }
2385 
2386   switch(SiS_Pr->SiS_LCDResInfo) {
2387   case Panel_640x480:
2388      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2389      break;
2390   case Panel_1280x800:
2391      /* Don't pass 1:1 by default (TMDS special) */
2392      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2393      break;
2394   case Panel_1280x960:
2395      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2396      break;
2397   case Panel_Custom:
2398      if((!SiS_Pr->CP_PrefClock) ||
2399         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2400         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2401      }
2402      break;
2403   }
2404 
2405   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2406      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2407   }
2408 
2409   /* (In)validate LCDPass11 flag */
2410   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2411      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2412   }
2413 
2414   /* LVDS DDA */
2415   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2416 
2417      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2418 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2419 	   if(ModeNo == 0x12) {
2420 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2421 		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2422 	      }
2423 	   } else if(ModeNo > 0x13) {
2424 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2425 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2426 		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2427 		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2428 		    }
2429 		 }
2430 	      }
2431 	   }
2432 	}
2433      }
2434 
2435      if(modeflag & HalfDCLK) {
2436 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2437 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2438 	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2439 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2440 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2441 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2442 	} else if(ModeNo > 0x13) {
2443 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2444 	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2445 	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2446 	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2447 	   }
2448 	}
2449      }
2450 
2451   }
2452 
2453   /* VESA timing */
2454   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2455      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2456 	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2457      }
2458   } else {
2459      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2460   }
2461 
2462 #if 0
2463   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2464 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2465 #endif
2466 }
2467 
2468 /*********************************************/
2469 /*                 GET VCLK                  */
2470 /*********************************************/
2471 
2472 unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2473 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2474 		unsigned short RefreshRateTableIndex)
2475 {
2476   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2477   unsigned short resinfo, tempbx;
2478   const unsigned char *CHTVVCLKPtr = NULL;
2479 
2480   if(ModeNo <= 0x13) {
2481      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2482      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2483      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2484      VCLKIndexGENCRT = VCLKIndexGEN;
2485   } else {
2486      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2487      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2488      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2489      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2490 		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2491   }
2492 
2493   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2494 
2495      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2496 
2497 	CRT2Index >>= 6;
2498 	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2499 
2500 	   if(SiS_Pr->ChipType < SIS_315H) {
2501 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2502 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2503 		 VCLKIndex = VCLKIndexGEN;
2504 	      }
2505 	   } else {
2506 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2507 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2508 		 switch(resinfo) {
2509 		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2510 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2511 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2512 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2513 		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2514 		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2515 		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2516 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2517 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2518 		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2519 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2520 		 default:              VCLKIndex = VCLKIndexGEN;
2521 		 }
2522 
2523 		 if(ModeNo <= 0x13) {
2524 		    if(SiS_Pr->ChipType <= SIS_315PRO) {
2525 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2526 		    } else {
2527 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2528 		    }
2529 		 }
2530 		 if(SiS_Pr->ChipType <= SIS_315PRO) {
2531 		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2532 		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2533 		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2534 		 }
2535 	      }
2536 	   }
2537 
2538 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2539 
2540 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2541 	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
2542 	      else                                  	   VCLKIndex = HiTVVCLK;
2543 	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2544 	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2545 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2546 	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2547 	   else						   VCLKIndex = TVVCLK;
2548 
2549 	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2550 	   else				   VCLKIndex += TVCLKBASE_315;
2551 
2552 	} else {							/* VGA2 */
2553 
2554 	   VCLKIndex = VCLKIndexGENCRT;
2555 	   if(SiS_Pr->ChipType < SIS_315H) {
2556 	      if(ModeNo > 0x13) {
2557 		 if( (SiS_Pr->ChipType == SIS_630) &&
2558 		     (SiS_Pr->ChipRevision >= 0x30)) {
2559 		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2560 		 }
2561 		 /* Better VGA2 clock for 1280x1024@75 */
2562 		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2563 	      }
2564 	   }
2565 	}
2566 
2567      } else {   /* If not programming CRT2 */
2568 
2569 	VCLKIndex = VCLKIndexGENCRT;
2570 	if(SiS_Pr->ChipType < SIS_315H) {
2571 	   if(ModeNo > 0x13) {
2572 	      if( (SiS_Pr->ChipType != SIS_630) &&
2573 		  (SiS_Pr->ChipType != SIS_300) ) {
2574 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2575 	      }
2576 	   }
2577 	}
2578      }
2579 
2580   } else {       /*   LVDS  */
2581 
2582      VCLKIndex = CRT2Index;
2583 
2584      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2585 
2586 	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2587 
2588 	   VCLKIndex &= 0x1f;
2589 	   tempbx = 0;
2590 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2591 	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2592 	      tempbx += 2;
2593 	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2594 		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2595 	      }
2596 	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2597 		 tempbx = 4;
2598 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2599 	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2600 		 tempbx = 6;
2601 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2602 	      }
2603 	   }
2604 	   switch(tempbx) {
2605 	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2606 	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2607 	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2608 	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2609 	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2610 	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2611 	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2612 	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2613 	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2614 	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2615 	   }
2616 	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2617 
2618 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2619 
2620 	   if(SiS_Pr->ChipType < SIS_315H) {
2621 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2622 	   } else {
2623 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2624 	   }
2625 
2626 #ifdef CONFIG_FB_SIS_300
2627 	   /* Special Timing: Barco iQ Pro R series */
2628 	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2629 
2630 	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2631 	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2632 	      if(SiS_Pr->ChipType < SIS_315H) {
2633 		 VCLKIndex = VCLK34_300;
2634 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2635 	      } else {
2636 		 VCLKIndex = VCLK34_315;
2637 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2638 	      }
2639 	   }
2640 #endif
2641 
2642 	} else {
2643 
2644 	   VCLKIndex = VCLKIndexGENCRT;
2645 	   if(SiS_Pr->ChipType < SIS_315H) {
2646 	      if(ModeNo > 0x13) {
2647 		 if( (SiS_Pr->ChipType == SIS_630) &&
2648 		     (SiS_Pr->ChipRevision >= 0x30) ) {
2649 		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2650 		 }
2651 	      }
2652 	   }
2653 	}
2654 
2655      } else {  /* if not programming CRT2 */
2656 
2657 	VCLKIndex = VCLKIndexGENCRT;
2658 	if(SiS_Pr->ChipType < SIS_315H) {
2659 	   if(ModeNo > 0x13) {
2660 	      if( (SiS_Pr->ChipType != SIS_630) &&
2661 		  (SiS_Pr->ChipType != SIS_300) ) {
2662 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2663 	      }
2664 #if 0
2665 	      if(SiS_Pr->ChipType == SIS_730) {
2666 		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2667 		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2668 	      }
2669 #endif
2670 	   }
2671         }
2672 
2673      }
2674 
2675   }
2676 
2677   return VCLKIndex;
2678 }
2679 
2680 /*********************************************/
2681 /*        SET CRT2 MODE TYPE REGISTERS       */
2682 /*********************************************/
2683 
2684 static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2685 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2686 {
2687   unsigned short i, j, modeflag, tempah=0;
2688   short tempcl;
2689 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2690   unsigned short tempbl;
2691 #endif
2692 #ifdef CONFIG_FB_SIS_315
2693   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2694   unsigned short tempah2, tempbl2;
2695 #endif
2696 
2697   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2698 
2699   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2700 
2701      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2702      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2703 
2704   } else {
2705 
2706      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2707      if(SiS_Pr->ChipType >= SIS_315H) {
2708         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2709      }
2710 
2711      tempcl = SiS_Pr->SiS_ModeType;
2712 
2713      if(SiS_Pr->ChipType < SIS_315H) {
2714 
2715 #ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
2716 
2717 	/* For 301BDH: (with LCD via LVDS) */
2718 	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2719 	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2720 	   tempbl &= 0xef;
2721 	   tempbl |= 0x02;
2722 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2723 	      tempbl |= 0x10;
2724 	      tempbl &= 0xfd;
2725 	   }
2726 	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2727 	}
2728 
2729 	if(ModeNo > 0x13) {
2730 	   tempcl -= ModeVGA;
2731 	   if(tempcl >= 0) {
2732 	      tempah = ((0x10 >> tempcl) | 0x80);
2733 	   }
2734 	} else tempah = 0x80;
2735 
2736 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2737 
2738 #endif  /* CONFIG_FB_SIS_300 */
2739 
2740      } else {
2741 
2742 #ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
2743 
2744 	if(ModeNo > 0x13) {
2745 	   tempcl -= ModeVGA;
2746 	   if(tempcl >= 0) {
2747 	      tempah = (0x08 >> tempcl);
2748 	      if (tempah == 0) tempah = 1;
2749 	      tempah |= 0x40;
2750 	   }
2751 	} else tempah = 0x40;
2752 
2753 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2754 
2755 #endif  /* CONFIG_FB_SIS_315 */
2756 
2757      }
2758 
2759      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2760 
2761      if(SiS_Pr->ChipType < SIS_315H) {
2762 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2763      } else {
2764 #ifdef CONFIG_FB_SIS_315
2765 	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2766 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2767 	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2768 	   if(IS_SIS740) {
2769 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2770 	   } else {
2771 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2772 	   }
2773 	}
2774 #endif
2775      }
2776 
2777      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2778 
2779 	tempah = 0x01;
2780 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2781 	   tempah |= 0x02;
2782 	}
2783 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2784 	   tempah ^= 0x05;
2785 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2786 	      tempah ^= 0x01;
2787 	   }
2788 	}
2789 
2790 	if(SiS_Pr->ChipType < SIS_315H) {
2791 
2792 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2793 
2794 	   tempah = (tempah << 5) & 0xFF;
2795 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2796 	   tempah = (tempah >> 5) & 0xFF;
2797 
2798 	} else {
2799 
2800 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2801 	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2802 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2803 	   tempah &= ~0x08;
2804 
2805 	}
2806 
2807 	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2808 	   tempah |= 0x10;
2809 	}
2810 
2811 	tempah |= 0x80;
2812 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2813 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2814 	}
2815 
2816 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2817 	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2818 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2819 		 tempah |= 0x20;
2820 	      }
2821 	   }
2822 	}
2823 
2824 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2825 
2826 	tempah = 0x80;
2827 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2828 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2829 	}
2830 
2831 	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2832 
2833 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2834 	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2835 	      tempah |= 0x40;
2836 	   }
2837 	}
2838 
2839 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2840 
2841      } else {  /* LVDS */
2842 
2843 	if(SiS_Pr->ChipType >= SIS_315H) {
2844 
2845 #ifdef CONFIG_FB_SIS_315
2846 	   /* LVDS can only be slave in 8bpp modes */
2847 	   tempah = 0x80;
2848 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2849 	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2850 	         tempah |= 0x02;
2851 	      }
2852 	   }
2853 
2854 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2855 
2856 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2857 
2858 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2859 
2860 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2861 #endif
2862 
2863 	} else {
2864 
2865 #ifdef CONFIG_FB_SIS_300
2866 	   tempah = 0;
2867 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2868 	      tempah |= 0x02;
2869 	   }
2870 	   tempah <<= 5;
2871 
2872 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2873 
2874 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2875 #endif
2876 
2877 	}
2878 
2879      }
2880 
2881   }  /* LCDA */
2882 
2883   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2884 
2885      if(SiS_Pr->ChipType >= SIS_315H) {
2886 
2887 #ifdef CONFIG_FB_SIS_315
2888 	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2889 
2890 	/* The following is nearly unpreditable and varies from machine
2891 	 * to machine. Especially the 301DH seems to be a real trouble
2892 	 * maker. Some BIOSes simply set the registers (like in the
2893 	 * NoLCD-if-statements here), some set them according to the
2894 	 * LCDA stuff. It is very likely that some machines are not
2895 	 * treated correctly in the following, very case-orientated
2896 	 * code. What do I do then...?
2897 	 */
2898 
2899 	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2900 
2901 	if(!(IS_SIS740)) {
2902 	   tempah = 0x04;						   /* For all bridges */
2903 	   tempbl = 0xfb;
2904 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2905 	      tempah = 0x00;
2906 	      if(SiS_IsDualEdge(SiS_Pr)) {
2907 	         tempbl = 0xff;
2908 	      }
2909 	   }
2910 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2911 	}
2912 
2913 	/* The following two are responsible for eventually wrong colors
2914 	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2915 	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2916 	 * in a 650 box (Jake). What is the criteria?
2917 	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2918 	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2919 	 * chipset than the bridge revision.
2920 	 */
2921 
2922 	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2923 	   tempah = 0x30;
2924 	   tempbl = 0xc0;
2925 	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2926 	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2927 	      tempah = 0x00;
2928 	      tempbl = 0x00;
2929 	   }
2930 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2931 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2932 	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2933 	   /* Fixes "TV-blue-bug" on 315+301 */
2934 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
2935 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2936 	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2937 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
2938 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2939 	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
2940 	   tempah = 0x30; tempah2 = 0xc0;
2941 	   tempbl = 0xcf; tempbl2 = 0x3f;
2942 	   if(SiS_Pr->SiS_TVBlue == 0) {
2943 	         tempah = tempah2 = 0x00;
2944 	   } else if(SiS_Pr->SiS_TVBlue == -1) {
2945 	      /* Set on 651/M650, clear on 315/650 */
2946 	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2947 	         tempah = tempah2 = 0x00;
2948 	      }
2949 	   }
2950 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2951 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2952 	} else {
2953 	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
2954 	   tempbl = 0xcf; tempbl2 = 0x3f;
2955 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2956 	      tempah = tempah2 = 0x00;
2957 	      if(SiS_IsDualEdge(SiS_Pr)) {
2958 		 tempbl = tempbl2 = 0xff;
2959 	      }
2960 	   }
2961 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2962 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2963 	}
2964 
2965 	if(IS_SIS740) {
2966 	   tempah = 0x80;
2967 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2968 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2969 	} else {
2970 	   tempah = 0x00;
2971 	   tempbl = 0x7f;
2972 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2973 	      tempbl = 0xff;
2974 	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2975 	   }
2976 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2977 	}
2978 
2979 #endif /* CONFIG_FB_SIS_315 */
2980 
2981      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2982 
2983 #ifdef CONFIG_FB_SIS_300
2984 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2985 
2986 	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2987 	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2988 	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2989 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2990 	} else {
2991 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2992 	}
2993 #endif
2994 
2995      }
2996 
2997      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2998 	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2999 	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3000 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3001         }
3002      }
3003 
3004   } else {  /* LVDS */
3005 
3006 #ifdef CONFIG_FB_SIS_315
3007      if(SiS_Pr->ChipType >= SIS_315H) {
3008 
3009 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3010 
3011 	   tempah = 0x04;
3012 	   tempbl = 0xfb;
3013 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3014 	      tempah = 0x00;
3015 	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3016 	   }
3017 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3018 
3019 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3020 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3021 	   }
3022 
3023 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3024 
3025 	} else if(SiS_Pr->ChipType == SIS_550) {
3026 
3027 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3028 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3029 
3030 	}
3031 
3032      }
3033 #endif
3034 
3035   }
3036 
3037 }
3038 
3039 /*********************************************/
3040 /*            GET RESOLUTION DATA            */
3041 /*********************************************/
3042 
3043 unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3044 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3045 {
3046    if(ModeNo <= 0x13)
3047       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3048    else
3049       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3050 }
3051 
3052 static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3053 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3054 {
3055    unsigned short xres, yres, modeflag=0, resindex;
3056 
3057    if(SiS_Pr->UseCustomMode) {
3058       xres = SiS_Pr->CHDisplay;
3059       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3060       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3061       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3062       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3063       return;
3064    }
3065 
3066    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3067 
3068    if(ModeNo <= 0x13) {
3069       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3070       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3071    } else {
3072       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3073       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3074       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3075    }
3076 
3077    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3078 
3079       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3080 	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3081 	    if(yres == 350) yres = 400;
3082 	 }
3083 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3084 	    if(ModeNo == 0x12) yres = 400;
3085 	 }
3086       }
3087 
3088       if(modeflag & HalfDCLK)       xres <<= 1;
3089       if(modeflag & DoubleScanMode) yres <<= 1;
3090 
3091    }
3092 
3093    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3094 
3095       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3096 	 switch(SiS_Pr->SiS_LCDResInfo) {
3097 	   case Panel_1024x768:
3098 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3099 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3100 		    if(yres == 350) yres = 357;
3101 		    if(yres == 400) yres = 420;
3102 		    if(yres == 480) yres = 525;
3103 		 }
3104 	      }
3105 	      break;
3106 	   case Panel_1280x1024:
3107 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3108 		 /* BIOS bug - does this regardless of scaling */
3109 		 if(yres == 400) yres = 405;
3110 	      }
3111 	      if(yres == 350) yres = 360;
3112 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3113 		 if(yres == 360) yres = 375;
3114 	      }
3115 	      break;
3116 	   case Panel_1600x1200:
3117 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3118 		 if(yres == 1024) yres = 1056;
3119 	      }
3120 	      break;
3121 	 }
3122       }
3123 
3124    } else {
3125 
3126       if(SiS_Pr->SiS_VBType & VB_SISVB) {
3127 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3128 	    if(xres == 720) xres = 640;
3129 	 }
3130       } else if(xres == 720) xres = 640;
3131 
3132       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3133 	 yres = 400;
3134 	 if(SiS_Pr->ChipType >= SIS_315H) {
3135 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3136 	 } else {
3137 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3138 	 }
3139 	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3140       }
3141 
3142    }
3143    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3144    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3145 }
3146 
3147 /*********************************************/
3148 /*           GET CRT2 TIMING DATA            */
3149 /*********************************************/
3150 
3151 static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)3152 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3153 	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3154 	       unsigned short *ResIndex)
3155 {
3156   unsigned short tempbx=0, tempal=0, resinfo=0;
3157 
3158   if(ModeNo <= 0x13) {
3159      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3160   } else {
3161      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3162      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3163   }
3164 
3165   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3166 
3167      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
3168 
3169 	tempbx = SiS_Pr->SiS_LCDResInfo;
3170 	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3171 
3172 	/* patch index */
3173 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3174 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
3175 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3176 	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3177 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3178 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3179 	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
3180 	}
3181 
3182 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3183 	   /* Pass 1:1 only (center-screen handled outside) */
3184 	   /* This is never called for the panel's native resolution */
3185 	   /* since Pass1:1 will not be set in this case */
3186 	   tempbx = 100;
3187 	   if(ModeNo >= 0x13) {
3188 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3189 	   }
3190 	}
3191 
3192 #ifdef CONFIG_FB_SIS_315
3193 	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3194 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3195 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3196 		 tempbx = 200;
3197 		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3198 	      }
3199 	   }
3200 	}
3201 #endif
3202 
3203      } else {						  	/* TV */
3204 
3205 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3206 	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3207 	   tempbx = 2;
3208 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3209 	      tempbx = 13;
3210 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3211 	   }
3212 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3213 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
3214 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
3215 	   else						tempbx = 5;
3216 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3217 	} else {
3218 	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
3219 	   else						tempbx = 4;
3220 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3221 	}
3222 
3223      }
3224 
3225      tempal &= 0x3F;
3226 
3227      if(ModeNo > 0x13) {
3228         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3229 	   switch(resinfo) {
3230 	   case SIS_RI_720x480:
3231 	      tempal = 6;
3232 	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
3233 	      break;
3234 	   case SIS_RI_720x576:
3235 	   case SIS_RI_768x576:
3236 	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3237 	      tempal = 6;
3238 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3239 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
3240 	      }
3241 	      break;
3242 	   case SIS_RI_800x480:
3243 	      tempal = 4;
3244 	      break;
3245 	   case SIS_RI_512x384:
3246 	   case SIS_RI_1024x768:
3247 	      tempal = 7;
3248 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3249 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
3250 	      }
3251 	      break;
3252 	   case SIS_RI_1280x720:
3253 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3254 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
3255 	      }
3256 	      break;
3257 	   }
3258 	}
3259      }
3260 
3261      *CRT2Index = tempbx;
3262      *ResIndex = tempal;
3263 
3264   } else {   /* LVDS, 301B-DH (if running on LCD) */
3265 
3266      tempbx = 0;
3267      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3268 
3269 	tempbx = 90;
3270 	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3271 	   tempbx = 92;
3272 	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
3273 	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3274 	   }
3275 	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3276 	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3277 	}
3278 	if(tempbx != 99) {
3279 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3280 	}
3281 
3282      } else {
3283 
3284 	switch(SiS_Pr->SiS_LCDResInfo) {
3285 	case Panel_640x480:   tempbx = 12; break;
3286 	case Panel_320x240_1: tempbx = 10; break;
3287 	case Panel_320x240_2:
3288 	case Panel_320x240_3: tempbx = 14; break;
3289 	case Panel_800x600:   tempbx = 16; break;
3290 	case Panel_1024x600:  tempbx = 18; break;
3291 	case Panel_1152x768:
3292 	case Panel_1024x768:  tempbx = 20; break;
3293 	case Panel_1280x768:  tempbx = 22; break;
3294 	case Panel_1280x1024: tempbx = 24; break;
3295 	case Panel_1400x1050: tempbx = 26; break;
3296 	case Panel_1600x1200: tempbx = 28; break;
3297 #ifdef CONFIG_FB_SIS_300
3298 	case Panel_Barco1366: tempbx = 80; break;
3299 #endif
3300 	}
3301 
3302 	switch(SiS_Pr->SiS_LCDResInfo) {
3303 	case Panel_320x240_1:
3304 	case Panel_320x240_2:
3305 	case Panel_320x240_3:
3306 	case Panel_640x480:
3307 	   break;
3308 	default:
3309 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3310 	}
3311 
3312 	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3313 
3314 #ifdef CONFIG_FB_SIS_300
3315 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3316 	   tempbx = 82;
3317 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3318 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3319 	   tempbx = 84;
3320 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3321 	}
3322 #endif
3323 
3324      }
3325 
3326      (*CRT2Index) = tempbx;
3327      (*ResIndex) = tempal & 0x1F;
3328   }
3329 }
3330 
3331 static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3332 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3333 		unsigned short RefreshRateTableIndex)
3334 {
3335   unsigned short tempax=0, tempbx=0, index, dotclock;
3336   unsigned short temp1=0, modeflag=0, tempcx=0;
3337 
3338   SiS_Pr->SiS_RVBHCMAX  = 1;
3339   SiS_Pr->SiS_RVBHCFACT = 1;
3340 
3341   if(ModeNo <= 0x13) {
3342 
3343      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3344      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3345 
3346      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3347      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3348      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3349 
3350      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3351 
3352   } else {
3353 
3354      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3355      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3356 
3357      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3358      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3359      tempax &= 0x03FF;
3360      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3361      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3362      tempcx &= 0x0100;
3363      tempcx <<= 2;
3364      tempbx |= tempcx;
3365      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3366 
3367      dotclock = 8;
3368 
3369   }
3370 
3371   if(temp1 & 0x01) tempbx |= 0x0100;
3372   if(temp1 & 0x20) tempbx |= 0x0200;
3373 
3374   tempax += 5;
3375   tempax *= dotclock;
3376   if(modeflag & HalfDCLK) tempax <<= 1;
3377 
3378   tempbx++;
3379 
3380   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3381   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3382 }
3383 
3384 static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3385 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3386 		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3387 {
3388    unsigned short ResIndex;
3389 
3390    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3391       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3392 	 if(SiS_Pr->UseCustomMode) {
3393 	    ResIndex = SiS_Pr->CHTotal;
3394 	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3395 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3396 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3397 	 } else {
3398 	    if(ModeNo < 0x13) {
3399 	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3400 	    } else {
3401 	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3402 	    }
3403 	    if(ResIndex == 0x09) {
3404 	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3405 	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3406 	    }
3407 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3408 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3409 	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3410 	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3411 	 }
3412       } else {
3413 	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3414 	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3415       }
3416    } else {
3417       /* This handles custom modes and custom panels */
3418       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3419       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3420       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3421       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3422       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3423       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3424    }
3425 }
3426 
3427 static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3428 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3429                     unsigned short RefreshRateTableIndex)
3430 {
3431    unsigned short CRT2Index, ResIndex, backup;
3432    const struct SiS_LVDSData *LVDSData = NULL;
3433 
3434    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3435 
3436    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3437       SiS_Pr->SiS_RVBHCMAX  = 1;
3438       SiS_Pr->SiS_RVBHCFACT = 1;
3439       SiS_Pr->SiS_NewFlickerMode = 0;
3440       SiS_Pr->SiS_RVBHRS = 50;
3441       SiS_Pr->SiS_RY1COE = 0;
3442       SiS_Pr->SiS_RY2COE = 0;
3443       SiS_Pr->SiS_RY3COE = 0;
3444       SiS_Pr->SiS_RY4COE = 0;
3445       SiS_Pr->SiS_RVBHRS2 = 0;
3446    }
3447 
3448    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3449 
3450 #ifdef CONFIG_FB_SIS_315
3451       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3452       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3453 #endif
3454 
3455    } else {
3456 
3457       /* 301BDH needs LVDS Data */
3458       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3459       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3460 	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3461       }
3462 
3463       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3464                      		            &CRT2Index, &ResIndex);
3465 
3466       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3467 
3468       switch(CRT2Index) {
3469 	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3470 	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3471 	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3472 	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3473 	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3474 	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3475 #ifdef CONFIG_FB_SIS_300
3476 	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3477 	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3478 	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3479 	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3480 	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3481 #endif
3482 	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3483 	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3484 	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3485 	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3486 	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3487 	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3488 	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3489 	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3490 	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
3491       }
3492 
3493       if(LVDSData) {
3494 	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3495 	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3496 	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3497 	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3498       } else {
3499 	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3500       }
3501 
3502       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3503 	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3504 	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3505 	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3506 	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3507 	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3508             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3509 #ifdef CONFIG_FB_SIS_300
3510 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3511 	       if(ResIndex < 0x08) {
3512 		  SiS_Pr->SiS_HDE = 1280;
3513 		  SiS_Pr->SiS_VDE = 1024;
3514 	       }
3515 	    }
3516 #endif
3517          }
3518       }
3519    }
3520 }
3521 
3522 static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3523 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3524 		unsigned short RefreshRateTableIndex)
3525 {
3526   unsigned char  *ROMAddr = NULL;
3527   unsigned short tempax, tempbx, modeflag, romptr=0;
3528   unsigned short resinfo, CRT2Index, ResIndex;
3529   const struct SiS_LCDData *LCDPtr = NULL;
3530   const struct SiS_TVData  *TVPtr  = NULL;
3531 #ifdef CONFIG_FB_SIS_315
3532   short resinfo661;
3533 #endif
3534 
3535   if(ModeNo <= 0x13) {
3536      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3537      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3538   } else if(SiS_Pr->UseCustomMode) {
3539      modeflag = SiS_Pr->CModeFlag;
3540      resinfo = 0;
3541   } else {
3542      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3543      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3544 #ifdef CONFIG_FB_SIS_315
3545      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3546      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3547 	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3548 	 (resinfo661 >= 0)                     &&
3549 	 (SiS_Pr->SiS_NeedRomModeData) ) {
3550 	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3551 	   if((romptr = (SISGETROMW(21)))) {
3552 	      romptr += (resinfo661 * 10);
3553 	      ROMAddr = SiS_Pr->VirtualRomBase;
3554 	   }
3555 	}
3556      }
3557 #endif
3558   }
3559 
3560   SiS_Pr->SiS_NewFlickerMode = 0;
3561   SiS_Pr->SiS_RVBHRS = 50;
3562   SiS_Pr->SiS_RY1COE = 0;
3563   SiS_Pr->SiS_RY2COE = 0;
3564   SiS_Pr->SiS_RY3COE = 0;
3565   SiS_Pr->SiS_RY4COE = 0;
3566   SiS_Pr->SiS_RVBHRS2 = 0;
3567 
3568   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3569 
3570   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3571 
3572      if(SiS_Pr->UseCustomMode) {
3573 
3574 	SiS_Pr->SiS_RVBHCMAX  = 1;
3575 	SiS_Pr->SiS_RVBHCFACT = 1;
3576 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3577 	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3578 
3579 	tempax = SiS_Pr->CHTotal;
3580 	if(modeflag & HalfDCLK) tempax <<= 1;
3581 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3582 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3583 
3584      } else {
3585 
3586 	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3587 
3588      }
3589 
3590   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3591 
3592      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3593 		    &CRT2Index,&ResIndex);
3594 
3595      switch(CRT2Index) {
3596 	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3597 	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3598 	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3599 	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3600 	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3601 	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3602 	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3603 	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3604 	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3605 	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3606 	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3607 	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3608 	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3609 	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3610      }
3611 
3612      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3613      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3614      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3615      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3616      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3617      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3618      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3619      if(modeflag & HalfDCLK) {
3620 	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3621 	if(SiS_Pr->SiS_RVBHRS2) {
3622 	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3623 	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3624 	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3625 	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3626 	}
3627      } else {
3628 	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3629      }
3630      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3631 
3632      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3633 
3634 	if((resinfo == SIS_RI_960x600)   ||
3635 	   (resinfo == SIS_RI_1024x768)  ||
3636 	   (resinfo == SIS_RI_1280x1024) ||
3637 	   (resinfo == SIS_RI_1280x720)) {
3638 	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3639 	}
3640 
3641 	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3642 
3643 	SiS_Pr->SiS_HT = ExtHiTVHT;
3644 	SiS_Pr->SiS_VT = ExtHiTVVT;
3645 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3646 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3647 	      SiS_Pr->SiS_HT = StHiTVHT;
3648 	      SiS_Pr->SiS_VT = StHiTVVT;
3649 	   }
3650 	}
3651 
3652      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3653 
3654 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3655 	   SiS_Pr->SiS_HT = 1650;
3656 	   SiS_Pr->SiS_VT = 750;
3657 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3658 	   SiS_Pr->SiS_HT = NTSCHT;
3659 	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3660 	   SiS_Pr->SiS_VT = NTSCVT;
3661 	} else {
3662 	   SiS_Pr->SiS_HT = NTSCHT;
3663 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3664 	   SiS_Pr->SiS_VT = NTSCVT;
3665 	}
3666 
3667      } else {
3668 
3669 	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3670 	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3671 	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3672 	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3673 
3674 	if(modeflag & HalfDCLK) {
3675 	   SiS_Pr->SiS_RY1COE = 0x00;
3676 	   SiS_Pr->SiS_RY2COE = 0xf4;
3677 	   SiS_Pr->SiS_RY3COE = 0x10;
3678 	   SiS_Pr->SiS_RY4COE = 0x38;
3679 	}
3680 
3681 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3682 	   SiS_Pr->SiS_HT = NTSCHT;
3683 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3684 	   SiS_Pr->SiS_VT = NTSCVT;
3685 	} else {
3686 	   SiS_Pr->SiS_HT = PALHT;
3687 	   SiS_Pr->SiS_VT = PALVT;
3688 	}
3689 
3690      }
3691 
3692   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3693 
3694      SiS_Pr->SiS_RVBHCMAX  = 1;
3695      SiS_Pr->SiS_RVBHCFACT = 1;
3696 
3697      if(SiS_Pr->UseCustomMode) {
3698 
3699 	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3700 	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3701 
3702 	tempax = SiS_Pr->CHTotal;
3703 	if(modeflag & HalfDCLK) tempax <<= 1;
3704 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3705 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3706 
3707      } else {
3708 
3709 	bool gotit = false;
3710 
3711 	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3712 
3713 	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3714 	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3715 	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3716 	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3717 	   gotit = true;
3718 
3719 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3720 
3721 #ifdef CONFIG_FB_SIS_315
3722 	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3723 	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3724 	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3725 	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3726 	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3727 	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3728 	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3729 	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3730 	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3731 	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3732 	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3733 	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3734 	   }
3735 	   if(SiS_Pr->SiS_VGAHT) gotit = true;
3736 	   else {
3737 	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3738 	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3739 	      SiS_Pr->SiS_RVBHCMAX  = 1;
3740 	      SiS_Pr->SiS_RVBHCFACT = 1;
3741 	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3742 	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3743 	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3744 	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3745 	      SiS_Pr->SiS_RVBHRS2 = 0;
3746 	      gotit = true;
3747 	   }
3748 #endif
3749 
3750 	}
3751 
3752 	if(!gotit) {
3753 
3754 	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3755 			  &CRT2Index,&ResIndex);
3756 
3757 	   switch(CRT2Index) {
3758 	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3759 	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3760 	      case Panel_1280x720      :
3761 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3762 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3763 	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3764 	      case Panel_1280x800      :
3765 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3766 	      case Panel_1280x800_2    :
3767 	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3768 	      case Panel_1280x854      :
3769 	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3770 	      case Panel_1280x960      :
3771 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3772 	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3773 	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3774 	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3775 	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3776 	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3777 	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3778 	      case Panel_1680x1050     :
3779 	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3780 	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3781 #ifdef CONFIG_FB_SIS_315
3782 	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3783 	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3784 #endif
3785 	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3786 	   }
3787 
3788 	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3789 	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3790 	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3791 	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3792 	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3793 	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3794 
3795         }
3796 
3797 	tempax = SiS_Pr->PanelXRes;
3798 	tempbx = SiS_Pr->PanelYRes;
3799 
3800 	switch(SiS_Pr->SiS_LCDResInfo) {
3801 	case Panel_1024x768:
3802 	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3803 	      if(SiS_Pr->ChipType < SIS_315H) {
3804 		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3805 		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3806 	      }
3807 	   } else {
3808 	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3809 	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3810 	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3811 	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3812 	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3813 	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3814 	   }
3815 	   break;
3816 	case Panel_1280x960:
3817 	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3818 	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3819 	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3820 	   break;
3821 	case Panel_1280x1024:
3822 	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3823 	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3824 	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3825 	   break;
3826 	case Panel_1600x1200:
3827 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3828 	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3829 	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3830 	   }
3831 	   break;
3832 	}
3833 
3834 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3835 	   tempax = SiS_Pr->SiS_VGAHDE;
3836 	   tempbx = SiS_Pr->SiS_VGAVDE;
3837 	}
3838 
3839 	SiS_Pr->SiS_HDE = tempax;
3840 	SiS_Pr->SiS_VDE = tempbx;
3841      }
3842   }
3843 }
3844 
3845 static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3846 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3847                 unsigned short RefreshRateTableIndex)
3848 {
3849 
3850    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3851 
3852       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3853          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3854       } else {
3855 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3856 	    /* Need LVDS Data for LCD on 301B-DH */
3857 	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3858 	 } else {
3859 	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3860 	 }
3861       }
3862 
3863    } else {
3864 
3865       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3866 
3867    }
3868 }
3869 
3870 /*********************************************/
3871 /*         GET LVDS DES (SKEW) DATA          */
3872 /*********************************************/
3873 
3874 static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3875 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3876 {
3877    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3878 
3879 #ifdef CONFIG_FB_SIS_300
3880    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3881 
3882       if(SiS_Pr->ChipType < SIS_315H) {
3883 	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3884 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3885 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3886 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3887 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3888 	       }
3889             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3890 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3891 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3892 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3893 	       }
3894 	    }
3895 	 }
3896       }
3897    }
3898 #endif
3899    return PanelDesPtr;
3900 }
3901 
3902 static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3903 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3904                    unsigned short RefreshRateTableIndex)
3905 {
3906   unsigned short modeflag, ResIndex;
3907   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3908 
3909   SiS_Pr->SiS_LCDHDES = 0;
3910   SiS_Pr->SiS_LCDVDES = 0;
3911 
3912   /* Some special cases */
3913   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3914 
3915      /* Trumpion */
3916      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3917 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3918 	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3919 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3920 	   }
3921 	}
3922 	return;
3923      }
3924 
3925      /* 640x480 on LVDS */
3926      if(SiS_Pr->ChipType < SIS_315H) {
3927 	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3928 	   SiS_Pr->SiS_LCDHDES = 8;
3929 	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3930 	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3931 	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3932 	   return;
3933 	}
3934      }
3935 
3936   } /* LCD */
3937 
3938   if( (SiS_Pr->UseCustomMode) 		         ||
3939       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3940       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3941       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3942       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3943      return;
3944   }
3945 
3946   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3947   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3948 
3949   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3950 
3951 #ifdef CONFIG_FB_SIS_315
3952      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3953 	/* non-pass 1:1 only, see above */
3954 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3955 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3956 	}
3957 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3958 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3959 	}
3960      }
3961      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3962 	switch(SiS_Pr->SiS_CustomT) {
3963 	case CUT_UNIWILL1024:
3964 	case CUT_UNIWILL10242:
3965 	case CUT_CLEVO1400:
3966 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3967 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3968 	   }
3969 	   break;
3970 	}
3971 	switch(SiS_Pr->SiS_LCDResInfo) {
3972 	case Panel_1280x1024:
3973 	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3974 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3975 	   }
3976 	   break;
3977 	case Panel_1280x800:	/* Verified for Averatec 6240 */
3978 	case Panel_1280x800_2:	/* Verified for Asus A4L */
3979 	case Panel_1280x854:    /* Not verified yet FIXME */
3980 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3981 	   break;
3982 	}
3983      }
3984 #endif
3985 
3986   } else {
3987 
3988      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3989 
3990 	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3991 	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3992 	}
3993 
3994      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3995 
3996 	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3997 	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3998 
3999      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4000 
4001 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4002 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4003 	}
4004 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4005 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4006 	} else {
4007 	   if(SiS_Pr->ChipType < SIS_315H) {
4008 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4009 	   } else {
4010 	      switch(SiS_Pr->SiS_LCDResInfo) {
4011 	      case Panel_800x600:
4012 	      case Panel_1024x768:
4013 	      case Panel_1280x1024:
4014 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4015 		 break;
4016 	      case Panel_1400x1050:
4017 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4018 		 break;
4019 	      }
4020 	   }
4021 	}
4022 
4023      } else {
4024 
4025         if(SiS_Pr->ChipType < SIS_315H) {
4026 #ifdef CONFIG_FB_SIS_300
4027 	   switch(SiS_Pr->SiS_LCDResInfo) {
4028 	   case Panel_800x600:
4029 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4030 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4031 	      } else {
4032 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4033 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4034 		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4035 		 else                          SiS_Pr->SiS_LCDVDES -= 4;
4036 	      }
4037 	      break;
4038 	   case Panel_1024x768:
4039 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4040 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4041 	      } else {
4042 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4043 		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4044 		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4045 	      }
4046 	      break;
4047 	   case Panel_1024x600:
4048 	   default:
4049 	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4050 		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4051 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4052 	      } else {
4053 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4054 	      }
4055 	      break;
4056 	   }
4057 
4058 	   switch(SiS_Pr->SiS_LCDTypeInfo) {
4059 	   case 1:
4060 	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4061 	      break;
4062 	   case 3: /* 640x480 only? */
4063 	      SiS_Pr->SiS_LCDHDES = 8;
4064 	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4065 	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4066 	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4067 	      break;
4068 	   }
4069 #endif
4070         } else {
4071 #ifdef CONFIG_FB_SIS_315
4072 	   switch(SiS_Pr->SiS_LCDResInfo) {
4073 	   case Panel_1024x768:
4074 	   case Panel_1280x1024:
4075 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4076 	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4077 	      }
4078 	      break;
4079 	   case Panel_320x240_1:
4080 	   case Panel_320x240_2:
4081 	   case Panel_320x240_3:
4082 	      SiS_Pr->SiS_LCDVDES = 524;
4083 	      break;
4084 	   }
4085 #endif
4086 	}
4087      }
4088 
4089      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4090 	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4091 	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4092 	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4093 	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4094 	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4095 	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4096 	         if(SiS_Pr->ChipType < SIS_315H) {
4097 	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4098 	         } else {
4099 #ifdef CONFIG_FB_SIS_315
4100 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
4101 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4102 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4103 		    if(!(modeflag & HalfDCLK)) {
4104 		       SiS_Pr->SiS_LCDHDES = 320;
4105 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4106 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4107         	    }
4108 #endif
4109 		 }
4110 	      }
4111 	   }
4112 	}
4113      }
4114   }
4115 }
4116 
4117 /*********************************************/
4118 /*           DISABLE VIDEO BRIDGE            */
4119 /*********************************************/
4120 
4121 #ifdef CONFIG_FB_SIS_315
4122 static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)4123 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4124 {
4125    int ret = 0;
4126 #ifdef SET_PWD
4127    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4128    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4129    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4130    unsigned short temp;
4131 
4132    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4133        (romptr)				&&
4134        (SiS_Pr->SiS_PWDOffset) ) {
4135       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4136       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4137       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4138       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4139       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4140       temp = 0x00;
4141       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4142          temp = 0x80;
4143 	 ret = 1;
4144       }
4145       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4146    }
4147 #endif
4148    return ret;
4149 }
4150 #endif
4151 
4152 /* NEVER use any variables (VBInfo), this will be called
4153  * from outside the context of modeswitch!
4154  * MUST call getVBType before calling this
4155  */
4156 void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)4157 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4158 {
4159 #ifdef CONFIG_FB_SIS_315
4160   unsigned short tempah, pushax=0, modenum;
4161 #endif
4162   unsigned short temp=0;
4163 
4164   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4165 
4166      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
4167 
4168 	if(SiS_Pr->ChipType < SIS_315H) {
4169 
4170 #ifdef CONFIG_FB_SIS_300	   /* 300 series */
4171 
4172 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4173 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4174 		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4175 	      } else {
4176 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4177 	      }
4178 	      SiS_PanelDelay(SiS_Pr, 3);
4179 	   }
4180 	   if(SiS_Is301B(SiS_Pr)) {
4181 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4182 	      SiS_ShortDelay(SiS_Pr,1);
4183 	   }
4184 	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4185 	   SiS_DisplayOff(SiS_Pr);
4186 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4187 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4188 	   SiS_UnLockCRT2(SiS_Pr);
4189 	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4190 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4191 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4192 	   }
4193 	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4194 	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4195 	      SiS_PanelDelay(SiS_Pr, 2);
4196 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4197 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4198 	      } else {
4199 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4200 	      }
4201 	   }
4202 
4203 #endif  /* CONFIG_FB_SIS_300 */
4204 
4205         } else {
4206 
4207 #ifdef CONFIG_FB_SIS_315	   /* 315 series */
4208 
4209 	   int didpwd = 0;
4210 	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4211 	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4212 
4213 	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4214 
4215 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4216 
4217 #ifdef SET_EMI
4218 	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4219 		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4220 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4221 		 }
4222 	      }
4223 #endif
4224 
4225 	      didpwd = SiS_HandlePWD(SiS_Pr);
4226 
4227 	      if( (modenum <= 0x13)           ||
4228 		  (SiS_IsVAMode(SiS_Pr))      ||
4229 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4230 		 if(!didpwd) {
4231 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4232 		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4233 		 } else {
4234 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4235 		 }
4236 	      }
4237 
4238 	      if(!custom1) {
4239 		 SiS_DDC2Delay(SiS_Pr,0xff00);
4240 		 SiS_DDC2Delay(SiS_Pr,0xe000);
4241 		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4242 		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4243 		 if(IS_SIS740) {
4244 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4245 		 }
4246 	         SiS_PanelDelay(SiS_Pr, 3);
4247 	      }
4248 
4249 	   }
4250 
4251 	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4252 	      /* if(SiS_Pr->ChipType < SIS_340) {*/
4253 		 tempah = 0xef;
4254 		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4255 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4256 	      /*}*/
4257 	   }
4258 
4259 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4260 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4261 	   }
4262 
4263 	   tempah = 0x3f;
4264 	   if(SiS_IsDualEdge(SiS_Pr)) {
4265 	      tempah = 0x7f;
4266 	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4267 	   }
4268 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4269 
4270 	   if((SiS_IsVAMode(SiS_Pr)) ||
4271 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4272 
4273 	      SiS_DisplayOff(SiS_Pr);
4274 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4275 		 SiS_PanelDelay(SiS_Pr, 2);
4276 	      }
4277 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4278 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4279 
4280 	   }
4281 
4282 	   if((!(SiS_IsVAMode(SiS_Pr))) ||
4283 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4284 
4285 	      if(!(SiS_IsDualEdge(SiS_Pr))) {
4286 		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4287 		 SiS_DisplayOff(SiS_Pr);
4288 	      }
4289 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4290 
4291 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4292 		 SiS_PanelDelay(SiS_Pr, 2);
4293 	      }
4294 
4295 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4296 	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4297 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4298 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4299 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4300 
4301 	   }
4302 
4303 	   if(SiS_IsNotM650orLater(SiS_Pr)) {
4304 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4305 	   }
4306 
4307 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4308 
4309 	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4310 		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4311 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4312 
4313 		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4314 		 if(!didpwd) {
4315 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4316 		 }
4317 		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4318 	      }
4319 
4320 	      if(!custom1) {
4321 		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4322 		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4323 		    if(SiS_IsVAorLCD(SiS_Pr)) {
4324 		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4325 		    }
4326 		 }
4327 	      }
4328 
4329 	   }
4330 
4331 #endif /* CONFIG_FB_SIS_315 */
4332 
4333 	}
4334 
4335      } else {     /* ============ For 301 ================ */
4336 
4337         if(SiS_Pr->ChipType < SIS_315H) {
4338 #ifdef CONFIG_FB_SIS_300
4339 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4340 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4341 	      SiS_PanelDelay(SiS_Pr, 3);
4342 	   }
4343 #endif
4344 	}
4345 
4346 	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4347 	SiS_DisplayOff(SiS_Pr);
4348 
4349 	if(SiS_Pr->ChipType >= SIS_315H) {
4350 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4351 	}
4352 
4353 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4354 
4355 	if(SiS_Pr->ChipType >= SIS_315H) {
4356 	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4357 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4358 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4359 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4360 	} else {
4361 #ifdef CONFIG_FB_SIS_300
4362 	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4363 	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4364 		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4365 		SiS_PanelDelay(SiS_Pr, 2);
4366 		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4367 	    }
4368 #endif
4369 	}
4370 
4371       }
4372 
4373   } else {     /* ============ For LVDS =============*/
4374 
4375     if(SiS_Pr->ChipType < SIS_315H) {
4376 
4377 #ifdef CONFIG_FB_SIS_300	/* 300 series */
4378 
4379 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4380 	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4381 	}
4382 
4383 	if(SiS_Pr->ChipType == SIS_730) {
4384 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4385 	      SiS_WaitVBRetrace(SiS_Pr);
4386 	   }
4387 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4388 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4389 	      SiS_PanelDelay(SiS_Pr, 3);
4390 	   }
4391 	} else {
4392 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4393 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4394 		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4395 		    SiS_WaitVBRetrace(SiS_Pr);
4396 		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4397 		       SiS_DisplayOff(SiS_Pr);
4398 		    }
4399 		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4400 		    SiS_PanelDelay(SiS_Pr, 3);
4401 		 }
4402 	      }
4403 	   }
4404 	}
4405 
4406 	SiS_DisplayOff(SiS_Pr);
4407 
4408 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4409 
4410 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4411 	SiS_UnLockCRT2(SiS_Pr);
4412 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4413 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4414 
4415 	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4416 	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4417 	   SiS_PanelDelay(SiS_Pr, 2);
4418 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4419 	}
4420 
4421 #endif  /* CONFIG_FB_SIS_300 */
4422 
4423     } else {
4424 
4425 #ifdef CONFIG_FB_SIS_315	/* 315 series */
4426 
4427 	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4428 	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4429 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4430 	   /* } */
4431 	}
4432 
4433 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4434 
4435 	   if(SiS_Pr->ChipType == SIS_740) {
4436 	      temp = SiS_GetCH701x(SiS_Pr,0x61);
4437 	      if(temp < 1) {
4438 		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4439 		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4440 	      }
4441 
4442 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4443 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4444 		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4445 	      }
4446 	   }
4447 
4448 	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4449 	       (SiS_IsVAMode(SiS_Pr)) ) {
4450 	      SiS_Chrontel701xBLOff(SiS_Pr);
4451 	      SiS_Chrontel701xOff(SiS_Pr);
4452 	   }
4453 
4454 	   if(SiS_Pr->ChipType != SIS_740) {
4455 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4456 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4457 		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4458 	      }
4459 	   }
4460 
4461 	}
4462 
4463 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4464 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4465 	   SiS_PanelDelay(SiS_Pr, 3);
4466 	}
4467 
4468 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4469 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4470 	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4471 	   SiS_DisplayOff(SiS_Pr);
4472 	}
4473 
4474 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4475 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4476 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4477 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4478 	}
4479 
4480 	if(SiS_Pr->ChipType == SIS_740) {
4481 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4482 	}
4483 
4484 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4485 
4486 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4487 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4488 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4489 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4490 	}
4491 
4492 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4493 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4494 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4495 	      if(SiS_Pr->ChipType == SIS_550) {
4496 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4497 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4498 	      }
4499 	   }
4500 	} else {
4501 	   if(SiS_Pr->ChipType == SIS_740) {
4502 	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4503 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4504 	      }
4505 	   } else if(SiS_IsVAMode(SiS_Pr)) {
4506 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4507 	   }
4508 	}
4509 
4510 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4511 	   if(SiS_IsDualEdge(SiS_Pr)) {
4512 	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4513 	   } else {
4514 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4515 	   }
4516 	}
4517 
4518 	SiS_UnLockCRT2(SiS_Pr);
4519 
4520 	if(SiS_Pr->ChipType == SIS_550) {
4521 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4522 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4523 	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4524 		   (!(SiS_IsDualEdge(SiS_Pr))) ||
4525 		   (!(SiS_IsVAMode(SiS_Pr))) ) {
4526 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4527 	}
4528 
4529         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4530 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4531 	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4532 		 SiS_PanelDelay(SiS_Pr, 2);
4533 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4534 	      }
4535 	   }
4536         }
4537 
4538 #endif  /* CONFIG_FB_SIS_315 */
4539 
4540     }  /* 315 series */
4541 
4542   }  /* LVDS */
4543 
4544 }
4545 
4546 /*********************************************/
4547 /*            ENABLE VIDEO BRIDGE            */
4548 /*********************************************/
4549 
4550 /* NEVER use any variables (VBInfo), this will be called
4551  * from outside the context of a mode switch!
4552  * MUST call getVBType before calling this
4553  */
4554 static
4555 void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4556 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4557 {
4558   unsigned short temp=0, tempah;
4559 #ifdef CONFIG_FB_SIS_315
4560   unsigned short temp1, pushax=0;
4561   bool delaylong = false;
4562 #endif
4563 
4564   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4565 
4566     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
4567 
4568       if(SiS_Pr->ChipType < SIS_315H) {
4569 
4570 #ifdef CONFIG_FB_SIS_300     /* 300 series */
4571 
4572 	 if(SiS_CRT2IsLCD(SiS_Pr)) {
4573 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4574 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4575 	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4576 	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4577 	    }
4578 	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4579 	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4580 		  SiS_PanelDelay(SiS_Pr, 0);
4581 	       }
4582 	    }
4583 	 }
4584 
4585 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4586 	    (SiS_CRT2IsLCD(SiS_Pr))) {
4587 
4588 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4589 	    SiS_DisplayOn(SiS_Pr);
4590 	    SiS_UnLockCRT2(SiS_Pr);
4591 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4592 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4593 	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4594 	    } else {
4595 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4596 	    }
4597 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4598 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4599 		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4600 		     SiS_PanelDelay(SiS_Pr, 1);
4601 		  }
4602 		  SiS_WaitVBRetrace(SiS_Pr);
4603 		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4604 	       }
4605 	    }
4606 
4607 	 } else {
4608 
4609 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4610 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4611 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4612 	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4613 	    }
4614 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4615 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4616 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4617 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4618 	    SiS_DisplayOn(SiS_Pr);
4619 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4620 	       if(SiS_CRT2IsLCD(SiS_Pr)) {
4621 		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4622 		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4623 		        SiS_PanelDelay(SiS_Pr, 1);
4624 		     }
4625 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4626 		  }
4627 	       }
4628 	    }
4629 
4630 	 }
4631 
4632 
4633 #endif /* CONFIG_FB_SIS_300 */
4634 
4635       } else {
4636 
4637 #ifdef CONFIG_FB_SIS_315    /* 315 series */
4638 
4639 #ifdef SET_EMI
4640 	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4641 	 int didpwd = 0;
4642 	 /* unsigned short  emidelay=0; */
4643 #endif
4644 
4645 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4646 	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4647 #ifdef SET_EMI
4648 	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4649 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4650 	    }
4651 #endif
4652 	 }
4653 
4654 	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4655 	    /*if(SiS_Pr->ChipType < SIS_340) { */
4656 	       tempah = 0x10;
4657 	       if(SiS_LCDAEnabled(SiS_Pr)) {
4658 		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4659 		  else			    tempah = 0x08;
4660 	       }
4661 	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4662 	    /*}*/
4663 	 }
4664 
4665 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4666 
4667 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4668 	    SiS_DisplayOff(SiS_Pr);
4669 	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4670 	    if(IS_SIS740) {
4671 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4672 	    }
4673 
4674 	    didpwd = SiS_HandlePWD(SiS_Pr);
4675 
4676 	    if(SiS_IsVAorLCD(SiS_Pr)) {
4677 	       if(!didpwd) {
4678 		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4679 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4680 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4681 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4682 		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4683 		        SiS_GenericDelay(SiS_Pr, 17664);
4684 		     }
4685 		  }
4686 	       } else {
4687 		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4688 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4689 		     SiS_GenericDelay(SiS_Pr, 17664);
4690 		  }
4691 	       }
4692 	    }
4693 
4694 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4695 	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4696 	       delaylong = true;
4697 	    }
4698 
4699 	 }
4700 
4701 	 if(!(SiS_IsVAMode(SiS_Pr))) {
4702 
4703 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4704 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4705 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4706 	       if(!(tempah & SetCRT2ToRAMDAC)) {
4707 		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4708 	       }
4709 	    }
4710 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4711 
4712 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4713 
4714 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4715 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4716 
4717 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4718 	       SiS_PanelDelay(SiS_Pr, 2);
4719 	    }
4720 
4721 	 } else {
4722 
4723 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4724 
4725 	 }
4726 
4727 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4728 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4729 
4730 	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4731 	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
4732 	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
4733 	       /* Enable "LVDS PLL power on" (even on 301C) */
4734 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4735 	       /* Enable "LVDS Driver Power on" (even on 301C) */
4736 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4737 	    }
4738 	 }
4739 
4740 	 tempah = 0xc0;
4741 	 if(SiS_IsDualEdge(SiS_Pr)) {
4742 	    tempah = 0x80;
4743 	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4744 	 }
4745 	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4746 
4747 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4748 
4749 	    SiS_PanelDelay(SiS_Pr, 2);
4750 
4751 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4752 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4753 
4754 	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4755 #ifdef SET_EMI
4756 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4757 		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4758 		  SiS_GenericDelay(SiS_Pr, 2048);
4759 	       }
4760 #endif
4761 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4762 
4763 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4764 #ifdef SET_EMI
4765 		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4766 
4767 		  if(SiS_Pr->SiS_ROMNew) {
4768 		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4769 		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4770 		     if(romptr) {
4771 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4772 			SiS_Pr->EMI_30 = 0;
4773 			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4774 			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4775 			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4776 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4777 			/* emidelay = SISGETROMW((romptr + 0x22)); */
4778 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4779 		     }
4780 		  }
4781 
4782 		  /*                                              (P4_30|0x40)  */
4783 		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4784 		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4785 		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4786 		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4787 		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4788 		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4789 		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4790 		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4791 		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4792 
4793 		  if(SiS_Pr->HaveEMI) {
4794 		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4795 		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4796 		  } else {
4797 		     r30 = 0;
4798 		  }
4799 
4800 		  /* EMI_30 is read at driver start; however, the BIOS sets this
4801 		   * (if it is used) only if the LCD is in use. In case we caught
4802 		   * the machine while on TV output, this bit is not set and we
4803 		   * don't know if it should be set - hence our detection is wrong.
4804 		   * Work-around this here:
4805 		   */
4806 
4807 		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4808 		     switch((cr36 & 0x0f)) {
4809 		     case 2:
4810 			r30 |= 0x40;
4811 			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4812 			if(!SiS_Pr->HaveEMI) {
4813 			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4814 			   if((cr36 & 0xf0) == 0x30) {
4815 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4816 			   }
4817 			}
4818 			break;
4819 		     case 3:  /* 1280x1024 */
4820 			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4821 			if(!SiS_Pr->HaveEMI) {
4822 			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4823 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4824 			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4825 			   }
4826 			}
4827 			break;
4828 		     case 9:  /* 1400x1050 */
4829 			r30 |= 0x40;
4830 			if(!SiS_Pr->HaveEMI) {
4831 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4832 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4833 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4834 			   }
4835 			}
4836 			break;
4837 		     case 11: /* 1600x1200 - unknown */
4838 			r30 |= 0x40;
4839 			if(!SiS_Pr->HaveEMI) {
4840 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4841 			}
4842 		     }
4843                   }
4844 
4845 		  /* BIOS values don't work so well sometimes */
4846 		  if(!SiS_Pr->OverruleEMI) {
4847 #ifdef COMPAL_HACK
4848 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4849 			if((cr36 & 0x0f) == 0x09) {
4850 			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4851 			}
4852  		     }
4853 #endif
4854 #ifdef COMPAQ_HACK
4855 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4856 			if((cr36 & 0x0f) == 0x03) {
4857 			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4858 			}
4859 		     }
4860 #endif
4861 #ifdef ASUS_HACK
4862 		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4863 			if((cr36 & 0x0f) == 0x02) {
4864 			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4865 			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4866 			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4867 			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4868 			}
4869 		     }
4870 #endif
4871 		  }
4872 
4873 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4874 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4875 		     SiS_GenericDelay(SiS_Pr, 2048);
4876 		  }
4877 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4878 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4879 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4880 #endif	/* SET_EMI */
4881 
4882 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4883 
4884 #ifdef SET_EMI
4885 		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4886 		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
4887 		     if(r30 & 0x40) {
4888 			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4889 			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4890 			if(delaylong) {
4891 			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4892 			   delaylong = false;
4893 			}
4894 			SiS_WaitVBRetrace(SiS_Pr);
4895 			SiS_WaitVBRetrace(SiS_Pr);
4896 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4897 			   SiS_GenericDelay(SiS_Pr, 1280);
4898 			}
4899 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4900 			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4901 		     }
4902 		  }
4903 #endif
4904 	       }
4905 	    }
4906 
4907 	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4908 	       if(SiS_IsVAorLCD(SiS_Pr)) {
4909 		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4910 		  if(delaylong) {
4911 		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4912 		  }
4913 		  SiS_WaitVBRetrace(SiS_Pr);
4914 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4915 		     SiS_GenericDelay(SiS_Pr, 2048);
4916 		     SiS_WaitVBRetrace(SiS_Pr);
4917 		  }
4918 		  if(!didpwd) {
4919 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4920 		  } else {
4921 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4922 		  }
4923 	       }
4924 	    }
4925 
4926 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4927 	    SiS_DisplayOn(SiS_Pr);
4928 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4929 
4930 	 }
4931 
4932 	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4933 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4934 	 }
4935 
4936 #endif /* CONFIG_FB_SIS_315 */
4937 
4938       }
4939 
4940     } else {	/* ============  For 301 ================ */
4941 
4942        if(SiS_Pr->ChipType < SIS_315H) {
4943 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4944 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4945 	     SiS_PanelDelay(SiS_Pr, 0);
4946 	  }
4947        }
4948 
4949        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4950        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4951 	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4952 	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4953        }
4954        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4955 
4956        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4957 
4958        if(SiS_Pr->ChipType >= SIS_315H) {
4959 	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4960 	  if(!(temp & 0x80)) {
4961 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4962 	  }
4963        }
4964 
4965        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4966 
4967        SiS_VBLongWait(SiS_Pr);
4968        SiS_DisplayOn(SiS_Pr);
4969        if(SiS_Pr->ChipType >= SIS_315H) {
4970 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4971        }
4972        SiS_VBLongWait(SiS_Pr);
4973 
4974        if(SiS_Pr->ChipType < SIS_315H) {
4975 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4976 	     SiS_PanelDelay(SiS_Pr, 1);
4977 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4978 	  }
4979        }
4980 
4981     }
4982 
4983   } else {   /* =================== For LVDS ================== */
4984 
4985     if(SiS_Pr->ChipType < SIS_315H) {
4986 
4987 #ifdef CONFIG_FB_SIS_300    /* 300 series */
4988 
4989        if(SiS_CRT2IsLCD(SiS_Pr)) {
4990 	  if(SiS_Pr->ChipType == SIS_730) {
4991 	     SiS_PanelDelay(SiS_Pr, 1);
4992 	     SiS_PanelDelay(SiS_Pr, 1);
4993 	     SiS_PanelDelay(SiS_Pr, 1);
4994 	  }
4995 	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4996 	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4997 	     SiS_PanelDelay(SiS_Pr, 0);
4998 	  }
4999        }
5000 
5001        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5002        SiS_DisplayOn(SiS_Pr);
5003        SiS_UnLockCRT2(SiS_Pr);
5004        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5005        if(SiS_BridgeInSlavemode(SiS_Pr)) {
5006 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5007        } else {
5008 	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5009        }
5010 
5011        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5012 	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5013 	     SiS_WaitVBRetrace(SiS_Pr);
5014 	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5015 	  }
5016        }
5017 
5018        if(SiS_CRT2IsLCD(SiS_Pr)) {
5019 	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5020 	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5021 		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5022 		   SiS_PanelDelay(SiS_Pr, 1);
5023 		   SiS_PanelDelay(SiS_Pr, 1);
5024 		}
5025 		SiS_WaitVBRetrace(SiS_Pr);
5026 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5027 	     }
5028 	  }
5029        }
5030 
5031 #endif  /* CONFIG_FB_SIS_300 */
5032 
5033     } else {
5034 
5035 #ifdef CONFIG_FB_SIS_315    /* 315 series */
5036 
5037        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5038 	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
5039 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5040 	  /*}*/
5041        }
5042 
5043        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5044 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5045 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5046 	     SiS_PanelDelay(SiS_Pr, 0);
5047 	  }
5048        }
5049 
5050        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5051        SiS_UnLockCRT2(SiS_Pr);
5052 
5053        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5054 
5055        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5056 	  temp = SiS_GetCH701x(SiS_Pr,0x66);
5057 	  temp &= 0x20;
5058 	  SiS_Chrontel701xBLOff(SiS_Pr);
5059        }
5060 
5061        if(SiS_Pr->ChipType != SIS_550) {
5062 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5063        }
5064 
5065        if(SiS_Pr->ChipType == SIS_740) {
5066 	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5067 	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5068 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5069 	     }
5070 	  }
5071        }
5072 
5073        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5074        if(!(temp1 & 0x80)) {
5075 	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5076        }
5077 
5078        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5079 	  if(temp) {
5080 	     SiS_Chrontel701xBLOn(SiS_Pr);
5081 	  }
5082        }
5083 
5084        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5085 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5086 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5087 	     if(SiS_Pr->ChipType == SIS_550) {
5088 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5089 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5090 	     }
5091 	  }
5092        } else if(SiS_IsVAMode(SiS_Pr)) {
5093 	  if(SiS_Pr->ChipType != SIS_740) {
5094 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5095 	  }
5096        }
5097 
5098        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5099 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5100        }
5101 
5102        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5103 	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5104 	     SiS_Chrontel701xOn(SiS_Pr);
5105 	  }
5106 	  if( (SiS_IsVAMode(SiS_Pr)) ||
5107 	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5108 	     SiS_ChrontelDoSomething1(SiS_Pr);
5109 	  }
5110        }
5111 
5112        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5113 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5114 	     if( (SiS_IsVAMode(SiS_Pr)) ||
5115 		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5116 		SiS_Chrontel701xBLOn(SiS_Pr);
5117 		SiS_ChrontelInitTVVSync(SiS_Pr);
5118 	     }
5119 	  }
5120        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5121 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5122 	     if(SiS_CRT2IsLCD(SiS_Pr)) {
5123 		SiS_PanelDelay(SiS_Pr, 1);
5124 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5125 	     }
5126 	  }
5127        }
5128 
5129 #endif  /* CONFIG_FB_SIS_315 */
5130 
5131     } /* 310 series */
5132 
5133   }  /* LVDS */
5134 
5135 }
5136 
5137 /*********************************************/
5138 /*         SET PART 1 REGISTER GROUP         */
5139 /*********************************************/
5140 
5141 /* Set CRT2 OFFSET / PITCH */
5142 static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)5143 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5144 		unsigned short RRTI)
5145 {
5146    unsigned short offset;
5147    unsigned char  temp;
5148 
5149    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5150 
5151    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5152 
5153    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5154    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5155 
5156    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5157    if(offset & 0x07) temp++;
5158    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5159 }
5160 
5161 /* Set CRT2 sync and PanelLink mode */
5162 static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)5163 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5164 {
5165    unsigned short tempah=0, tempbl, infoflag;
5166 
5167    tempbl = 0xC0;
5168 
5169    if(SiS_Pr->UseCustomMode) {
5170       infoflag = SiS_Pr->CInfoFlag;
5171    } else {
5172       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5173    }
5174 
5175    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
5176 
5177       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5178 	 tempah = 0;
5179       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5180 	 tempah = SiS_Pr->SiS_LCDInfo;
5181       } else tempah = infoflag >> 8;
5182       tempah &= 0xC0;
5183       tempah |= 0x20;
5184       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5185       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5186 	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5187 	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5188 	    tempah |= 0xf0;
5189 	 }
5190 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5191 	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
5192 	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5193 	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5194 	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5195 	    tempah |= 0x30;
5196 	 }
5197 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5198 	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5199 	    tempah &= ~0xc0;
5200 	 }
5201       }
5202       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5203 	 if(SiS_Pr->ChipType >= SIS_315H) {
5204 	    tempah >>= 3;
5205 	    tempah &= 0x18;
5206 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5207 	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5208 	 } else {
5209 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5210 	 }
5211       } else {
5212 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5213       }
5214 
5215    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5216 
5217       if(SiS_Pr->ChipType < SIS_315H) {
5218 
5219 #ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
5220 
5221 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
5222 
5223 	    tempah = infoflag >> 8;
5224 	    tempbl = 0;
5225 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5226 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5227 		  tempah = SiS_Pr->SiS_LCDInfo;
5228 		  tempbl = (tempah >> 6) & 0x03;
5229 	       }
5230 	    }
5231 	    tempah &= 0xC0;
5232 	    tempah |= 0x20;
5233 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5234 	    tempah |= 0xc0;
5235 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5236 	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5237 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5238 	    }
5239 
5240 	 } else {							/* 630 - 301 */
5241 
5242 	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5243 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5244 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5245 
5246 	 }
5247 
5248 #endif /* CONFIG_FB_SIS_300 */
5249 
5250       } else {
5251 
5252 #ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
5253 
5254 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
5255 
5256 	    tempbl = 0;
5257 	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5258 	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5259 	       tempah = infoflag >> 8;
5260 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5261 		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5262 	       }
5263 	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5264 		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5265 	       tempah = infoflag >> 8;
5266 	       tempbl = 0x03;
5267 	    } else {
5268 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5269 	       tempbl = (tempah >> 6) & 0x03;
5270 	       tempbl |= 0x08;
5271 	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5272 	    }
5273 	    tempah &= 0xC0;
5274 	    tempah |= 0x20;
5275 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5276 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5277 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5278 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5279 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5280 		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5281 	       }
5282 	    }
5283 
5284 	 } else {							/* 315 - TMDS */
5285 
5286 	    tempah = tempbl = infoflag >> 8;
5287 	    if(!SiS_Pr->UseCustomMode) {
5288 	       tempbl = 0;
5289 	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5290 		  if(ModeNo <= 0x13) {
5291 		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5292 		  }
5293 	       }
5294 	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5295 		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5296 		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5297 		       tempah = SiS_Pr->SiS_LCDInfo;
5298 		       tempbl = (tempah >> 6) & 0x03;
5299 		    }
5300 		  }
5301 	       }
5302 	    }
5303 	    tempah &= 0xC0;
5304 	    tempah |= 0x20;
5305 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5306 	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5307 	       /* Imitate BIOS bug */
5308 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5309 	    }
5310 	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5311 	       tempah >>= 3;
5312 	       tempah &= 0x18;
5313 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5314 	    } else {
5315 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5316 	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5317 		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5318 		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5319 		  }
5320 	       }
5321 	    }
5322 
5323          }
5324 #endif  /* CONFIG_FB_SIS_315 */
5325       }
5326    }
5327 }
5328 
5329 /* Set CRT2 FIFO on 300/540/630/730 */
5330 #ifdef CONFIG_FB_SIS_300
5331 static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5332 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5333 {
5334   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5335   unsigned short temp, index, modeidindex, refreshratetableindex;
5336   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5337   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5338   unsigned int   data, pci50, pciA0;
5339   static const unsigned char colortharray[] = {
5340   	1, 1, 2, 2, 3, 4
5341   };
5342 
5343   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5344 
5345   if(!SiS_Pr->CRT1UsesCustomMode) {
5346 
5347      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5348      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5349      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5350      SiS_Pr->SiS_SelectCRT2Rate = 0;
5351      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5352 
5353      if(CRT1ModeNo >= 0x13) {
5354         /* Get VCLK */
5355 	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5356 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5357 
5358 	/* Get colordepth */
5359 	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5360 	if(!colorth) colorth++;
5361      }
5362 
5363   } else {
5364 
5365      CRT1ModeNo = 0xfe;
5366 
5367      /* Get VCLK */
5368      VCLK = SiS_Pr->CSRClock_CRT1;
5369 
5370      /* Get color depth */
5371      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5372 
5373   }
5374 
5375   if(CRT1ModeNo >= 0x13) {
5376      /* Get MCLK */
5377      if(SiS_Pr->ChipType == SIS_300) {
5378         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5379      } else {
5380         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5381      }
5382      index &= 0x07;
5383      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5384 
5385      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5386      if(!temp) temp++;
5387      temp <<= 2;
5388 
5389      data2 = temp - ((colorth * VCLK) / MCLK);
5390 
5391      temp = (28 * 16) % data2;
5392      data2 = (28 * 16) / data2;
5393      if(temp) data2++;
5394 
5395      if(SiS_Pr->ChipType == SIS_300) {
5396 
5397 	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5398 	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5399 
5400      } else {
5401 
5402 	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5403 	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5404 
5405         if(SiS_Pr->ChipType == SIS_730) {
5406 
5407 	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5408 	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
5409 
5410 	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5411 	   index = 0;  /* -- do it like the BIOS anyway... */
5412 
5413 	} else {
5414 
5415 	   pci50 >>= 24;
5416 	   pciA0 >>= 24;
5417 
5418 	   index = (pci50 >> 1) & 0x07;
5419 
5420 	   if(pci50 & 0x01)    index += 6;
5421 	   if(!(pciA0 & 0x01)) index += 24;
5422 
5423 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5424 
5425 	}
5426 
5427 	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5428 	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5429 
5430      }
5431 
5432      data += data2;						/* CRT1 Request Period */
5433 
5434      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5435      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5436 
5437      if(!SiS_Pr->UseCustomMode) {
5438 
5439 	CRT2ModeNo = ModeNo;
5440 	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5441 
5442 	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5443 
5444 	/* Get VCLK  */
5445 	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5446 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5447 
5448 	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5449 	   if(SiS_Pr->SiS_UseROM) {
5450 	      if(ROMAddr[0x220] & 0x01) {
5451 		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5452 	      }
5453            }
5454         }
5455 
5456      } else {
5457 
5458 	/* Get VCLK */
5459 	CRT2ModeNo = 0xfe;
5460 	VCLK = SiS_Pr->CSRClock;
5461 
5462      }
5463 
5464      /* Get colordepth */
5465      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5466      if(!colorth) colorth++;
5467 
5468      data = data * VCLK * colorth;
5469      temp = data % (MCLK << 4);
5470      data = data / (MCLK << 4);
5471      if(temp) data++;
5472 
5473      if(data < 6) data = 6;
5474      else if(data > 0x14) data = 0x14;
5475 
5476      if(SiS_Pr->ChipType == SIS_300) {
5477         temp = 0x16;
5478 	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5479 	   temp = 0x13;
5480      } else {
5481         temp = 0x16;
5482 	if(( (SiS_Pr->ChipType == SIS_630) ||
5483 	     (SiS_Pr->ChipType == SIS_730) )  &&
5484 	   (SiS_Pr->ChipRevision >= 0x30))
5485 	   temp = 0x1b;
5486      }
5487      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5488 
5489      if((SiS_Pr->ChipType == SIS_630) &&
5490 	(SiS_Pr->ChipRevision >= 0x30)) {
5491 	if(data > 0x13) data = 0x13;
5492      }
5493      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5494 
5495   } else {  /* If mode <= 0x13, we just restore everything */
5496 
5497      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5498      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5499 
5500   }
5501 }
5502 #endif
5503 
5504 /* Set CRT2 FIFO on 315/330 series */
5505 #ifdef CONFIG_FB_SIS_315
5506 static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5507 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5508 {
5509   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5510   if( (SiS_Pr->ChipType == SIS_760)      &&
5511       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5512       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5513       (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5514       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5515      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5516      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5517      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5518      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5519      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5520      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5521   } else {
5522      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5523   }
5524 
5525 }
5526 #endif
5527 
5528 static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5529 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5530 {
5531   unsigned int tempax,tempbx;
5532 
5533   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5534   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5535   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5536   return (unsigned short)tempax;
5537 }
5538 
5539 /* Set Part 1 / SiS bridge slave mode */
5540 static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5541 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5542                   unsigned short RefreshRateTableIndex)
5543 {
5544   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5545   static const unsigned short CRTranslation[] = {
5546        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5547 	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5548        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5549 	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5550        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5551 	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5552   };
5553 
5554   if(ModeNo <= 0x13) {
5555      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5556   } else if(SiS_Pr->UseCustomMode) {
5557      modeflag = SiS_Pr->CModeFlag;
5558      xres = SiS_Pr->CHDisplay;
5559   } else {
5560      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5561      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5562   }
5563 
5564   /* The following is only done if bridge is in slave mode: */
5565 
5566   if(SiS_Pr->ChipType >= SIS_315H) {
5567      if(xres >= 1600) {  /* BIOS: == 1600 */
5568         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5569      }
5570   }
5571 
5572   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5573 
5574   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5575   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5576 
5577   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5578   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5579      SiS_Pr->CHBlankStart += 16;
5580   }
5581 
5582   SiS_Pr->CHBlankEnd = 32;
5583   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5584      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5585   }
5586 
5587   temp = SiS_Pr->SiS_VGAHT - 96;
5588   if(!(modeflag & HalfDCLK)) temp -= 32;
5589   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5590      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5591      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5592      temp -= 3;
5593      temp <<= 3;
5594   } else {
5595      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5596   }
5597   SiS_Pr->CHSyncStart = temp;
5598 
5599   SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
5600 
5601   SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
5602 
5603   VGAVDE = SiS_Pr->SiS_VGAVDE;
5604   if     (VGAVDE ==  357) VGAVDE =  350;
5605   else if(VGAVDE ==  360) VGAVDE =  350;
5606   else if(VGAVDE ==  375) VGAVDE =  350;
5607   else if(VGAVDE ==  405) VGAVDE =  400;
5608   else if(VGAVDE ==  420) VGAVDE =  400;
5609   else if(VGAVDE ==  525) VGAVDE =  480;
5610   else if(VGAVDE == 1056) VGAVDE = 1024;
5611   SiS_Pr->CVDisplay = VGAVDE;
5612 
5613   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5614 
5615   SiS_Pr->CVBlankEnd = 1;
5616   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5617 
5618   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5619   SiS_Pr->CVSyncStart = VGAVDE + temp;
5620 
5621   temp >>= 3;
5622   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5623 
5624   SiS_CalcCRRegisters(SiS_Pr, 0);
5625   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5626 
5627   for(i = 0; i <= 7; i++) {
5628      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5629   }
5630   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5631      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5632   }
5633   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5634      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5635   }
5636   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5637      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5638   }
5639 
5640   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5641   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5642 
5643   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5644   if(modeflag & DoubleScanMode) temp |= 0x80;
5645   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5646 
5647   temp = 0;
5648   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5649   if(modeflag & HalfDCLK) temp |= 0x08;
5650   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5651 
5652   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
5653   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
5654 
5655   temp = 0;
5656   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5657      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5658   }
5659   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
5660 
5661   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5662   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
5663 }
5664 
5665 /* Setup panel link
5666  * This is used for LVDS, LCDA and Chrontel TV output
5667  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5668  */
5669 static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5670 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5671 		unsigned short RefreshRateTableIndex)
5672 {
5673   unsigned short modeflag, resinfo = 0;
5674   unsigned short push2, tempax, tempbx, tempcx, temp;
5675   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5676   bool islvds = false, issis  = false, chkdclkfirst = false;
5677 #ifdef CONFIG_FB_SIS_300
5678   unsigned short crt2crtc = 0;
5679 #endif
5680 #ifdef CONFIG_FB_SIS_315
5681   unsigned short pushcx;
5682 #endif
5683 
5684   if(ModeNo <= 0x13) {
5685      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5686      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5687 #ifdef CONFIG_FB_SIS_300
5688      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5689 #endif
5690   } else if(SiS_Pr->UseCustomMode) {
5691      modeflag = SiS_Pr->CModeFlag;
5692   } else {
5693      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5694      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5695 #ifdef CONFIG_FB_SIS_300
5696      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5697 #endif
5698   }
5699 
5700   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5701   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5702      islvds = true;
5703   }
5704 
5705   /* is really sis if sis bridge, but not 301B-DH */
5706   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5707      issis = true;
5708   }
5709 
5710   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5711      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5712         chkdclkfirst = true;
5713      }
5714   }
5715 
5716 #ifdef CONFIG_FB_SIS_315
5717   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5718      if(IS_SIS330) {
5719         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5720      } else if(IS_SIS740) {
5721         if(islvds) {
5722            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5723 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5724         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5725            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5726         }
5727      } else {
5728         if(islvds) {
5729            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5730 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5731         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5732            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5733 	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5734 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5735 	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5736 	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5737 	      }
5738 	   }
5739         }
5740      }
5741   }
5742 #endif
5743 
5744   /* Horizontal */
5745 
5746   tempax = SiS_Pr->SiS_LCDHDES;
5747   if(islvds) {
5748      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5749 	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5750 	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5751 	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5752 	      tempax -= 8;
5753 	   }
5754 	}
5755      }
5756   }
5757 
5758   temp = (tempax & 0x0007);
5759   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5760   temp = (tempax >> 3) & 0x00FF;
5761   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5762 
5763   tempbx = SiS_Pr->SiS_HDE;
5764   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5765      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5766         tempbx = SiS_Pr->PanelXRes;
5767      }
5768      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5769         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5770         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5771         tempbx >>= 1;
5772      }
5773   }
5774 
5775   tempax += tempbx;
5776   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5777 
5778   temp = tempax;
5779   if(temp & 0x07) temp += 8;
5780   temp >>= 3;
5781   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5782 
5783   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5784 
5785   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5786      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5787         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5788      }
5789   }
5790 
5791   tempcx += tempax;
5792   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5793 
5794   temp = (tempcx >> 3) & 0x00FF;
5795   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5796      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5797 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5798 	   switch(ModeNo) {
5799 	   case 0x04:
5800 	   case 0x05:
5801 	   case 0x0d: temp = 0x56; break;
5802 	   case 0x10: temp = 0x60; break;
5803 	   case 0x13: temp = 0x5f; break;
5804 	   case 0x40:
5805 	   case 0x41:
5806 	   case 0x4f:
5807 	   case 0x43:
5808 	   case 0x44:
5809 	   case 0x62:
5810 	   case 0x56:
5811 	   case 0x53:
5812 	   case 0x5d:
5813 	   case 0x5e: temp = 0x54; break;
5814 	   }
5815 	}
5816      }
5817   }
5818   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5819 
5820   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5821      temp += 2;
5822      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5823 	temp += 8;
5824 	if(SiS_Pr->PanelHRE != 999) {
5825 	   temp = tempcx + SiS_Pr->PanelHRE;
5826 	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5827 	   temp >>= 3;
5828 	}
5829      }
5830   } else {
5831      temp += 10;
5832   }
5833 
5834   temp &= 0x1F;
5835   temp |= ((tempcx & 0x07) << 5);
5836   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5837 
5838   /* Vertical */
5839 
5840   tempax = SiS_Pr->SiS_VGAVDE;
5841   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5842      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5843 	tempax = SiS_Pr->PanelYRes;
5844      }
5845   }
5846 
5847   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5848   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5849 
5850   push2 = tempbx;
5851 
5852   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5853   if(SiS_Pr->ChipType < SIS_315H) {
5854      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5855 	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5856 	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5857 	}
5858      }
5859   }
5860   if(islvds) tempcx >>= 1;
5861   else       tempcx >>= 2;
5862 
5863   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5864       (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5865       (SiS_Pr->PanelVRS != 999) ) {
5866      tempcx = SiS_Pr->PanelVRS;
5867      tempbx += tempcx;
5868      if(issis) tempbx++;
5869   } else {
5870      tempbx += tempcx;
5871      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5872      else if(issis)                   tempbx++;
5873   }
5874 
5875   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5876 
5877   temp = tempbx & 0x00FF;
5878   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5879      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5880 	if(ModeNo == 0x10) temp = 0xa9;
5881      }
5882   }
5883   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
5884 
5885   tempcx >>= 3;
5886   tempcx++;
5887 
5888   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5889      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5890         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5891      }
5892   }
5893 
5894   tempcx += tempbx;
5895   temp = tempcx & 0x000F;
5896   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5897 
5898   temp = ((tempbx >> 8) & 0x07) << 3;
5899   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5900      if(SiS_Pr->SiS_HDE != 640) {
5901         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5902      }
5903   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5904   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5905   tempbx = 0x87;
5906   if((SiS_Pr->ChipType >= SIS_315H) ||
5907      (SiS_Pr->ChipRevision >= 0x30)) {
5908      tempbx = 0x07;
5909      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5910 	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5911      }
5912      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5913      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5914 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5915 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5916 	} else {
5917 	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5918 	}
5919      }
5920   }
5921   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5922 
5923   tempbx = push2;						/* BPLVDEE */
5924 
5925   tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
5926 
5927   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5928      switch(SiS_Pr->SiS_LCDResInfo) {
5929      case Panel_640x480:
5930 	tempbx = SiS_Pr->SiS_VGAVDE - 1;
5931 	tempcx = SiS_Pr->SiS_VGAVDE;
5932 	break;
5933      case Panel_800x600:
5934 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5935 	   if(resinfo == SIS_RI_800x600) tempcx++;
5936 	}
5937 	break;
5938      case Panel_1024x600:
5939 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5940 	   if(resinfo == SIS_RI_1024x600) tempcx++;
5941 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5942 	      if(resinfo == SIS_RI_800x600) tempcx++;
5943 	   }
5944 	}
5945 	break;
5946      case Panel_1024x768:
5947 	if(SiS_Pr->ChipType < SIS_315H) {
5948 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5949 	      if(resinfo == SIS_RI_1024x768) tempcx++;
5950 	   }
5951 	}
5952 	break;
5953      }
5954   }
5955 
5956   temp = ((tempbx >> 8) & 0x07) << 3;
5957   temp |= ((tempcx >> 8) & 0x07);
5958   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5959   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5960   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5961 
5962   /* Vertical scaling */
5963 
5964   if(SiS_Pr->ChipType < SIS_315H) {
5965 
5966 #ifdef CONFIG_FB_SIS_300      /* 300 series */
5967      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5968      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5969      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5970      if(temp) tempeax++;
5971 
5972      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5973 
5974      temp = (unsigned short)(tempeax & 0x00FF);
5975      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5976      tempvcfact = temp;
5977 #endif /* CONFIG_FB_SIS_300 */
5978 
5979   } else {
5980 
5981 #ifdef CONFIG_FB_SIS_315  /* 315 series */
5982      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5983      tempebx = SiS_Pr->SiS_VDE;
5984      temp = (tempeax % tempebx);
5985      tempeax = tempeax / tempebx;
5986      if(temp) tempeax++;
5987      tempvcfact = tempeax;
5988 
5989      temp = (unsigned short)(tempeax & 0x00FF);
5990      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5991      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5992      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5993      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5994      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5995      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5996 
5997      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5998         temp = (unsigned short)(tempeax & 0x00FF);
5999         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6000         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6001         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6002         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6003         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6004         temp = 0;
6005         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6006         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6007      }
6008 #endif
6009 
6010   }
6011 
6012   /* Horizontal scaling */
6013 
6014   tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6015   if(chkdclkfirst) {
6016      if(modeflag & HalfDCLK) tempeax >>= 1;
6017   }
6018   tempebx = tempeax << 16;
6019   if(SiS_Pr->SiS_HDE == tempeax) {
6020      tempecx = 0xFFFF;
6021   } else {
6022      tempecx = tempebx / SiS_Pr->SiS_HDE;
6023      if(SiS_Pr->ChipType >= SIS_315H) {
6024         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6025      }
6026   }
6027 
6028   if(SiS_Pr->ChipType >= SIS_315H) {
6029      tempeax = (tempebx / tempecx) - 1;
6030   } else {
6031      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6032   }
6033   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6034   temp = (unsigned short)(tempecx & 0x00FF);
6035   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6036 
6037   if(SiS_Pr->ChipType >= SIS_315H) {
6038      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6039      tempbx = (unsigned short)(tempeax & 0xFFFF);
6040   } else {
6041      tempeax = SiS_Pr->SiS_VGAVDE << 6;
6042      tempbx = tempvcfact & 0x3f;
6043      if(tempbx == 0) tempbx = 64;
6044      tempeax /= tempbx;
6045      tempbx = (unsigned short)(tempeax & 0xFFFF);
6046   }
6047   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6048   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6049      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6050      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
6051   }
6052 
6053   temp = ((tempbx >> 8) & 0x07) << 3;
6054   temp = temp | ((tempecx >> 8) & 0x07);
6055   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6056   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6057 
6058   tempecx >>= 16;						/* BPLHCFACT  */
6059   if(!chkdclkfirst) {
6060      if(modeflag & HalfDCLK) tempecx >>= 1;
6061   }
6062   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6063   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6064   temp = (unsigned short)(tempecx & 0x00FF);
6065   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6066 
6067 #ifdef CONFIG_FB_SIS_315
6068   if(SiS_Pr->ChipType >= SIS_315H) {
6069      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6070         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6071            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6072 	}
6073      } else {
6074         if(islvds) {
6075            if(SiS_Pr->ChipType == SIS_740) {
6076               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6077            } else {
6078 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6079            }
6080         }
6081      }
6082   }
6083 #endif
6084 
6085 #ifdef CONFIG_FB_SIS_300
6086   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6087      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6088      unsigned char *trumpdata;
6089      int   i, j = crt2crtc;
6090      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
6091      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6092      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6093 
6094      if(SiS_Pr->SiS_UseROM) {
6095 	trumpdata = &ROMAddr[0x8001 + (j * 80)];
6096      } else {
6097 	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6098 	trumpdata = &SiS300_TrumpionData[j][0];
6099      }
6100 
6101      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6102      for(i=0; i<5; i++) {
6103 	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6104      }
6105      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6106 	if(ModeNo == 0x13) {
6107 	   for(i=0; i<4; i++) {
6108 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6109 	   }
6110 	} else if(ModeNo == 0x10) {
6111 	   for(i=0; i<4; i++) {
6112 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6113 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6114 	   }
6115 	}
6116      }
6117      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6118   }
6119 #endif
6120 
6121 #ifdef CONFIG_FB_SIS_315
6122   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6123      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6124      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6125      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6126      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6127      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6128      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6129      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6130      tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6131      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6132         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6133         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6134      tempax += 64;
6135      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6136      temp = (tempax >> 8) << 3;
6137      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6138      tempax += 32;						/* Blpe = lBlps+32 */
6139      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6140      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
6141      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6142 
6143      tempax = SiS_Pr->SiS_VDE;
6144      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6145         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6146         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6147      tempax >>= 1;
6148      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6149      temp = (tempax >> 8) << 3;
6150      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6151 
6152      tempeax = SiS_Pr->SiS_HDE;
6153      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6154         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6155         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6156      tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
6157      temp = tempeax & 0x7f;
6158      tempeax >>= 7;
6159      if(temp) tempeax++;
6160      temp = tempeax & 0x3f;
6161      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6162      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
6163      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6164      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6165      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6166 
6167      tempax = SiS_Pr->SiS_HDE;
6168      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6169         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6170         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6171      tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
6172      pushcx = tempax;
6173      temp = tempax & 0x00FF;
6174      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6175      temp = ((tempax & 0xFF00) >> 8) << 3;
6176      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6177 
6178      tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6179      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6180         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6181         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6182      tempeax = tempax * pushcx;
6183      temp = tempeax & 0xFF;
6184      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6185      temp = (tempeax & 0xFF00) >> 8;
6186      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6187      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6188      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6189      temp = ((tempeax & 0x01000000) >> 24) << 7;
6190      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6191 
6192      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6193      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6194      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6195      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6196      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6197 
6198      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6199         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6200         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6201         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6202         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6203         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6204         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6205         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6206         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6207         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6208         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6209         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6210         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6211         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6212         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6213         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6214         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6215         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6216         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6217         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6218         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6219      }
6220   }
6221 #endif  /* CONFIG_FB_SIS_315 */
6222 }
6223 
6224 /* Set Part 1 */
6225 static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6226 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6227 		unsigned short RefreshRateTableIndex)
6228 {
6229 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6230   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6231 #endif
6232   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6233   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6234 #ifdef CONFIG_FB_SIS_315
6235   unsigned short  tempbl=0;
6236 #endif
6237 
6238   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6239      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6240      return;
6241   }
6242 
6243   if(ModeNo <= 0x13) {
6244      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6245   } else if(SiS_Pr->UseCustomMode) {
6246      modeflag = SiS_Pr->CModeFlag;
6247   } else {
6248      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6249      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6250      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6251   }
6252 
6253   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6254 
6255   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6256          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6257          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6258 
6259      if(SiS_Pr->ChipType < SIS_315H ) {
6260 #ifdef CONFIG_FB_SIS_300
6261 	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6262 #endif
6263      } else {
6264 #ifdef CONFIG_FB_SIS_315
6265 	SiS_SetCRT2FIFO_310(SiS_Pr);
6266 #endif
6267      }
6268 
6269      /* 1. Horizontal setup */
6270 
6271      if(SiS_Pr->ChipType < SIS_315H ) {
6272 
6273 #ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
6274 
6275 	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
6276 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6277 
6278 	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6279 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6280 
6281 	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6282 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6283 
6284 	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6285 	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6286 	tempbx = pushbx + tempcx;
6287 	tempcx <<= 1;
6288 	tempcx += tempbx;
6289 
6290 	bridgeadd = 12;
6291 
6292 #endif /* CONFIG_FB_SIS_300 */
6293 
6294      } else {
6295 
6296 #ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
6297 
6298 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
6299 	if(modeflag & HalfDCLK) {
6300 	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6301 	      tempcx >>= 1;
6302 	   } else {
6303 	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
6304 	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6305 	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6306 	         tempcx = SiS_Pr->SiS_HT - tempax;
6307 	      }
6308 	   }
6309 	}
6310 	tempcx--;
6311 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6312 	temp = (tempcx >> 4) & 0xF0;
6313 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6314 
6315 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
6316 	tempbx = SiS_Pr->SiS_VGAHDE;
6317 	tempcx -= tempbx;
6318 	tempcx >>= 2;
6319 	if(modeflag & HalfDCLK) {
6320 	   tempbx >>= 1;
6321 	   tempcx >>= 1;
6322 	}
6323 	tempbx += 16;
6324 
6325 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6326 
6327 	pushbx = tempbx;
6328 	tempcx >>= 1;
6329 	tempbx += tempcx;
6330 	tempcx += tempbx;
6331 
6332 	bridgeadd = 16;
6333 
6334 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6335 	   if(SiS_Pr->ChipType >= SIS_661) {
6336 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6337 		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6338 		 if(resinfo == SIS_RI_1280x1024) {
6339 		    tempcx = (tempcx & 0xff00) | 0x30;
6340 		 } else if(resinfo == SIS_RI_1600x1200) {
6341 		    tempcx = (tempcx & 0xff00) | 0xff;
6342 		 }
6343 	      }
6344 	   }
6345         }
6346 
6347 #endif  /* CONFIG_FB_SIS_315 */
6348 
6349      }  /* 315/330 series */
6350 
6351      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6352 
6353 	if(SiS_Pr->UseCustomMode) {
6354 	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6355 	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6356 	   tempax = SiS_Pr->SiS_VGAHT;
6357 	   if(modeflag & HalfDCLK) tempax >>= 1;
6358 	   tempax--;
6359 	   if(tempcx > tempax) tempcx = tempax;
6360 	}
6361 
6362 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6363 	   unsigned char cr4, cr14, cr5, cr15;
6364 	   if(SiS_Pr->UseCustomMode) {
6365 	      cr4  = SiS_Pr->CCRT1CRTC[4];
6366 	      cr14 = SiS_Pr->CCRT1CRTC[14];
6367 	      cr5  = SiS_Pr->CCRT1CRTC[5];
6368 	      cr15 = SiS_Pr->CCRT1CRTC[15];
6369 	   } else {
6370 	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6371 	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6372 	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6373 	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6374 	   }
6375 	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6376 	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6377 	   tempcx &= 0x00FF;
6378 	   tempcx |= (tempbx & 0xFF00);
6379 	   tempbx += bridgeadd;
6380 	   tempcx += bridgeadd;
6381 	   tempax = SiS_Pr->SiS_VGAHT;
6382 	   if(modeflag & HalfDCLK) tempax >>= 1;
6383 	   tempax--;
6384 	   if(tempcx > tempax) tempcx = tempax;
6385 	}
6386 
6387 	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6388 	   tempbx = 1040;
6389 	   tempcx = 1044;   /* HWCursor bug! */
6390 	}
6391 
6392      }
6393 
6394      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6395 
6396      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6397 
6398      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6399      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6400 
6401      /* 2. Vertical setup */
6402 
6403      tempcx = SiS_Pr->SiS_VGAVT - 1;
6404      temp = tempcx & 0x00FF;
6405 
6406      if(SiS_Pr->ChipType < SIS_661) {
6407         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6408 	   if(SiS_Pr->ChipType < SIS_315H) {
6409 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6410 	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6411 	            temp--;
6412 	         }
6413 	      }
6414 	   } else {
6415 	      temp--;
6416 	   }
6417 	} else if(SiS_Pr->ChipType >= SIS_315H) {
6418 	   temp--;
6419 	}
6420      }
6421      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6422 
6423      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6424      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6425 
6426      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6427      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6428 
6429      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6430 	tempbx++;
6431 	tempax = tempbx;
6432 	tempcx++;
6433 	tempcx -= tempax;
6434 	tempcx >>= 2;
6435 	tempbx += tempcx;
6436 	if(tempcx < 4) tempcx = 4;
6437 	tempcx >>= 2;
6438 	tempcx += tempbx;
6439 	tempcx++;
6440      } else {
6441 	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6442 	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6443      }
6444 
6445      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6446 	if(SiS_Pr->UseCustomMode) {
6447 	   tempbx = SiS_Pr->CVSyncStart;
6448 	   tempcx = SiS_Pr->CVSyncEnd;
6449 	}
6450 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6451 	   unsigned char cr8, cr7, cr13;
6452 	   if(SiS_Pr->UseCustomMode) {
6453 	      cr8    = SiS_Pr->CCRT1CRTC[8];
6454 	      cr7    = SiS_Pr->CCRT1CRTC[7];
6455 	      cr13   = SiS_Pr->CCRT1CRTC[13];
6456 	      tempcx = SiS_Pr->CCRT1CRTC[9];
6457 	   } else {
6458 	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6459 	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6460 	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6461 	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6462 	   }
6463 	   tempbx = cr8;
6464 	   if(cr7  & 0x04) tempbx |= 0x0100;
6465 	   if(cr7  & 0x80) tempbx |= 0x0200;
6466 	   if(cr13 & 0x08) tempbx |= 0x0400;
6467 	}
6468      }
6469      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6470 
6471      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6472      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6473 
6474      /* 3. Panel delay compensation */
6475 
6476      if(SiS_Pr->ChipType < SIS_315H) {
6477 
6478 #ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
6479 
6480 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6481 	   temp = 0x20;
6482 	   if(SiS_Pr->ChipType == SIS_300) {
6483 	      temp = 0x10;
6484 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6485 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6486 	   }
6487 	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6488 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6489 	   }
6490 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6491 	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6492 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6493 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6494 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6495 	      else 					    temp = 0x20;
6496 	   }
6497 	   if(SiS_Pr->SiS_UseROM) {
6498 	      if(ROMAddr[0x220] & 0x80) {
6499 		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6500 		    temp = ROMAddr[0x221];
6501 		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6502 		    temp = ROMAddr[0x222];
6503 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6504 		    temp = ROMAddr[0x223];
6505 		 else
6506 		    temp = ROMAddr[0x224];
6507 	      }
6508 	   }
6509 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6510 	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6511 	   }
6512 
6513 	} else {
6514 	   temp = 0x20;
6515 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6516 	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6517 	   }
6518 	   if(SiS_Pr->SiS_UseROM) {
6519 	      if(ROMAddr[0x220] & 0x80) {
6520 	         temp = ROMAddr[0x220];
6521 	      }
6522 	   }
6523 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6524 	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6525 	   }
6526 	}
6527 
6528 	temp &= 0x3c;
6529 
6530 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6531 
6532 #endif  /* CONFIG_FB_SIS_300 */
6533 
6534      } else {
6535 
6536 #ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
6537 
6538 	if(SiS_Pr->ChipType < SIS_661) {
6539 
6540 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6541 
6542 	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6543 	      else 		              temp = 0x00;
6544 
6545 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6546 	      tempbl = 0xF0;
6547 	      if(SiS_Pr->ChipType == SIS_650) {
6548 		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6549 		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6550 		 }
6551 	      }
6552 
6553 	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6554 		 temp = 0x08;
6555 		 tempbl = 0;
6556 		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6557 		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6558 		 }
6559 	      }
6560 
6561 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6562 	   }
6563 
6564 	} /* < 661 */
6565 
6566 	tempax = 0;
6567 	if(modeflag & DoubleScanMode) tempax |= 0x80;
6568 	if(modeflag & HalfDCLK)       tempax |= 0x40;
6569 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6570 
6571 #endif  /* CONFIG_FB_SIS_315 */
6572 
6573      }
6574 
6575   }  /* Slavemode */
6576 
6577   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6578      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6579 	/* For 301BDH with LCD, we set up the Panel Link */
6580 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6581      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6582 	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6583      }
6584   } else {
6585      if(SiS_Pr->ChipType < SIS_315H) {
6586 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6587      } else {
6588 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6589 	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6590 	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6591 	   }
6592 	} else {
6593 	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6594 	}
6595      }
6596   }
6597 }
6598 
6599 /*********************************************/
6600 /*         SET PART 2 REGISTER GROUP         */
6601 /*********************************************/
6602 
6603 #ifdef CONFIG_FB_SIS_315
6604 static unsigned char *
SiS_GetGroup2CLVXPtr(struct SiS_Private * SiS_Pr,int tabletype)6605 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6606 {
6607    const unsigned char *tableptr = NULL;
6608    unsigned short      a, b, p = 0;
6609 
6610    a = SiS_Pr->SiS_VGAHDE;
6611    b = SiS_Pr->SiS_HDE;
6612    if(tabletype) {
6613       a = SiS_Pr->SiS_VGAVDE;
6614       b = SiS_Pr->SiS_VDE;
6615    }
6616 
6617    if(a < b) {
6618       tableptr = SiS_Part2CLVX_1;
6619    } else if(a == b) {
6620       tableptr = SiS_Part2CLVX_2;
6621    } else {
6622       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6623 	 tableptr = SiS_Part2CLVX_4;
6624       } else {
6625 	 tableptr = SiS_Part2CLVX_3;
6626       }
6627       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6628 	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
6629 	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
6630 	 else 				         	tableptr = SiS_Part2CLVX_5;
6631       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6632 	 tableptr = SiS_Part2CLVX_6;
6633       }
6634       do {
6635 	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6636 	 p += 0x42;
6637       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6638       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6639    }
6640    p += 2;
6641    return ((unsigned char *)&tableptr[p]);
6642 }
6643 
6644 static void
SiS_SetGroup2_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6645 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6646 	      	    unsigned short RefreshRateTableIndex)
6647 {
6648    unsigned char *tableptr;
6649    unsigned char temp;
6650    int i, j;
6651 
6652    if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6653 
6654    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6655    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6656       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6657    }
6658    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6659       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6660       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6661          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6662       }
6663    }
6664    temp = 0x10;
6665    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6666    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6667 }
6668 
6669 static bool
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6670 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6671 		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6672 		    unsigned short *ResIndex)
6673 {
6674 
6675   if(SiS_Pr->ChipType < SIS_315H) return false;
6676 
6677   if(ModeNo <= 0x13)
6678      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6679   else
6680      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6681 
6682   (*ResIndex) &= 0x3f;
6683   (*CRT2Index) = 0;
6684 
6685   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6686      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6687         (*CRT2Index) = 200;
6688      }
6689   }
6690 
6691   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6692      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6693         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6694      }
6695   }
6696   return (((*CRT2Index) != 0));
6697 }
6698 #endif
6699 
6700 #ifdef CONFIG_FB_SIS_300
6701 static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6702 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6703 {
6704    unsigned short tempcx;
6705    static const unsigned char atable[] = {
6706        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6707        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6708    };
6709 
6710    if(!SiS_Pr->UseCustomMode) {
6711       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6712 	      (SiS_Pr->ChipType == SIS_730) ) &&
6713 	    (SiS_Pr->ChipRevision > 2) )  &&
6714 	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6715 	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6716 	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6717 	 if(ModeNo == 0x13) {
6718 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6719 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6720 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6721 	 } else if((crt2crtc & 0x3F) == 4) {
6722 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6723 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6724 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6725 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6726 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6727 	 }
6728       }
6729 
6730       if(SiS_Pr->ChipType < SIS_315H) {
6731 	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6732 	    crt2crtc &= 0x1f;
6733 	    tempcx = 0;
6734 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6735 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6736 		  tempcx += 7;
6737 	       }
6738 	    }
6739 	    tempcx += crt2crtc;
6740 	    if(crt2crtc >= 4) {
6741 	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6742 	    }
6743 
6744 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6745 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6746 		  if(crt2crtc == 4) {
6747 		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6748 		  }
6749 	       }
6750 	    }
6751 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6752 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6753 	 }
6754       }
6755    }
6756 }
6757 
6758 /* For ECS A907. Highly preliminary. */
6759 static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6760 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6761 		    unsigned short ModeNo)
6762 {
6763   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6764   unsigned short crt2crtc, resindex;
6765   int i, j;
6766 
6767   if(SiS_Pr->ChipType != SIS_300) return;
6768   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6769   if(SiS_Pr->UseCustomMode) return;
6770 
6771   if(ModeNo <= 0x13) {
6772      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6773   } else {
6774      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6775   }
6776 
6777   resindex = crt2crtc & 0x3F;
6778   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6779   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6780 
6781   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6782   if(ModeNo > 0x13) {
6783      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6784      resindex = 4;
6785   }
6786 
6787   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6788   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6789   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6790      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6791   }
6792   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6793      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6794   }
6795   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6796      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6797   }
6798   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6799   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6800 }
6801 #endif
6802 
6803 static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6804 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6805 {
6806   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6807   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6808   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6809 
6810   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6811      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6812         static const unsigned char specialtv[] = {
6813 		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6814 		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6815 		0x58,0xe4,0x73,0xda,0x13
6816 	};
6817 	int i, j;
6818 	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6819 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6820 	}
6821 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6822 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6823 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6824 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6825 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6826 	   } else {
6827 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6828 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6829 	   }
6830 	}
6831      }
6832   } else {
6833      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6834         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6835         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6836         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6837      } else {
6838         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6839         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6840      }
6841   }
6842 }
6843 
6844 static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6845 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6846 {
6847   unsigned short temp;
6848 
6849   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6850      if(SiS_Pr->SiS_VGAVDE == 525) {
6851 	temp = 0xc3;
6852 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6853 	   temp++;
6854 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6855 	}
6856 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6857 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6858      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6859 	temp = 0x4d;
6860 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6861 	   temp++;
6862 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6863 	}
6864 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6865      }
6866   }
6867 
6868   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6869      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6870 	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6871 	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6872 	   /* Not always for LV, see SetGrp2 */
6873 	}
6874 	temp = 1;
6875 	if(ModeNo <= 0x13) temp = 3;
6876 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6877      }
6878 #if 0
6879      /* 651+301C, for 1280x768 - do I really need that? */
6880      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6881         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6882 	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6883 	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6884 	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6885 	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
6886 	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6887 	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
6888 	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6889 	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6890 	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6891 	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6892 	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
6893 	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6894 	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6895 	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
6896 	   }
6897 	}
6898      }
6899 #endif
6900   }
6901 }
6902 
6903 static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6904 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6905 		unsigned short RefreshRateTableIndex)
6906 {
6907   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6908   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6909   unsigned int   longtemp, PhaseIndex;
6910   bool           newtvphase;
6911   const unsigned char *TimingPoint;
6912 #ifdef CONFIG_FB_SIS_315
6913   unsigned short resindex, CRT2Index;
6914   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6915 
6916   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6917 #endif
6918 
6919   if(ModeNo <= 0x13) {
6920      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6921      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6922   } else if(SiS_Pr->UseCustomMode) {
6923      modeflag = SiS_Pr->CModeFlag;
6924      crt2crtc = 0;
6925   } else {
6926      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6927      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6928   }
6929 
6930   temp = 0;
6931   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6932   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6933   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6934   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6935 
6936   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
6937 
6938   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6939 
6940   PhaseIndex  = 0x01; /* SiS_PALPhase */
6941   TimingPoint = SiS_Pr->SiS_PALTiming;
6942 
6943   newtvphase = false;
6944   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6945       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6946 	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6947      newtvphase = true;
6948   }
6949 
6950   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6951 
6952      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6953      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6954         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6955         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6956 	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6957         }
6958      }
6959 
6960   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6961 
6962      i = 0;
6963      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6964      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6965 
6966      TimingPoint = &SiS_YPbPrTable[i][0];
6967 
6968      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6969 
6970   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6971 
6972      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6973 
6974   } else {
6975 
6976      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6977      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
6978      if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
6979 
6980   }
6981 
6982   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6983      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
6984      if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
6985   }
6986 
6987   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6988      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6989         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6990      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6991         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6992      } else {
6993         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6994      }
6995   }
6996 
6997   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6998      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6999   }
7000 
7001   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7002      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7003   }
7004   for(i = 0x39; i <= 0x45; i++, j++) {
7005      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7006   }
7007 
7008   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7009      if(SiS_Pr->SiS_ModeType != ModeText) {
7010         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7011      }
7012   }
7013 
7014   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7015 
7016   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7017   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7018   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7019   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7020 
7021   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
7022   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
7023   else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;
7024   else						tempax = 440; /* NTSC, YPbPr 525 */
7025 
7026   if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7027       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7028         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7029 
7030      tempax -= SiS_Pr->SiS_VDE;
7031      tempax >>= 1;
7032      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7033         tempax >>= 1;
7034      }
7035      tempax &= 0x00ff;
7036 
7037      temp = tempax + (unsigned short)TimingPoint[0];
7038      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7039 
7040      temp = tempax + (unsigned short)TimingPoint[1];
7041      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7042 
7043      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7044         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7045            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7046            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7047         } else {
7048            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7049            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7050         }
7051      }
7052 
7053   }
7054 
7055   tempcx = SiS_Pr->SiS_HT;
7056   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7057   tempcx--;
7058   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7059   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7060   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7061 
7062   tempcx = SiS_Pr->SiS_HT >> 1;
7063   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7064   tempcx += 7;
7065   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7066   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7067 
7068   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7069   tempbx += tempcx;
7070   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7071   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7072 
7073   tempbx += 8;
7074   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7075      tempbx -= 4;
7076      tempcx = tempbx;
7077   }
7078   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7079 
7080   j += 2;
7081   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7082   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7083   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7084 
7085   tempcx += 8;
7086   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7087   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7088 
7089   tempcx = SiS_Pr->SiS_HT >> 1;
7090   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7091   j += 2;
7092   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7093   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7094 
7095   tempcx -= 11;
7096   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7097      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7098   }
7099   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7100 
7101   tempbx = SiS_Pr->SiS_VDE;
7102   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7103      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7104      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7105      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7106   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7107              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7108      tempbx >>= 1;
7109      if(SiS_Pr->ChipType >= SIS_315H) {
7110         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7111 	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7112 	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7113 	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7114 	      if(crt2crtc == 4) tempbx++;
7115 	   }
7116 	}
7117      }
7118      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7119         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7120 	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7121 	}
7122 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7123 	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7124         }
7125      }
7126   }
7127   tempbx -= 2;
7128   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7129 
7130   temp = (tempcx >> 8) & 0x0F;
7131   temp |= ((tempbx >> 2) & 0xC0);
7132   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7133      temp |= 0x10;
7134      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7135   }
7136   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7137 
7138   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7139      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7140   }
7141 
7142   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7143      tempbx = SiS_Pr->SiS_VDE;
7144      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7145          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7146         tempbx >>= 1;
7147      }
7148      tempbx -= 3;
7149      temp = ((tempbx >> 3) & 0x60) | 0x18;
7150      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7151      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7152 
7153      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7154 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7155      }
7156   }
7157 
7158   tempbx = 0;
7159   if(!(modeflag & HalfDCLK)) {
7160      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7161         tempax = 0;
7162         tempbx |= 0x20;
7163      }
7164   }
7165 
7166   tempch = tempcl = 0x01;
7167   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7168      if(SiS_Pr->SiS_VGAHDE >= 960) {
7169         if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7170 	   tempcl = 0x20;
7171 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
7172               tempch = 20;
7173               tempbx &= ~0x20;
7174            } else {
7175 	      tempch = 25; /* OK */
7176 	   }
7177         }
7178      }
7179   }
7180 
7181   if(!(tempbx & 0x20)) {
7182      if(modeflag & HalfDCLK) tempcl <<= 1;
7183      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7184      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7185      tempax = longtemp / SiS_Pr->SiS_HDE;
7186      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7187      tempbx |= ((tempax >> 8) & 0x1F);
7188      tempcx = tempax >> 13;
7189   }
7190 
7191   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7192   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7193 
7194   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7195 
7196      tempcx &= 0x07;
7197      if(tempbx & 0x20) tempcx = 0;
7198      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7199 
7200      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7201         tempbx = 0x0382;
7202         tempcx = 0x007e;
7203      } else {
7204         tempbx = 0x0369;
7205         tempcx = 0x0061;
7206      }
7207      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7208      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7209      temp = (tempcx & 0x0300) >> 6;
7210      temp |= ((tempbx >> 8) & 0x03);
7211      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7212         temp |= 0x10;
7213 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7214 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7215      }
7216      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7217 
7218      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7219      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7220 
7221      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7222 
7223      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7224         temp = 0;
7225         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7226         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7227      }
7228 
7229   }
7230 
7231   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7232      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7233         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7234         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7235      }
7236      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7237   }
7238 
7239   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7240      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7241         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7242      }
7243   }
7244 
7245   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7246 
7247   /* From here: Part2 LCD setup */
7248 
7249   tempbx = SiS_Pr->SiS_HDE;
7250   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7251   tempbx--;			         	/* RHACTE = HDE - 1 */
7252   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7253   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7254 
7255   temp = 0x01;
7256   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7257      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7258         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7259            temp = 0x02;
7260            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7261               temp = 0x01;
7262 	   }
7263         }
7264      }
7265   }
7266   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7267 
7268   tempbx = SiS_Pr->SiS_VDE - 1;
7269   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7270   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7271 
7272   tempcx = SiS_Pr->SiS_VT - 1;
7273   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7274   temp = (tempcx >> 3) & 0xE0;
7275   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7276      /* Enable dithering; only do this for 32bpp mode */
7277      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7278         temp |= 0x10;
7279      }
7280   }
7281   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7282 
7283   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7284   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7285 
7286   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7287   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7288 
7289 #ifdef CONFIG_FB_SIS_315
7290   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7291                           			&CRT2Index, &resindex)) {
7292       switch(CRT2Index) {
7293         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7294 	default:
7295         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7296       }
7297 
7298       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7299       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7300       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7301         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7302       }
7303       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7304         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305       }
7306       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7307         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308       }
7309       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7310       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7311 
7312       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7313 
7314   } else {
7315 #endif
7316 
7317     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7318     /*             Clevo dual-link 1024x768 */
7319     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7320     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7321 
7322     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7323        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7324           tempbx = SiS_Pr->SiS_VDE - 1;
7325           tempcx = SiS_Pr->SiS_VT - 1;
7326        } else {
7327           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7328 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329        }
7330     } else {
7331        tempbx = SiS_Pr->PanelYRes;
7332        tempcx = SiS_Pr->SiS_VT;
7333        tempax = 1;
7334        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7335           tempax = SiS_Pr->PanelYRes;
7336 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7337           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7338              tempax = tempcx = 0;
7339           } else {
7340              tempax -= SiS_Pr->SiS_VDE;
7341           }
7342           tempax >>= 1;
7343        }
7344        tempcx -= tempax; /* lcdvdes */
7345        tempbx -= tempax; /* lcdvdee */
7346     }
7347 
7348     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7349 
7350     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7351     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7352 
7353     temp = (tempbx >> 5) & 0x38;
7354     temp |= ((tempcx >> 8) & 0x07);
7355     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7356 
7357     tempax = SiS_Pr->SiS_VDE;
7358     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7359        tempax = SiS_Pr->PanelYRes;
7360     }
7361     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7362     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7363        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7364 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7365        }
7366     }
7367 
7368     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7369     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7370        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7371           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7372              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7373 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7374 	     else           { tempax >>= 2;           }
7375              tempbx -= (tempax - 1);
7376 	  } else {
7377 	     tempbx -= 10;
7378 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7379 	  }
7380        }
7381     }
7382     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7383        tempbx++;
7384        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7385           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7386 	     tempbx = 770;
7387 	     tempcx = 3;
7388 	  }
7389        }
7390     }
7391 
7392     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7393 
7394     if(SiS_Pr->UseCustomMode) {
7395        tempbx = SiS_Pr->CVSyncStart;
7396     }
7397 
7398     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7399 
7400     temp = (tempbx >> 4) & 0xF0;
7401     tempbx += (tempcx + 1);
7402     temp |= (tempbx & 0x0F);
7403 
7404     if(SiS_Pr->UseCustomMode) {
7405        temp &= 0xf0;
7406        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7407     }
7408 
7409     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7410 
7411 #ifdef CONFIG_FB_SIS_300
7412     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7413 #endif
7414 
7415     bridgeoffset = 7;
7416     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7417     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7418     if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7419     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7420     /* Higher bridgeoffset shifts to the LEFT */
7421 
7422     temp = 0;
7423     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7424        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7425 	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7426 	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7427        }
7428     }
7429     temp += bridgeoffset;
7430     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7431     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7432 
7433     tempcx = SiS_Pr->SiS_HT;
7434     tempax = tempbx = SiS_Pr->SiS_HDE;
7435     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7436        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7437           tempax = SiS_Pr->PanelXRes;
7438           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7439        }
7440     }
7441     if(SiS_IsDualLink(SiS_Pr)) {
7442        tempcx >>= 1;
7443        tempbx >>= 1;
7444        tempax >>= 1;
7445     }
7446 
7447     tempbx += bridgeoffset;
7448 
7449     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7450     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7451 
7452     tempcx = (tempcx - tempax) >> 2;
7453 
7454     tempbx += tempcx;
7455     push2 = tempbx;
7456 
7457     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7458        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7459           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7460              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7461 	  }
7462        }
7463     }
7464 
7465     if(SiS_Pr->UseCustomMode) {
7466        tempbx = SiS_Pr->CHSyncStart;
7467        if(modeflag & HalfDCLK) tempbx <<= 1;
7468        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7469        tempbx += bridgeoffset;
7470     }
7471 
7472     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7473     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7474 
7475     tempbx = push2;
7476 
7477     tempcx <<= 1;
7478     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7479        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7480     }
7481     tempbx += tempcx;
7482 
7483     if(SiS_Pr->UseCustomMode) {
7484        tempbx = SiS_Pr->CHSyncEnd;
7485        if(modeflag & HalfDCLK) tempbx <<= 1;
7486        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7487        tempbx += bridgeoffset;
7488     }
7489 
7490     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7491 
7492     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7493 
7494 #ifdef CONFIG_FB_SIS_300
7495     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7496 #endif
7497 #ifdef CONFIG_FB_SIS_315
7498   } /* CRT2-LCD from table */
7499 #endif
7500 }
7501 
7502 /*********************************************/
7503 /*         SET PART 3 REGISTER GROUP         */
7504 /*********************************************/
7505 
7506 static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7507 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7508 {
7509   unsigned short i;
7510   const unsigned char *tempdi;
7511 
7512   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7513 
7514 #ifndef SIS_CP
7515   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7516 #else
7517   SIS_CP_INIT301_CP
7518 #endif
7519 
7520   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7521      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7522      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7523   } else {
7524      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7525      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7526   }
7527 
7528   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7529      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7530      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7531      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7532   }
7533 
7534   tempdi = NULL;
7535   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7536      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7537      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7538         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7539      }
7540   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7541      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7542         tempdi = SiS_HiTVGroup3_1;
7543         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7544      }
7545   }
7546   if(tempdi) {
7547      for(i=0; i<=0x3E; i++) {
7548         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7549      }
7550      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7551 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7552 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7553 	}
7554      }
7555   }
7556 
7557 #ifdef SIS_CP
7558   SIS_CP_INIT301_CP2
7559 #endif
7560 }
7561 
7562 /*********************************************/
7563 /*         SET PART 4 REGISTER GROUP         */
7564 /*********************************************/
7565 
7566 #ifdef CONFIG_FB_SIS_315
7567 #if 0
7568 static void
7569 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7570 {
7571    unsigned short temp, temp1, temp2;
7572 
7573    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7574    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7575    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7576    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7577    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7578    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7579    temp = (unsigned short)((int)(temp) + shift);
7580    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7581    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7582    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7583    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7584    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7585    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7586 }
7587 #endif
7588 
7589 static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7590 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7591 {
7592    unsigned short temp, temp1;
7593    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7594 
7595    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7596    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7597 
7598    if(SiS_Pr->ChipType >= XGI_20) return;
7599 
7600    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7601       if(!(ROMAddr[0x61] & 0x04)) return;
7602    }
7603 
7604    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7605    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7606    if(!(temp & 0x01)) {
7607       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7608       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7609       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7610          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7611       }
7612       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7613       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7614       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7615       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7616       else					   temp = 0x0402;
7617       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7618          temp1 = 0;
7619 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7620 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7621 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7622 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7623 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7624 	 if(ModeNo > 0x13) {
7625             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7626          }
7627       } else {
7628          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7629 	 if(temp1 == 0x01) temp |= 0x01;
7630 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7631 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7632 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7633 	 if(ModeNo > 0x13) {
7634             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7635          }
7636       }
7637 
7638 #if 0
7639       if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7640          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7641             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7642 	       if(resinfo == SIS_RI_1024x768) {
7643 	          SiS_ShiftXPos(SiS_Pr, 97);
7644 	       } else {
7645 	          SiS_ShiftXPos(SiS_Pr, 111);
7646 	       }
7647 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7648 	       SiS_ShiftXPos(SiS_Pr, 136);
7649 	    }
7650          }
7651       }
7652 #endif
7653 
7654    }
7655 
7656 }
7657 #endif
7658 
7659 static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7660 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7661                  unsigned short RefreshRateTableIndex)
7662 {
7663   unsigned short vclkindex, temp, reg1, reg2;
7664 
7665   if(SiS_Pr->UseCustomMode) {
7666      reg1 = SiS_Pr->CSR2B;
7667      reg2 = SiS_Pr->CSR2C;
7668   } else {
7669      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7670      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7671      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7672   }
7673 
7674   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7675      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7676         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7677  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7678 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7679      } else {
7680         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7681         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7682      }
7683   } else {
7684      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7685      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7686      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7687   }
7688   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7689   temp = 0x08;
7690   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7691   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7692 }
7693 
7694 static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7695 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7696 {
7697   if(SiS_Pr->ChipType >= SIS_315H) {
7698      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7699 	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7700 	   (SiS_IsVAMode(SiS_Pr))) {
7701 	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7702 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7703 	   } else {
7704 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7705 	   }
7706 	}
7707      }
7708   }
7709   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7710      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7711 #ifdef SET_EMI
7712      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7713 #endif
7714      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7715   }
7716 }
7717 
7718 static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7719 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7720 		unsigned short RefreshRateTableIndex)
7721 {
7722   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7723   unsigned int   tempebx, tempeax, templong;
7724 
7725   if(ModeNo <= 0x13) {
7726      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7727      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7728   } else if(SiS_Pr->UseCustomMode) {
7729      modeflag = SiS_Pr->CModeFlag;
7730      resinfo = 0;
7731   } else {
7732      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7733      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7734   }
7735 
7736   if(SiS_Pr->ChipType >= SIS_315H) {
7737      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7738 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7739 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7740 	}
7741      }
7742   }
7743 
7744   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7745      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7746 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7747      }
7748   }
7749 
7750   if(SiS_Pr->ChipType >= SIS_315H) {
7751      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7752 	SiS_SetDualLinkEtc(SiS_Pr);
7753 	return;
7754      }
7755   }
7756 
7757   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7758 
7759   tempbx = SiS_Pr->SiS_RVBHCMAX;
7760   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7761 
7762   temp = (tempbx >> 1) & 0x80;
7763 
7764   tempcx = SiS_Pr->SiS_VGAHT - 1;
7765   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7766 
7767   temp |= ((tempcx >> 5) & 0x78);
7768 
7769   tempcx = SiS_Pr->SiS_VGAVT - 1;
7770   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7771   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7772 
7773   temp |= ((tempcx >> 8) & 0x07);
7774   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7775 
7776   tempbx = SiS_Pr->SiS_VGAHDE;
7777   if(modeflag & HalfDCLK)    tempbx >>= 1;
7778   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7779 
7780   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7781      temp = 0;
7782      if(tempbx > 800)        temp = 0x60;
7783   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7784      temp = 0;
7785      if(tempbx > 1024)       temp = 0xC0;
7786      else if(tempbx >= 960)  temp = 0xA0;
7787   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7788      temp = 0;
7789      if(tempbx >= 1280)      temp = 0x40;
7790      else if(tempbx >= 1024) temp = 0x20;
7791   } else {
7792      temp = 0x80;
7793      if(tempbx >= 1024)      temp = 0xA0;
7794   }
7795 
7796   temp |= SiS_Pr->Init_P4_0E;
7797 
7798   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7799      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7800         temp &= 0xf0;
7801         temp |= 0x0A;
7802      }
7803   }
7804 
7805   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7806 
7807   tempeax = SiS_Pr->SiS_VGAVDE;
7808   tempebx = SiS_Pr->SiS_VDE;
7809   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7810      if(!(temp & 0xE0)) tempebx >>=1;
7811   }
7812 
7813   tempcx = SiS_Pr->SiS_RVBHRS;
7814   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7815   tempcx >>= 8;
7816   tempcx |= 0x40;
7817 
7818   if(tempeax <= tempebx) {
7819      tempcx ^= 0x40;
7820   } else {
7821      tempeax -= tempebx;
7822   }
7823 
7824   tempeax *= (256 * 1024);
7825   templong = tempeax % tempebx;
7826   tempeax /= tempebx;
7827   if(templong) tempeax++;
7828 
7829   temp = (unsigned short)(tempeax & 0x000000FF);
7830   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7831   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7832   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7833   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7834   temp |= (tempcx & 0x4F);
7835   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7836 
7837   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7838 
7839      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7840 
7841      /* Calc Linebuffer max address and set/clear decimode */
7842      tempbx = 0;
7843      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7844      tempax = SiS_Pr->SiS_VGAHDE;
7845      if(modeflag & HalfDCLK)    tempax >>= 1;
7846      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7847      if(tempax > 800) {
7848         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7849 	   tempax -= 800;
7850 	} else {
7851 	   tempbx = 0x08;
7852 	   if(tempax == 960)	   tempax *= 25; /* Correct */
7853            else if(tempax == 1024) tempax *= 25;
7854            else			   tempax *= 20;
7855 	   temp = tempax % 32;
7856 	   tempax /= 32;
7857 	   if(temp) tempax++;
7858 	   tempax++;
7859 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7860 	      if(resinfo == SIS_RI_1024x768 ||
7861 	         resinfo == SIS_RI_1024x576 ||
7862 		 resinfo == SIS_RI_1280x1024 ||
7863 		 resinfo == SIS_RI_1280x720) {
7864 	         /* Otherwise white line or garbage at right edge */
7865 	         tempax = (tempax & 0xff00) | 0x20;
7866 	      }
7867 	   }
7868 	}
7869      }
7870      tempax--;
7871      temp = ((tempax >> 4) & 0x30) | tempbx;
7872      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7873      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7874 
7875      temp = 0x0036; tempbx = 0xD0;
7876      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7877 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7878      }
7879      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7880         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7881 	   temp |= 0x01;
7882 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7883 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7884   	         temp &= ~0x01;
7885 	      }
7886 	   }
7887 	}
7888      }
7889      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7890 
7891      tempbx = SiS_Pr->SiS_HT >> 1;
7892      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7893      tempbx -= 2;
7894      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7895      temp = (tempbx >> 5) & 0x38;
7896      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7897 
7898      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7899 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7900            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7901 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7902 	}
7903      }
7904 
7905      SiS_SetDualLinkEtc(SiS_Pr);
7906 
7907   }  /* 301B */
7908 
7909   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7910 }
7911 
7912 /*********************************************/
7913 /*         SET PART 5 REGISTER GROUP         */
7914 /*********************************************/
7915 
7916 static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7917 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7918 {
7919 
7920   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7921 
7922   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7923      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7924         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7925         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7926      }
7927   }
7928 }
7929 
7930 /*********************************************/
7931 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7932 /*********************************************/
7933 
7934 static bool
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7935 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7936 		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7937 		   unsigned short *DisplayType)
7938  {
7939   unsigned short modeflag = 0;
7940   bool checkhd = true;
7941 
7942   /* Pass 1:1 not supported here */
7943 
7944   if(ModeNo <= 0x13) {
7945      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7946      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7947   } else {
7948      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7949      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7950   }
7951 
7952   (*ResIndex) &= 0x3F;
7953 
7954   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7955 
7956      (*DisplayType) = 80;
7957      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7958       	(*DisplayType) = 82;
7959 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7960 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7961 	}
7962      }
7963      if((*DisplayType) != 84) {
7964         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7965      }
7966 
7967   } else {
7968 
7969      (*DisplayType = 0);
7970      switch(SiS_Pr->SiS_LCDResInfo) {
7971      case Panel_320x240_1: (*DisplayType) = 50;
7972 			   checkhd = false;
7973 			   break;
7974      case Panel_320x240_2: (*DisplayType) = 14;
7975 			   break;
7976      case Panel_320x240_3: (*DisplayType) = 18;
7977 			   break;
7978      case Panel_640x480:   (*DisplayType) = 10;
7979 			   break;
7980      case Panel_1024x600:  (*DisplayType) = 26;
7981 			   break;
7982      default: return true;
7983      }
7984 
7985      if(checkhd) {
7986         if(modeflag & HalfDCLK) (*DisplayType)++;
7987      }
7988 
7989      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7990         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7991      }
7992 
7993   }
7994 
7995   return true;
7996 }
7997 
7998 static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7999 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8000                 unsigned short RefreshRateTableIndex)
8001 {
8002   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8003   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8004   static const unsigned short CRIdx[] = {
8005 	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8006 	0x07, 0x10, 0x11, 0x15, 0x16
8007   };
8008 
8009   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8010      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8011      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
8012      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8013      return;
8014 
8015   if(SiS_Pr->SiS_IF_DEF_LVDS) {
8016      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8017         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8018      }
8019   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8020      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8021   } else return;
8022 
8023   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8024 
8025   if(SiS_Pr->ChipType < SIS_315H) {
8026      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8027   }
8028 
8029   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8030                           &ResIndex, &DisplayType))) {
8031      return;
8032   }
8033 
8034   switch(DisplayType) {
8035     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
8036     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
8037     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
8038     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
8039     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
8040     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
8041     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
8042 #if 0 /* Works better with calculated numbers */
8043     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
8044     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
8045     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
8046     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
8047 #endif
8048     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
8049     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
8050     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
8051     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
8052     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
8053   }
8054 
8055   if(LVDSCRT1Ptr) {
8056 
8057      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8058 
8059      for(i = 0; i <= 10; i++) {
8060         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8061         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8062      }
8063 
8064      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8065         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8066         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8067      }
8068 
8069      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8070      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8071 
8072      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8073      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8074 
8075      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8076      if(modeflag & DoubleScanMode) tempah |= 0x80;
8077      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8078 
8079   } else {
8080 
8081      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8082 
8083   }
8084 }
8085 
8086 /*********************************************/
8087 /*              SET CRT2 ECLK                */
8088 /*********************************************/
8089 
8090 static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8091 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8092            unsigned short RefreshRateTableIndex)
8093 {
8094   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
8095   unsigned short clkbase, vclkindex = 0;
8096   unsigned char  sr2b, sr2c;
8097 
8098   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8099      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8100      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8101 	RefreshRateTableIndex--;
8102      }
8103      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8104                                     RefreshRateTableIndex);
8105      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8106   } else {
8107      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8108                                     RefreshRateTableIndex);
8109   }
8110 
8111   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8112   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8113 
8114   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8115      if(SiS_Pr->SiS_UseROM) {
8116 	if(ROMAddr[0x220] & 0x01) {
8117 	   sr2b = ROMAddr[0x227];
8118 	   sr2c = ROMAddr[0x228];
8119 	}
8120      }
8121   }
8122 
8123   clkbase = 0x02B;
8124   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8125      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8126 	clkbase += 3;
8127      }
8128   }
8129 
8130   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8131   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8132   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8133   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8134   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8135   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8136   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8137   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8138   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8139 }
8140 
8141 /*********************************************/
8142 /*           SET UP CHRONTEL CHIPS           */
8143 /*********************************************/
8144 
8145 static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8146 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8147                unsigned short RefreshRateTableIndex)
8148 {
8149    unsigned short TVType, resindex;
8150    const struct SiS_CHTVRegData *CHTVRegData = NULL;
8151 
8152    if(ModeNo <= 0x13)
8153       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8154    else
8155       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8156 
8157    resindex &= 0x3F;
8158 
8159    TVType = 0;
8160    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8161    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8162       TVType += 2;
8163       if(SiS_Pr->SiS_ModeType > ModeVGA) {
8164 	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8165       }
8166       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8167 	 TVType = 4;
8168 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8169       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8170 	 TVType = 6;
8171 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8172       }
8173    }
8174 
8175    switch(TVType) {
8176       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8177       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8178       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8179       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8180       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8181       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8182       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8183       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8184       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8185       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8186    }
8187 
8188 
8189    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8190 
8191 #ifdef CONFIG_FB_SIS_300
8192 
8193       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8194 
8195       /* We don't support modes >800x600 */
8196       if (resindex > 5) return;
8197 
8198       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8199 	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8200 	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
8201       } else {
8202 	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8203 	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
8204       }
8205 
8206       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
8207       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
8208       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
8209       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
8210       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
8211 
8212       /* Set minimum flicker filter for Luma channel (SR1-0=00),
8213                 minimum text enhancement (S3-2=10),
8214    	        maximum flicker filter for Chroma channel (S5-4=10)
8215 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8216        */
8217       SiS_SetCH700x(SiS_Pr,0x01,0x28);
8218 
8219       /* Set video bandwidth
8220             High bandwidth Luma composite video filter(S0=1)
8221             low bandwidth Luma S-video filter (S2-1=00)
8222 	    disable peak filter in S-video channel (S3=0)
8223 	    high bandwidth Chroma Filter (S5-4=11)
8224 	    =00110001=0x31
8225       */
8226       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
8227 
8228       /* Register 0x3D does not exist in non-macrovision register map
8229             (Maybe this is a macrovision register?)
8230        */
8231 #ifndef SIS_CP
8232       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8233 #endif
8234 
8235       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8236              all other bits a read-only. Macrovision?
8237        */
8238       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8239 
8240       /* Register 0x11 only contains 3 writable bits (S0-S2) for
8241              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8242        */
8243       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8244 
8245       /* Clear DSEN
8246        */
8247       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8248 
8249       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
8250          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8251             if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
8252       	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8253                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
8254             } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
8255                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
8256                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8257                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8258                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8259                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8260                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8261                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8262                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8263                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
8264                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
8265             }
8266          } else {
8267             if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
8268                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8269                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8270             } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
8271 #if 0
8272                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8273                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
8274                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
8275                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8276                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8277                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8278                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8279                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8280                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
8281                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
8282 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8283 	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
8284                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8285             }
8286          }
8287       } else {						/* ---- PAL ---- */
8288 	/* We don't play around with FSCI in PAL mode */
8289 	SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
8290 	SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
8291       }
8292 
8293 #endif  /* 300 */
8294 
8295    } else {
8296 
8297       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8298 
8299 #ifdef CONFIG_FB_SIS_315
8300 
8301       unsigned short temp;
8302 
8303       /* We don't support modes >1024x768 */
8304       if (resindex > 6) return;
8305 
8306       temp = CHTVRegData[resindex].Reg[0];
8307       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8308       SiS_SetCH701x(SiS_Pr,0x00,temp);
8309 
8310       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8311       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8312       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8313       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8314       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8315       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8316 
8317       temp = CHTVRegData[resindex].Reg[7];
8318       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8319       SiS_SetCH701x(SiS_Pr,0x07,temp);
8320 
8321       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8322       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8323       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8324       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8325       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8326       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8327       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8328       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8329 
8330       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8331       /* D1 should be set for PAL, PAL-N and NTSC-J,
8332          but I won't do that for PAL unless somebody
8333 	 tells me to do so. Since the BIOS uses
8334 	 non-default CIV values and blacklevels,
8335 	 this might be compensated anyway.
8336        */
8337       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8338       SiS_SetCH701x(SiS_Pr,0x21,temp);
8339 
8340 #endif	/* 315 */
8341 
8342    }
8343 
8344 #ifdef SIS_CP
8345    SIS_CP_INIT301_CP3
8346 #endif
8347 
8348 }
8349 
8350 #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8351 
8352 void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8353 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8354 {
8355    unsigned short temp;
8356 
8357    /* Enable Chrontel 7019 LCD panel backlight */
8358    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8359       if(SiS_Pr->ChipType == SIS_740) {
8360 	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8361       } else {
8362 	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8363 	 temp |= 0x20;
8364 	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8365       }
8366    }
8367 }
8368 
8369 void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8370 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8371 {
8372    unsigned short temp;
8373 
8374    /* Disable Chrontel 7019 LCD panel backlight */
8375    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8376       temp = SiS_GetCH701x(SiS_Pr,0x66);
8377       temp &= 0xDF;
8378       SiS_SetCH701x(SiS_Pr,0x66,temp);
8379    }
8380 }
8381 
8382 static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8383 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8384 {
8385   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8386   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8387   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8388   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8389   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8391   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392   const unsigned char *tableptr = NULL;
8393   int i;
8394 
8395   /* Set up Power up/down timing */
8396 
8397   if(SiS_Pr->ChipType == SIS_740) {
8398      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8399 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8400 	else    			          tableptr = table1024_740;
8401      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8402 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8403 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8404 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8405         else					  tableptr = table1400_740;
8406      } else return;
8407   } else {
8408      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8409 	tableptr = table1024_650;
8410      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8411 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8412 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8413 	tableptr = table1400_650;
8414      } else return;
8415   }
8416 
8417   for(i=0; i<5; i++) {
8418      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8419   }
8420 }
8421 
8422 static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8423 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8424 {
8425   const unsigned char *tableptr = NULL;
8426   unsigned short tempbh;
8427   int i;
8428   static const unsigned char regtable[] = {
8429 		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8430 		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8431   };
8432   static const unsigned char table1024_740[] = {
8433 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8434 		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8435   };
8436   static const unsigned char table1280_740[] = {
8437 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8438 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8439   };
8440   static const unsigned char table1400_740[] = {
8441 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8442 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8443   };
8444   static const unsigned char table1600_740[] = {
8445 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8446 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8447   };
8448   static const unsigned char table1024_650[] = {
8449 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8450 		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8451   };
8452   static const unsigned char table1280_650[] = {
8453 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8454 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8455   };
8456   static const unsigned char table1400_650[] = {
8457 		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8458 		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8459   };
8460   static const unsigned char table1600_650[] = {
8461 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8462 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8463   };
8464 
8465   if(SiS_Pr->ChipType == SIS_740) {
8466      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8467      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8468      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8469      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8470      else return;
8471   } else {
8472      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8473      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8474      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8475      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8476      else return;
8477   }
8478 
8479   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8480   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8481      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8482      if(tempbh == 0xc8) {
8483         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8484      } else if(tempbh == 0xdb) {
8485         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8486 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8487      } else if(tempbh == 0xde) {
8488         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8489      }
8490   }
8491 
8492   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8493   else     			  tempbh = 0x0c;
8494 
8495   for(i = 0; i < tempbh; i++) {
8496      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8497   }
8498   SiS_ChrontelPowerSequencing(SiS_Pr);
8499   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8500   tempbh |= 0xc0;
8501   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8502 
8503   if(SiS_Pr->ChipType == SIS_740) {
8504      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8505      tempbh &= 0xfb;
8506      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8507      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8508      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8509      tempbh |= 0x40;
8510      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8511      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8512      tempbh &= 0x3f;
8513      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8514   }
8515 }
8516 
8517 static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8518 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8519 {
8520   unsigned char temp, temp1;
8521 
8522   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8523   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8524   temp = SiS_GetCH701x(SiS_Pr,0x47);
8525   temp &= 0x7f;	/* Use external VSYNC */
8526   SiS_SetCH701x(SiS_Pr,0x47,temp);
8527   SiS_LongDelay(SiS_Pr, 3);
8528   temp = SiS_GetCH701x(SiS_Pr,0x47);
8529   temp |= 0x80;	/* Use internal VSYNC */
8530   SiS_SetCH701x(SiS_Pr,0x47,temp);
8531   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8532 }
8533 
8534 static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8535 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8536 {
8537   unsigned short temp;
8538 
8539   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8540      if(SiS_Pr->ChipType == SIS_740) {
8541         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8542         temp |= 0x04;	/* Invert XCLK phase */
8543         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8544      }
8545      if(SiS_IsYPbPr(SiS_Pr)) {
8546         temp = SiS_GetCH701x(SiS_Pr,0x01);
8547 	temp &= 0x3f;
8548 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8549 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8550      }
8551      if(SiS_IsChScart(SiS_Pr)) {
8552         temp = SiS_GetCH701x(SiS_Pr,0x01);
8553 	temp &= 0x3f;
8554 	temp |= 0xc0;	/* Enable SCART + CVBS */
8555 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8556      }
8557      if(SiS_Pr->ChipType == SIS_740) {
8558         SiS_ChrontelResetVSync(SiS_Pr);
8559         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8560      } else {
8561         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8562         temp = SiS_GetCH701x(SiS_Pr,0x49);
8563         if(SiS_IsYPbPr(SiS_Pr)) {
8564            temp = SiS_GetCH701x(SiS_Pr,0x73);
8565 	   temp |= 0x60;
8566 	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8567         }
8568         temp = SiS_GetCH701x(SiS_Pr,0x47);
8569         temp &= 0x7f;
8570         SiS_SetCH701x(SiS_Pr,0x47,temp);
8571         SiS_LongDelay(SiS_Pr, 2);
8572         temp = SiS_GetCH701x(SiS_Pr,0x47);
8573         temp |= 0x80;
8574         SiS_SetCH701x(SiS_Pr,0x47,temp);
8575      }
8576   }
8577 }
8578 
8579 static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8580 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8581 {
8582   unsigned short temp;
8583 
8584   /* Complete power down of LVDS */
8585   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8586      if(SiS_Pr->ChipType == SIS_740) {
8587         SiS_LongDelay(SiS_Pr, 1);
8588 	SiS_GenericDelay(SiS_Pr, 5887);
8589 	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8590 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8591      } else {
8592         SiS_LongDelay(SiS_Pr, 2);
8593 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8594 	temp &= 0xfc;
8595 	SiS_SetCH701x(SiS_Pr,0x76,temp);
8596 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8597      }
8598   }
8599 }
8600 
8601 static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8602 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8603 {
8604      unsigned short temp;
8605 
8606      if(SiS_Pr->ChipType == SIS_740) {
8607 
8608         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8609         temp &= 0x01;
8610         if(!temp) {
8611 
8612            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8613 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8614 	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8615 	   }
8616 
8617 	   /* Reset Chrontel 7019 datapath */
8618            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8619            SiS_LongDelay(SiS_Pr, 1);
8620            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8621 
8622 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8623 	      SiS_ChrontelResetVSync(SiS_Pr);
8624 	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8625 	   }
8626 
8627         } else {
8628 
8629 	   /* Clear/set/clear GPIO */
8630            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8631 	   temp &= 0xef;
8632 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8633 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8634 	   temp |= 0x10;
8635 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8636 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8637 	   temp &= 0xef;
8638 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8639 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8640 	   if(!temp) {
8641 	      SiS_SetCH701xForLCD(SiS_Pr);
8642 	   }
8643         }
8644 
8645      } else { /* 650 */
8646         /* Reset Chrontel 7019 datapath */
8647         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8648         SiS_LongDelay(SiS_Pr, 1);
8649         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8650      }
8651 }
8652 
8653 static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8654 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8655 {
8656      unsigned short temp;
8657 
8658      if(SiS_Pr->ChipType == SIS_740) {
8659 
8660         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8661            SiS_ChrontelResetVSync(SiS_Pr);
8662         }
8663 
8664      } else {
8665 
8666         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8667         temp = SiS_GetCH701x(SiS_Pr,0x49);
8668         temp &= 1;
8669         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8670 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8671 	   temp &= 0x70;
8672 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8673 	   SiS_LongDelay(SiS_Pr, 3);
8674 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8675 	   temp |= 0x80;
8676 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8677         }
8678 
8679      }
8680 }
8681 
8682 static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8683 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8684 {
8685      unsigned short temp,temp1;
8686 
8687      if(SiS_Pr->ChipType == SIS_740) {
8688 
8689         temp = SiS_GetCH701x(SiS_Pr,0x61);
8690         if(temp < 1) {
8691            temp++;
8692 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8693         }
8694         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8695         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8696         SiS_LongDelay(SiS_Pr, 1);
8697         SiS_GenericDelay(SiS_Pr, 5887);
8698 
8699      } else {  /* 650 */
8700 
8701         temp1 = 0;
8702         temp = SiS_GetCH701x(SiS_Pr,0x61);
8703         if(temp < 2) {
8704            temp++;
8705 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8706 	   temp1 = 1;
8707         }
8708         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8709         temp = SiS_GetCH701x(SiS_Pr,0x66);
8710         temp |= 0x5f;
8711         SiS_SetCH701x(SiS_Pr,0x66,temp);
8712         if(ModeNo > 0x13) {
8713            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8714 	      SiS_GenericDelay(SiS_Pr, 1023);
8715 	   } else {
8716 	      SiS_GenericDelay(SiS_Pr, 767);
8717 	   }
8718         } else {
8719            if(!temp1)
8720 	      SiS_GenericDelay(SiS_Pr, 767);
8721         }
8722         temp = SiS_GetCH701x(SiS_Pr,0x76);
8723         temp |= 0x03;
8724         SiS_SetCH701x(SiS_Pr,0x76,temp);
8725         temp = SiS_GetCH701x(SiS_Pr,0x66);
8726         temp &= 0x7f;
8727         SiS_SetCH701x(SiS_Pr,0x66,temp);
8728         SiS_LongDelay(SiS_Pr, 1);
8729 
8730      }
8731 }
8732 
8733 static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8734 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8735 {
8736      unsigned short temp;
8737 
8738      SiS_LongDelay(SiS_Pr, 1);
8739 
8740      do {
8741        temp = SiS_GetCH701x(SiS_Pr,0x66);
8742        temp &= 0x04;  /* PLL stable? -> bail out */
8743        if(temp == 0x04) break;
8744 
8745        if(SiS_Pr->ChipType == SIS_740) {
8746           /* Power down LVDS output, PLL normal operation */
8747           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8748        }
8749 
8750        SiS_SetCH701xForLCD(SiS_Pr);
8751 
8752        temp = SiS_GetCH701x(SiS_Pr,0x76);
8753        temp &= 0xfb;  /* Reset PLL */
8754        SiS_SetCH701x(SiS_Pr,0x76,temp);
8755        SiS_LongDelay(SiS_Pr, 2);
8756        temp = SiS_GetCH701x(SiS_Pr,0x76);
8757        temp |= 0x04;  /* PLL normal operation */
8758        SiS_SetCH701x(SiS_Pr,0x76,temp);
8759        if(SiS_Pr->ChipType == SIS_740) {
8760           SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8761        } else {
8762           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8763        }
8764        SiS_LongDelay(SiS_Pr, 2);
8765     } while(0);
8766 
8767     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8768 }
8769 
8770 static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8771 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8772 {
8773      unsigned short temp;
8774 
8775      temp = SiS_GetCH701x(SiS_Pr,0x03);
8776      temp |= 0x80;	/* Set datapath 1 to TV   */
8777      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8778      SiS_SetCH701x(SiS_Pr,0x03,temp);
8779 
8780      if(SiS_Pr->ChipType == SIS_740) {
8781 
8782         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8783         temp &= 0xfb;	/* Normal XCLK phase */
8784         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8785 
8786         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8787 
8788         temp = SiS_GetCH701x(SiS_Pr,0x64);
8789         temp |= 0x40;	/* ? Bit not defined */
8790         SiS_SetCH701x(SiS_Pr,0x64,temp);
8791 
8792         temp = SiS_GetCH701x(SiS_Pr,0x03);
8793         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8794         SiS_SetCH701x(SiS_Pr,0x03,temp);
8795 
8796 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8797 	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8798 	   SiS_LongDelay(SiS_Pr, 1);
8799 	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8800 	   SiS_ChrontelResetDB(SiS_Pr);
8801 	   SiS_ChrontelDoSomething2(SiS_Pr);
8802 	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8803 	} else {
8804            temp = SiS_GetCH701x(SiS_Pr,0x66);
8805            if(temp != 0x45) {
8806               SiS_ChrontelResetDB(SiS_Pr);
8807               SiS_ChrontelDoSomething2(SiS_Pr);
8808               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8809            }
8810 	}
8811 
8812      } else { /* 650 */
8813 
8814         SiS_ChrontelResetDB(SiS_Pr);
8815         SiS_ChrontelDoSomething2(SiS_Pr);
8816         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8817         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8818         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8819 
8820      }
8821 
8822 }
8823 #endif  /* 315 series  */
8824 
8825 /*********************************************/
8826 /*      MAIN: SET CRT2 REGISTER GROUP        */
8827 /*********************************************/
8828 
8829 bool
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8830 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8831 {
8832 #ifdef CONFIG_FB_SIS_300
8833    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8834 #endif
8835    unsigned short ModeIdIndex, RefreshRateTableIndex;
8836 
8837    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8838 
8839    if(!SiS_Pr->UseCustomMode) {
8840       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8841    } else {
8842       ModeIdIndex = 0;
8843    }
8844 
8845    /* Used for shifting CR33 */
8846    SiS_Pr->SiS_SelectCRT2Rate = 4;
8847 
8848    SiS_UnLockCRT2(SiS_Pr);
8849 
8850    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8851 
8852    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8853 
8854    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8855       SiS_DisableBridge(SiS_Pr);
8856       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8857          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8858       }
8859       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8860    }
8861 
8862    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8863       SiS_LockCRT2(SiS_Pr);
8864       SiS_DisplayOn(SiS_Pr);
8865       return true;
8866    }
8867 
8868    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8869 
8870    /* Set up Panel Link for LVDS and LCDA */
8871    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8872    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8873        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8874        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8875       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8876    }
8877 
8878    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8879       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8880    }
8881 
8882    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8883 
8884       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8885 
8886 	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8887 #ifdef CONFIG_FB_SIS_315
8888 	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8889 #endif
8890 	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8891 	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8892 #ifdef CONFIG_FB_SIS_315
8893 	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8894 #endif
8895 	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8896 
8897 	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8898 
8899 	 /* For 301BDH (Panel link initialization): */
8900 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8901 
8902 	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8903 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8904 		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8905 	       }
8906             }
8907 	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8908 	 }
8909       }
8910 
8911    } else {
8912 
8913       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8914 
8915       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8916 
8917       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8918 
8919       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8920 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8921 	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8922 	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8923 #ifdef CONFIG_FB_SIS_315
8924 		  SiS_SetCH701xForLCD(SiS_Pr);
8925 #endif
8926 	       }
8927 	    }
8928 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8929 	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8930 	    }
8931 	 }
8932       }
8933 
8934    }
8935 
8936 #ifdef CONFIG_FB_SIS_300
8937    if(SiS_Pr->ChipType < SIS_315H) {
8938       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8939 	 if(SiS_Pr->SiS_UseOEM) {
8940 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8941 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8942 		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8943 	       }
8944 	    } else {
8945 	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8946 	    }
8947 	 }
8948 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8949 	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8950 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8951 	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8952 	    }
8953 	    SiS_DisplayOn(SiS_Pr);
8954          }
8955       }
8956    }
8957 #endif
8958 
8959 #ifdef CONFIG_FB_SIS_315
8960    if(SiS_Pr->ChipType >= SIS_315H) {
8961       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8962 	 if(SiS_Pr->ChipType < SIS_661) {
8963 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8964 	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8965 	 } else {
8966 	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8967 	 }
8968 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8969       }
8970    }
8971 #endif
8972 
8973    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8974       SiS_EnableBridge(SiS_Pr);
8975    }
8976 
8977    SiS_DisplayOn(SiS_Pr);
8978 
8979    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8980       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8981 	 /* Disable LCD panel when using TV */
8982 	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8983       } else {
8984 	 /* Disable TV when using LCD */
8985 	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8986       }
8987    }
8988 
8989    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8990       SiS_LockCRT2(SiS_Pr);
8991    }
8992 
8993    return true;
8994 }
8995 
8996 
8997 /*********************************************/
8998 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8999 /*********************************************/
9000 
9001 void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)9002 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9003 {
9004   /* Switch on LCD backlight on SiS30xLV */
9005   SiS_DDC2Delay(SiS_Pr,0xff00);
9006   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9007      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9008      SiS_WaitVBRetrace(SiS_Pr);
9009   }
9010   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9011      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9012   }
9013 }
9014 
9015 void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)9016 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9017 {
9018   /* Switch off LCD backlight on SiS30xLV */
9019   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9020   SiS_DDC2Delay(SiS_Pr,0xff00);
9021 }
9022 
9023 /*********************************************/
9024 /*          DDC RELATED FUNCTIONS            */
9025 /*********************************************/
9026 
9027 static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)9028 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9029 {
9030   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9031   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
9032   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9033      SiS_Pr->SiS_DDC_NData &= 0x0f;
9034      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
9035   }
9036 }
9037 
9038 #ifdef CONFIG_FB_SIS_300
9039 static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9040 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9041 {
9042   int i, j, num;
9043   unsigned short tempah,temp;
9044   unsigned char *mydataptr;
9045 
9046   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9047      mydataptr = dataptr;
9048      num = *mydataptr++;
9049      if(!num) return mydataptr;
9050      if(i) {
9051         SiS_SetStop(SiS_Pr);
9052 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9053      }
9054      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
9055      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9056      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
9057      if(temp) continue;				/*    (ERROR: no ack) */
9058      tempah = *mydataptr++;
9059      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
9060      if(temp) continue;				/*    (ERROR: no ack) */
9061      for(j=0; j<num; j++) {
9062         tempah = *mydataptr++;
9063         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9064 	if(temp) break;
9065      }
9066      if(temp) continue;
9067      if(SiS_SetStop(SiS_Pr)) continue;
9068      return mydataptr;
9069   }
9070   return NULL;
9071 }
9072 
9073 static bool
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9074 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9075 {
9076   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
9077   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9078   SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
9079   SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
9080   SiS_SetupDDCN(SiS_Pr);
9081 
9082   SiS_SetSwitchDDC2(SiS_Pr);
9083 
9084   while(*dataptr) {
9085      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9086      if(!dataptr) return false;
9087   }
9088   return true;
9089 }
9090 #endif
9091 
9092 /* The Chrontel 700x is connected to the 630/730 via
9093  * the 630/730's DDC/I2C port.
9094  *
9095  * On 630(S)T chipset, the index changed from 0x11 to
9096  * 0x0a, possibly for working around the DDC problems
9097  */
9098 
9099 static bool
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)9100 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9101 {
9102   unsigned short temp, i;
9103 
9104   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9105      if(i) {
9106 	SiS_SetStop(SiS_Pr);
9107 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9108      }
9109      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9110      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9111      if(temp) continue;							/*    (ERROR: no ack) */
9112      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
9113      if(temp) continue;							/*    (ERROR: no ack) */
9114      temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
9115      if(temp) continue;							/*    (ERROR: no ack) */
9116      if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
9117      SiS_Pr->SiS_ChrontelInit = 1;
9118      return true;
9119   }
9120   return false;
9121 }
9122 
9123 /* Write to Chrontel 700x */
9124 void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9125 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9126 {
9127   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9128 
9129   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9130 
9131   if(!(SiS_Pr->SiS_ChrontelInit)) {
9132      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9133      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9134      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9135      SiS_SetupDDCN(SiS_Pr);
9136   }
9137 
9138   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9139       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9140      SiS_Pr->SiS_DDC_Index = 0x0a;
9141      SiS_Pr->SiS_DDC_Data  = 0x80;
9142      SiS_Pr->SiS_DDC_Clk   = 0x40;
9143      SiS_SetupDDCN(SiS_Pr);
9144 
9145      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9146   }
9147 }
9148 
9149 /* Write to Chrontel 701x */
9150 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9151 void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9152 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9153 {
9154   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9155   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9156   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9157   SiS_SetupDDCN(SiS_Pr);
9158   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
9159   SiS_SetChReg(SiS_Pr, reg, val, 0);
9160 }
9161 
9162 static
9163 void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9164 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9165 {
9166   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9167      SiS_SetCH700x(SiS_Pr, reg, val);
9168   else
9169      SiS_SetCH701x(SiS_Pr, reg, val);
9170 }
9171 
9172 static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)9173 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9174 {
9175   unsigned short tempah, temp, i;
9176 
9177   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
9178      if(i) {
9179 	SiS_SetStop(SiS_Pr);
9180 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9181      }
9182      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9183      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9184      if(temp) continue;							/*        (ERROR: no ack) */
9185      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
9186      if(temp) continue;							/*        (ERROR: no ack) */
9187      if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
9188      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9189      if(temp) continue;							/*        (ERROR: no ack) */
9190      tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
9191      if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
9192      SiS_Pr->SiS_ChrontelInit = 1;
9193      return tempah;
9194   }
9195   return 0xFFFF;
9196 }
9197 
9198 /* Read from Chrontel 700x */
9199 /* Parameter is [Register no (S7-S0)] */
9200 unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9201 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9202 {
9203   unsigned short result;
9204 
9205   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9206 
9207   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9208 
9209   if(!(SiS_Pr->SiS_ChrontelInit)) {
9210      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9211      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9212      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9213      SiS_SetupDDCN(SiS_Pr);
9214   }
9215 
9216   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9217 
9218   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9219       (!SiS_Pr->SiS_ChrontelInit) ) {
9220 
9221      SiS_Pr->SiS_DDC_Index = 0x0a;
9222      SiS_Pr->SiS_DDC_Data  = 0x80;
9223      SiS_Pr->SiS_DDC_Clk   = 0x40;
9224      SiS_SetupDDCN(SiS_Pr);
9225 
9226      result = SiS_GetChReg(SiS_Pr,0x80);
9227   }
9228   return result;
9229 }
9230 
9231 /* Read from Chrontel 701x */
9232 /* Parameter is [Register no (S7-S0)] */
9233 unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9234 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9235 {
9236   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9237   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9238   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9239   SiS_SetupDDCN(SiS_Pr);
9240   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9241 
9242   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9243 
9244   return SiS_GetChReg(SiS_Pr,0);
9245 }
9246 
9247 /* Read from Chrontel 70xx */
9248 /* Parameter is [Register no (S7-S0)] */
9249 static
9250 unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)9251 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9252 {
9253   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9254      return SiS_GetCH700x(SiS_Pr, tempbx);
9255   else
9256      return SiS_GetCH701x(SiS_Pr, tempbx);
9257 }
9258 
9259 void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)9260 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9261 		unsigned char myor, unsigned short myand)
9262 {
9263   unsigned short tempbl;
9264 
9265   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9266   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9267 }
9268 
9269 /* Our own DDC functions */
9270 static
9271 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)9272 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9273                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9274 		unsigned int VBFlags2)
9275 {
9276      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9277      unsigned char flag, cr32;
9278      unsigned short        temp = 0, myadaptnum = adaptnum;
9279 
9280      if(adaptnum != 0) {
9281 	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9282 	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9283      }
9284 
9285      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9286 
9287      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9288 
9289      SiS_Pr->SiS_DDC_SecAddr = 0;
9290      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9291      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9292      SiS_Pr->SiS_DDC_Index = 0x11;
9293      flag = 0xff;
9294 
9295      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9296 
9297 #if 0
9298      if(VBFlags2 & VB2_SISBRIDGE) {
9299 	if(myadaptnum == 0) {
9300 	   if(!(cr32 & 0x20)) {
9301 	      myadaptnum = 2;
9302 	      if(!(cr32 & 0x10)) {
9303 	         myadaptnum = 1;
9304 		 if(!(cr32 & 0x08)) {
9305 		    myadaptnum = 0;
9306 		 }
9307 	      }
9308 	   }
9309         }
9310      }
9311 #endif
9312 
9313      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9314 
9315         if(myadaptnum != 0) {
9316 	   flag = 0;
9317 	   if(VBFlags2 & VB2_SISBRIDGE) {
9318 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9319               SiS_Pr->SiS_DDC_Index = 0x0f;
9320 	   }
9321         }
9322 
9323 	if(!(VBFlags2 & VB2_301)) {
9324 	   if((cr32 & 0x80) && (checkcr32)) {
9325               if(myadaptnum >= 1) {
9326 	         if(!(cr32 & 0x08)) {
9327 		     myadaptnum = 1;
9328 		     if(!(cr32 & 0x10)) return 0xFFFF;
9329                  }
9330 	      }
9331 	   }
9332 	}
9333 
9334 	temp = 4 - (myadaptnum * 2);
9335 	if(flag) temp = 0;
9336 
9337      } else {						/* 315/330 series */
9338 
9339 	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9340 
9341 	if(VBFlags2 & VB2_SISBRIDGE) {
9342 	   if(myadaptnum == 2) {
9343 	      myadaptnum = 1;
9344 	   }
9345 	}
9346 
9347         if(myadaptnum == 1) {
9348 	   flag = 0;
9349 	   if(VBFlags2 & VB2_SISBRIDGE) {
9350 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9351               SiS_Pr->SiS_DDC_Index = 0x0f;
9352 	   }
9353         }
9354 
9355         if((cr32 & 0x80) && (checkcr32)) {
9356            if(myadaptnum >= 1) {
9357 	      if(!(cr32 & 0x08)) {
9358 	         myadaptnum = 1;
9359 		 if(!(cr32 & 0x10)) return 0xFFFF;
9360 	      }
9361 	   }
9362         }
9363 
9364         temp = myadaptnum;
9365         if(myadaptnum == 1) {
9366            temp = 0;
9367 	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9368         }
9369 
9370 	if(flag) temp = 0;
9371     }
9372 
9373     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9374     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9375 
9376     SiS_SetupDDCN(SiS_Pr);
9377 
9378     return 0;
9379 }
9380 
9381 static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9382 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9383 {
9384    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9385    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9386       return 0xFFFF;
9387    }
9388    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9389       return 0xFFFF;
9390    }
9391    return 0;
9392 }
9393 
9394 static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9395 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9396 {
9397    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9398    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9399       return 0xFFFF;
9400    }
9401    return 0;
9402 }
9403 
9404 static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9405 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9406 {
9407    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9408    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9409    return 0;
9410 }
9411 
9412 static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9413 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9414 {
9415    SiS_SetSCLKLow(SiS_Pr);
9416    if(yesno) {
9417       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418 		      SiS_Pr->SiS_DDC_Index,
9419 		      SiS_Pr->SiS_DDC_NData,
9420 		      SiS_Pr->SiS_DDC_Data);
9421    } else {
9422       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9423 		      SiS_Pr->SiS_DDC_Index,
9424 		      SiS_Pr->SiS_DDC_NData,
9425 		      0);
9426    }
9427    SiS_SetSCLKHigh(SiS_Pr);
9428 }
9429 
9430 static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9431 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9432 {
9433     unsigned char mask, value;
9434     unsigned short  temp, ret=0;
9435     bool failed = false;
9436 
9437     SiS_SetSwitchDDC2(SiS_Pr);
9438     if(SiS_PrepareDDC(SiS_Pr)) {
9439          SiS_SetStop(SiS_Pr);
9440          return 0xFFFF;
9441     }
9442     mask = 0xf0;
9443     value = 0x20;
9444     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9445        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9446        SiS_SendACK(SiS_Pr, 0);
9447        if(temp == 0) {
9448            mask = 0xff;
9449 	   value = 0xff;
9450        } else {
9451            failed = true;
9452 	   ret = 0xFFFF;
9453        }
9454     }
9455     if(!failed) {
9456        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9457        SiS_SendACK(SiS_Pr, 1);
9458        temp &= mask;
9459        if(temp == value) ret = 0;
9460        else {
9461           ret = 0xFFFF;
9462           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9463              if(temp == 0x30) ret = 0;
9464           }
9465        }
9466     }
9467     SiS_SetStop(SiS_Pr);
9468     return ret;
9469 }
9470 
9471 static
9472 unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9473 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9474 {
9475    unsigned short flag;
9476 
9477    flag = 0x180;
9478    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9479    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9480    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9481    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9482    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9483    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9484    if(!(flag & 0x1a)) flag = 0;
9485    return flag;
9486 }
9487 
9488 static
9489 unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9490 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9491 {
9492    unsigned short flag, length, i;
9493    unsigned char chksum,gotcha;
9494 
9495    if(DDCdatatype > 4) return 0xFFFF;
9496 
9497    flag = 0;
9498    SiS_SetSwitchDDC2(SiS_Pr);
9499    if(!(SiS_PrepareDDC(SiS_Pr))) {
9500       length = 127;
9501       if(DDCdatatype != 1) length = 255;
9502       chksum = 0;
9503       gotcha = 0;
9504       for(i=0; i<length; i++) {
9505 	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9506 	 chksum += buffer[i];
9507 	 gotcha |= buffer[i];
9508 	 SiS_SendACK(SiS_Pr, 0);
9509       }
9510       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9511       chksum += buffer[i];
9512       SiS_SendACK(SiS_Pr, 1);
9513       if(gotcha) flag = (unsigned short)chksum;
9514       else flag = 0xFFFF;
9515    } else {
9516       flag = 0xFFFF;
9517    }
9518    SiS_SetStop(SiS_Pr);
9519    return flag;
9520 }
9521 
9522 /* Our private DDC functions
9523 
9524    It complies somewhat with the corresponding VESA function
9525    in arguments and return values.
9526 
9527    Since this is probably called before the mode is changed,
9528    we use our pre-detected pSiS-values instead of SiS_Pr as
9529    regards chipset and video bridge type.
9530 
9531    Arguments:
9532        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9533                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9534 		 LCDA is CRT1, but DDC is read from CRT2 port.
9535        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9536        buffer: ptr to 256 data bytes which will be filled with read data.
9537 
9538    Returns 0xFFFF if error, otherwise
9539        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9540        if DDCdatatype = 0:  Returns supported DDC modes
9541 
9542  */
9543 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)9544 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9545               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9546 	      unsigned int VBFlags2)
9547 {
9548    unsigned char  sr1f, cr17=1;
9549    unsigned short result;
9550 
9551    if(adaptnum > 2)
9552       return 0xFFFF;
9553 
9554    if(DDCdatatype > 4)
9555       return 0xFFFF;
9556 
9557    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9558       return 0xFFFF;
9559 
9560    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9561       return 0xFFFF;
9562 
9563    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9564    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9565    if(VGAEngine == SIS_300_VGA) {
9566       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9567       if(!cr17) {
9568          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9569          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9570          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9571       }
9572    }
9573    if((sr1f) || (!cr17)) {
9574       SiS_WaitRetrace1(SiS_Pr);
9575       SiS_WaitRetrace1(SiS_Pr);
9576       SiS_WaitRetrace1(SiS_Pr);
9577       SiS_WaitRetrace1(SiS_Pr);
9578    }
9579 
9580    if(DDCdatatype == 0) {
9581       result = SiS_ProbeDDC(SiS_Pr);
9582    } else {
9583       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9584       if((!result) && (DDCdatatype == 1)) {
9585          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9586 	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9587 	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9588 	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9589 	    (buffer[0x12] == 1)) {
9590 	    if(!SiS_Pr->DDCPortMixup) {
9591 	       if(adaptnum == 1) {
9592 	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9593 	       } else {
9594 	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9595 	       }
9596 	    }
9597 	 }
9598       }
9599    }
9600    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9601    if(VGAEngine == SIS_300_VGA) {
9602       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9603    }
9604    return result;
9605 }
9606 
9607 /* Generic I2C functions for Chrontel & DDC --------- */
9608 
9609 static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9610 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9611 {
9612   SiS_SetSCLKHigh(SiS_Pr);
9613   SiS_WaitRetrace1(SiS_Pr);
9614 
9615   SiS_SetSCLKLow(SiS_Pr);
9616   SiS_WaitRetrace1(SiS_Pr);
9617 }
9618 
9619 unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9620 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9621 {
9622    SiS_WaitRetrace1(SiS_Pr);
9623    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9624 }
9625 
9626 /* Set I2C start condition */
9627 /* This is done by a SD high-to-low transition while SC is high */
9628 static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9629 SiS_SetStart(struct SiS_Private *SiS_Pr)
9630 {
9631   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9632   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9633 		  SiS_Pr->SiS_DDC_Index,
9634 		  SiS_Pr->SiS_DDC_NData,
9635 		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9636   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9637   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9638 		  SiS_Pr->SiS_DDC_Index,
9639 		  SiS_Pr->SiS_DDC_NData,
9640 		  0x00);					/* SD->low = start condition */
9641   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9642   return 0;
9643 }
9644 
9645 /* Set I2C stop condition */
9646 /* This is done by a SD low-to-high transition while SC is high */
9647 static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9648 SiS_SetStop(struct SiS_Private *SiS_Pr)
9649 {
9650   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9651   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9652 		  SiS_Pr->SiS_DDC_Index,
9653 		  SiS_Pr->SiS_DDC_NData,
9654 		  0x00);					/* SD->low   */
9655   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9656   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9657 		  SiS_Pr->SiS_DDC_Index,
9658 		  SiS_Pr->SiS_DDC_NData,
9659 		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9660   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9661   return 0;
9662 }
9663 
9664 /* Write 8 bits of data */
9665 static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9666 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9667 {
9668   unsigned short i,flag,temp;
9669 
9670   flag = 0x80;
9671   for(i = 0; i < 8; i++) {
9672     SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9673     if(tempax & flag) {
9674       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9675 		      SiS_Pr->SiS_DDC_Index,
9676 		      SiS_Pr->SiS_DDC_NData,
9677 		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9678     } else {
9679       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9680 		      SiS_Pr->SiS_DDC_Index,
9681 		      SiS_Pr->SiS_DDC_NData,
9682 		      0x00);					/* Write bit (0) to SD */
9683     }
9684     SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9685     flag >>= 1;
9686   }
9687   temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9688   return temp;
9689 }
9690 
9691 static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9692 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9693 {
9694   unsigned short i, temp, getdata;
9695 
9696   getdata = 0;
9697   for(i = 0; i < 8; i++) {
9698     getdata <<= 1;
9699     SiS_SetSCLKLow(SiS_Pr);
9700     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9701 		    SiS_Pr->SiS_DDC_Index,
9702 		    SiS_Pr->SiS_DDC_NData,
9703 		    SiS_Pr->SiS_DDC_Data);
9704     SiS_SetSCLKHigh(SiS_Pr);
9705     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9706     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9707   }
9708   return getdata;
9709 }
9710 
9711 static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9712 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9713 {
9714   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9715 		  SiS_Pr->SiS_DDC_Index,
9716 		  SiS_Pr->SiS_DDC_NClk,
9717 		  0x00);					/* SetSCLKLow()  */
9718   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9719   return 0;
9720 }
9721 
9722 static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9723 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9724 {
9725   unsigned short temp, watchdog=1000;
9726 
9727   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9728 		  SiS_Pr->SiS_DDC_Index,
9729 		  SiS_Pr->SiS_DDC_NClk,
9730 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9731   do {
9732     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9733   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9734   if (!watchdog) {
9735   	return 0xFFFF;
9736   }
9737   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9738   return 0;
9739 }
9740 
9741 /* Check I2C acknowledge */
9742 /* Returns 0 if ack ok, non-0 if ack not ok */
9743 static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9744 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9745 {
9746   unsigned short tempah;
9747 
9748   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9749   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9750 		  SiS_Pr->SiS_DDC_Index,
9751 		  SiS_Pr->SiS_DDC_NData,
9752 		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9753   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9754   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9755   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9756   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9757   return 0;
9758 }
9759 
9760 /* End of I2C functions ----------------------- */
9761 
9762 
9763 /* =============== SiS 315/330 O.E.M. ================= */
9764 
9765 #ifdef CONFIG_FB_SIS_315
9766 
9767 static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9768 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9769 {
9770   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9771   unsigned short romptr;
9772 
9773   if(SiS_Pr->ChipType < SIS_330) {
9774      romptr = SISGETROMW(0x128);
9775      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9776         romptr = SISGETROMW(0x12a);
9777   } else {
9778      romptr = SISGETROMW(0x1a8);
9779      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9780         romptr = SISGETROMW(0x1aa);
9781   }
9782   return romptr;
9783 }
9784 
9785 static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9786 GetLCDromptr(struct SiS_Private *SiS_Pr)
9787 {
9788   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9789   unsigned short romptr;
9790 
9791   if(SiS_Pr->ChipType < SIS_330) {
9792      romptr = SISGETROMW(0x120);
9793      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9794         romptr = SISGETROMW(0x122);
9795   } else {
9796      romptr = SISGETROMW(0x1a0);
9797      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9798         romptr = SISGETROMW(0x1a2);
9799   }
9800   return romptr;
9801 }
9802 
9803 static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9804 GetTVromptr(struct SiS_Private *SiS_Pr)
9805 {
9806   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9807   unsigned short romptr;
9808 
9809   if(SiS_Pr->ChipType < SIS_330) {
9810      romptr = SISGETROMW(0x114);
9811      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9812         romptr = SISGETROMW(0x11a);
9813   } else {
9814      romptr = SISGETROMW(0x194);
9815      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9816         romptr = SISGETROMW(0x19a);
9817   }
9818   return romptr;
9819 }
9820 
9821 static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9822 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9823 {
9824   unsigned short index;
9825 
9826   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9827      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9828         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9829 	   index >>= 4;
9830 	   index *= 3;
9831 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9832            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9833            return index;
9834 	}
9835      }
9836   }
9837 
9838   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9839   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9840   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9841      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9842      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9843   } else {
9844      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9845   }
9846   index--;
9847   index *= 3;
9848   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9849   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9850   return index;
9851 }
9852 
9853 static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9854 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9855 {
9856   unsigned short index;
9857 
9858   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9859   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9860   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9861   return index;
9862 }
9863 
9864 static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9865 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9866 {
9867   unsigned short index;
9868 
9869   index = 0;
9870   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9871   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9872 
9873   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9874 
9875   index <<= 1;
9876 
9877   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9878      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9879      index++;
9880   }
9881 
9882   return index;
9883 }
9884 
9885 static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9886 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9887 {
9888    unsigned short index = 0, temp = 0;
9889 
9890    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9891    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9892    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9893    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9894    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9895       index = 4;
9896       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9897       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9898    }
9899 
9900    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9901       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9902          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9903 	 index += addme;
9904 	 temp++;
9905       }
9906       temp += 0x0100;
9907    }
9908    return (unsigned int)(index | (temp << 16));
9909 }
9910 
9911 static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9912 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9913 {
9914    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9915 }
9916 
9917 #if 0
9918 static unsigned int
9919 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9920 {
9921    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9922 }
9923 #endif
9924 
9925 static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9926 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9927 {
9928    int index = 0;
9929 
9930    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9931    if(SiS_Pr->SiS_ROMNew) {
9932       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9933       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9934       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9935       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9936    } else {
9937       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9938       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9939       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9940       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9941    }
9942 
9943    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9944 
9945    return index;
9946 }
9947 
9948 static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9949 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9950 {
9951   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9952   unsigned short delay=0,index,myindex,temp,romptr=0;
9953   bool dochiptest = true;
9954 
9955   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9956      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9957   } else {
9958      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9959   }
9960 
9961   /* Find delay (from ROM, internal tables, PCI subsystem) */
9962 
9963   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9964 
9965      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9966         romptr = GetRAMDACromptr(SiS_Pr);
9967      }
9968      if(romptr) delay = ROMAddr[romptr];
9969      else {
9970         delay = 0x04;
9971         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9972 	   if(IS_SIS650) {
9973 	      delay = 0x0a;
9974 	   } else if(IS_SIS740) {
9975 	      delay = 0x00;
9976 	   } else {
9977 	      delay = 0x0c;
9978 	   }
9979 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9980            delay = 0x00;
9981 	}
9982      }
9983 
9984   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9985 
9986      bool gotitfrompci = false;
9987 
9988      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9989 
9990      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9991 	if(SiS_Pr->PDC != -1) {
9992            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9993 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9994 	   return;
9995 	}
9996      } else {
9997 	if(SiS_Pr->PDCA != -1) {
9998 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9999 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10000 	   return;
10001 	}
10002      }
10003 
10004      /* Custom Panel? */
10005 
10006      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10007         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10008 	   delay = 0x00;
10009 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10010 	      delay = 0x20;
10011 	   }
10012 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10013 	} else {
10014 	   delay = 0x0c;
10015 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10016 	      delay = 0x03;
10017 	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10018 	         delay = 0x00;
10019 	      }
10020 	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10021 	      if(IS_SIS740) delay = 0x01;
10022 	      else          delay = 0x03;
10023 	   }
10024 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10025 	}
10026         return;
10027      }
10028 
10029      /* This is a piece of typical SiS crap: They code the OEM LCD
10030       * delay into the code, at no defined place in the BIOS.
10031       * We now have to start doing a PCI subsystem check here.
10032       */
10033 
10034      switch(SiS_Pr->SiS_CustomT) {
10035      case CUT_COMPAQ1280:
10036      case CUT_COMPAQ12802:
10037 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10038 	   gotitfrompci = true;
10039 	   dochiptest = false;
10040 	   delay = 0x03;
10041 	}
10042 	break;
10043      case CUT_CLEVO1400:
10044      case CUT_CLEVO14002:
10045 	gotitfrompci = true;
10046 	dochiptest = false;
10047 	delay = 0x02;
10048 	break;
10049      case CUT_CLEVO1024:
10050      case CUT_CLEVO10242:
10051         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10052 	   gotitfrompci = true;
10053 	   dochiptest = false;
10054 	   delay = 0x33;
10055 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10056 	   delay &= 0x0f;
10057 	}
10058 	break;
10059      }
10060 
10061      /* Could we find it through the PCI ID? If no, use ROM or table */
10062 
10063      if(!gotitfrompci) {
10064 
10065         index = GetLCDPtrIndexBIOS(SiS_Pr);
10066         myindex = GetLCDPtrIndex(SiS_Pr);
10067 
10068         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10069 
10070            if(SiS_IsNotM650orLater(SiS_Pr)) {
10071 
10072               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10073 	         /* Always use the second pointer on 650; some BIOSes */
10074                  /* still carry old 301 data at the first location    */
10075 	         /* romptr = SISGETROMW(0x120);                       */
10076 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10077 	         romptr = SISGETROMW(0x122);
10078 	         if(!romptr) return;
10079 	         delay = ROMAddr[(romptr + index)];
10080 	      } else {
10081                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10082 	      }
10083 
10084           } else {
10085 
10086              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10087 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10088 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10089 
10090           }
10091 
10092         } else if(SiS_Pr->SiS_UseROM 			      &&
10093 		  (!(SiS_Pr->SiS_ROMNew))		      &&
10094 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10095 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10096 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
10097 		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
10098 		  ((romptr = GetLCDromptr(SiS_Pr)))) {
10099 
10100 	   /* Data for 1280x1024 wrong in 301B BIOS */
10101 	   /* Data for 1600x1200 wrong in 301C BIOS */
10102 	   delay = ROMAddr[(romptr + index)];
10103 
10104         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10105 
10106 	   if(IS_SIS740) delay = 0x03;
10107 	   else          delay = 0x00;
10108 
10109 	} else {
10110 
10111            delay = SiS310_LCDDelayCompensation_301[myindex];
10112 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10113 	      if(IS_SIS740) delay = 0x01;
10114 	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10115 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10116 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10117 	      if(IS_SIS740) delay = 0x01;  /* ? */
10118 	      else          delay = 0x03;
10119 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10120 	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10121 	      if(IS_SIS740) delay = 0x01;
10122 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10123 	   }
10124 
10125         }
10126 
10127      }  /* got it from PCI */
10128 
10129      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10130 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10131 	dochiptest = false;
10132      }
10133 
10134   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
10135 
10136      index = GetTVPtrIndex(SiS_Pr);
10137 
10138      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10139 
10140         if(SiS_IsNotM650orLater(SiS_Pr)) {
10141 
10142            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10143 	      /* Always use the second pointer on 650; some BIOSes */
10144               /* still carry old 301 data at the first location    */
10145               /* romptr = SISGETROMW(0x114);			   */
10146 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10147 	      romptr = SISGETROMW(0x11a);
10148 	      if(!romptr) return;
10149 	      delay = ROMAddr[romptr + index];
10150 
10151 	   } else {
10152 
10153 	      delay = SiS310_TVDelayCompensation_301B[index];
10154 
10155 	   }
10156 
10157         } else {
10158 
10159            switch(SiS_Pr->SiS_CustomT) {
10160 	   case CUT_COMPAQ1280:
10161 	   case CUT_COMPAQ12802:
10162 	   case CUT_CLEVO1400:
10163 	   case CUT_CLEVO14002:
10164 	      delay = 0x02;
10165 	      dochiptest = false;
10166 	      break;
10167 	   case CUT_CLEVO1024:
10168 	   case CUT_CLEVO10242:
10169 	      delay = 0x03;
10170 	      dochiptest = false;
10171    	      break;
10172 	   default:
10173               delay = SiS310_TVDelayCompensation_651301LV[index];
10174 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10175 	         delay = SiS310_TVDelayCompensation_651302LV[index];
10176 	      }
10177 	   }
10178         }
10179 
10180      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10181 
10182         romptr = GetTVromptr(SiS_Pr);
10183 	if(!romptr) return;
10184 	delay = ROMAddr[romptr + index];
10185 
10186      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10187 
10188         delay = SiS310_TVDelayCompensation_LVDS[index];
10189 
10190      } else {
10191 
10192 	delay = SiS310_TVDelayCompensation_301[index];
10193         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10194 	   if(IS_SIS740) {
10195 	      delay = SiS310_TVDelayCompensation_740301B[index];
10196 	      /* LV: use 301 data? BIOS bug? */
10197 	   } else {
10198               delay = SiS310_TVDelayCompensation_301B[index];
10199 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10200 	   }
10201 	}
10202 
10203      }
10204 
10205      if(SiS_LCDAEnabled(SiS_Pr)) {
10206 	delay &= 0x0f;
10207 	dochiptest = false;
10208      }
10209 
10210   } else return;
10211 
10212   /* Write delay */
10213 
10214   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10215 
10216      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10217 
10218         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10219         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
10220 	   delay &= 0x0f;
10221 	   delay |= 0xb0;
10222         } else if(temp == 6) {
10223            delay &= 0x0f;
10224 	   delay |= 0xc0;
10225         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
10226 	   delay = 0x35;
10227         }
10228         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10229 
10230      } else {
10231 
10232         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10233 
10234      }
10235 
10236   } else {  /* LVDS */
10237 
10238      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10239         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10240      } else {
10241         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10242            delay <<= 4;
10243            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10244         } else {
10245            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10246         }
10247      }
10248 
10249   }
10250 
10251 }
10252 
10253 static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10254 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10255 {
10256   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10257   unsigned short index,temp,temp1,romptr=0;
10258 
10259   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10260 
10261   if(ModeNo<=0x13)
10262      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10263   else
10264      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10265 
10266   temp = GetTVPtrIndex(SiS_Pr);
10267   temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10268   temp1 = temp;
10269 
10270   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10271      if(SiS_Pr->ChipType >= SIS_661) {
10272         temp1 = GetOEMTVPtr661(SiS_Pr);
10273         temp1 >>= 1;
10274         romptr = SISGETROMW(0x260);
10275         if(SiS_Pr->ChipType >= SIS_760) {
10276 	   romptr = SISGETROMW(0x360);
10277 	}
10278      } else if(SiS_Pr->ChipType >= SIS_330) {
10279         romptr = SISGETROMW(0x192);
10280      } else {
10281         romptr = SISGETROMW(0x112);
10282      }
10283   }
10284 
10285   if(romptr) {
10286      temp1 <<= 1;
10287      temp = ROMAddr[romptr + temp1 + index];
10288   } else {
10289      temp = SiS310_TVAntiFlick1[temp][index];
10290   }
10291   temp <<= 4;
10292 
10293   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10294 }
10295 
10296 static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10297 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10298 {
10299   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10300   unsigned short index,temp,temp1,romptr=0;
10301 
10302   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10303 
10304   if(ModeNo <= 0x13)
10305      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10306   else
10307      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10308 
10309   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10310      if(SiS_Pr->ChipType >= SIS_661) {
10311         romptr = SISGETROMW(0x26c);
10312         if(SiS_Pr->ChipType >= SIS_760) {
10313 	   romptr = SISGETROMW(0x36c);
10314 	}
10315 	temp1 = GetOEMTVPtr661(SiS_Pr);
10316         temp1 >>= 1;
10317      } else if(SiS_Pr->ChipType >= SIS_330) {
10318         romptr = SISGETROMW(0x1a4);
10319      } else {
10320         romptr = SISGETROMW(0x124);
10321      }
10322   }
10323 
10324   if(romptr) {
10325      temp1 <<= 1;
10326      temp = ROMAddr[romptr + temp1 + index];
10327   } else {
10328      temp = SiS310_TVEdge1[temp][index];
10329   }
10330   temp <<= 5;
10331   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10332 }
10333 
10334 static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10335 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10336 {
10337   unsigned short index, temp, i, j;
10338 
10339   if(ModeNo <= 0x13) {
10340      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10341   } else {
10342      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10343   }
10344 
10345   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10346 
10347   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10348   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10349   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10350   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10351 
10352   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10353      for(i=0x35, j=0; i<=0x38; i++, j++) {
10354         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10355      }
10356      for(i=0x48; i<=0x4A; i++, j++) {
10357         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10358      }
10359   } else {
10360      for(i=0x35, j=0; i<=0x38; i++, j++) {
10361         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10362      }
10363   }
10364 }
10365 
10366 static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10367 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10368 {
10369   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10370   unsigned short index,temp,i,j,resinfo,romptr=0;
10371   unsigned int  lindex;
10372 
10373   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10374 
10375   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10376   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10377 
10378   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10379      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10380      lindex <<= 2;
10381      for(j=0, i=0x31; i<=0x34; i++, j++) {
10382         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10383      }
10384      return;
10385   }
10386 
10387   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10388   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10389 
10390   if(ModeNo<=0x13) {
10391      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10392   } else {
10393      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10394   }
10395 
10396   temp = GetTVPtrIndex(SiS_Pr);
10397   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10398    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10399    */
10400   if(SiS_Pr->SiS_UseROM) {
10401      romptr = SISGETROMW(0x116);
10402      if(SiS_Pr->ChipType >= SIS_330) {
10403         romptr = SISGETROMW(0x196);
10404      }
10405      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10406         romptr = SISGETROMW(0x11c);
10407 	if(SiS_Pr->ChipType >= SIS_330) {
10408 	   romptr = SISGETROMW(0x19c);
10409 	}
10410 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10411 	   romptr = SISGETROMW(0x116);
10412 	   if(SiS_Pr->ChipType >= SIS_330) {
10413               romptr = SISGETROMW(0x196);
10414            }
10415 	}
10416      }
10417   }
10418   if(romptr) {
10419      romptr += (temp << 2);
10420      for(j=0, i=0x31; i<=0x34; i++, j++) {
10421         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10422      }
10423   } else {
10424      index = temp % 2;
10425      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10426      for(j=0, i=0x31; i<=0x34; i++, j++) {
10427         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10428 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10429         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10430            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10431         else
10432            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10433      }
10434   }
10435 
10436   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10437      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10438         if((resinfo == SIS_RI_640x480) ||
10439 	   (resinfo == SIS_RI_800x600)) {
10440 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10441 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10442 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10443 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10444 	} else if(resinfo == SIS_RI_1024x768) {
10445 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10446 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10447 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10448 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10449 	}
10450      }
10451   }
10452 }
10453 
10454 static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10455 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10456                 unsigned short ModeIdIndex, unsigned short RTI)
10457 {
10458    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10459    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10460 
10461    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10462       return;
10463 
10464    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10465    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10466 
10467    if(SiS_Pr->SiS_ROMNew) {
10468       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10469          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10470 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10471          index = 25;
10472          if(SiS_Pr->UseCustomMode) {
10473 	    index = SiS_Pr->CSRClock;
10474          } else if(ModeNo > 0x13) {
10475             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10476             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10477          }
10478 	 if(index < 25) index = 25;
10479          index = ((index / 25) - 1) << 1;
10480          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10481 	    index++;
10482 	 }
10483 	 romptr = SISGETROMW(0x104);
10484          delay = ROMAddr[romptr + index];
10485          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10486             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10487             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10488          } else {
10489             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10490 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10491          }
10492          return;
10493       }
10494    }
10495 
10496    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10497 
10498    if(SiS_Pr->UseCustomMode) delay = 0x04;
10499    else if(ModeNo <= 0x13)   delay = 0x04;
10500    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10501    delay |= (delay << 8);
10502 
10503    if(SiS_Pr->ChipType >= XGI_20) {
10504 
10505       delay = 0x0606;
10506       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10507 
10508 	 delay = 0x0404;
10509          if(SiS_Pr->SiS_XGIROM) {
10510 	     index = GetTVPtrIndex(SiS_Pr);
10511 	     if((romptr = SISGETROMW(0x35e))) {
10512 	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10513 		delay |= (delay << 8);
10514 	     }
10515 	 }
10516 
10517 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10518 	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10519 	       delay -= 0x0404;
10520 	    }
10521 	 }
10522       }
10523 
10524    } else if(SiS_Pr->ChipType >= SIS_340) {
10525 
10526       delay = 0x0606;
10527       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10528          delay = 0x0404;
10529       }
10530       /* TODO (eventually) */
10531 
10532    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10533 
10534       /* 3. TV */
10535 
10536       index = GetOEMTVPtr661(SiS_Pr);
10537       if(SiS_Pr->SiS_ROMNew) {
10538          romptr = SISGETROMW(0x106);
10539 	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10540          delay = ROMAddr[romptr + index];
10541       } else {
10542          delay = 0x04;
10543 	 if(index > 3) delay = 0;
10544       }
10545 
10546    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10547 
10548       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10549 
10550       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10551           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10552 
10553 	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10554 
10555 	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10556 	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10557 	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10558 
10559       } else {
10560 
10561          /* TMDS: Set our own, since BIOS has no idea */
10562 	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10563          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10564 	    switch(SiS_Pr->SiS_LCDResInfo) {
10565 	    case Panel_1024x768:  delay = 0x0008; break;
10566 	    case Panel_1280x720:  delay = 0x0004; break;
10567 	    case Panel_1280x768:
10568 	    case Panel_1280x768_2:delay = 0x0004; break;
10569 	    case Panel_1280x800:
10570 	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10571 	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10572 	    case Panel_1280x1024: delay = 0x1e04; break;
10573 	    case Panel_1400x1050: delay = 0x0004; break;
10574 	    case Panel_1600x1200: delay = 0x0400; break;
10575 	    case Panel_1680x1050: delay = 0x0e04; break;
10576 	    default:
10577                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10578 	          delay = 0x0008;
10579 	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10580 	          delay = 0x1e04;
10581                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10582 	          delay = 0x0004;
10583 	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10584 	          delay = 0x0400;
10585                } else
10586 	          delay = 0x0e04;
10587 	       break;
10588 	    }
10589          }
10590 
10591 	 /* Override by detected or user-set values */
10592 	 /* (but only if, for some reason, we can't read value from BIOS) */
10593          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10594             delay = SiS_Pr->PDC & 0x1f;
10595          }
10596          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10597             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10598          }
10599 
10600       }
10601 
10602    }
10603 
10604    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10605       delay >>= 8;
10606       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10607       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10608    } else {
10609       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10610       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10611    }
10612 }
10613 
10614 static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10615 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10616 {
10617    unsigned short infoflag;
10618    unsigned char  temp;
10619 
10620    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10621 
10622       if(ModeNo <= 0x13) {
10623          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10624       } else if(SiS_Pr->UseCustomMode) {
10625          infoflag = SiS_Pr->CInfoFlag;
10626       } else {
10627          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10628       }
10629 
10630       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10631          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10632       }
10633 
10634       infoflag &= 0xc0;
10635 
10636       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10637          temp = (infoflag >> 6) | 0x0c;
10638          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10639 	    temp ^= 0x04;
10640 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10641 	 }
10642          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10643       } else {
10644          temp = 0x30;
10645          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10646          temp |= infoflag;
10647          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10648          temp = 0;
10649          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10650 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10651 	 }
10652          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10653       }
10654 
10655    }
10656 }
10657 
10658 static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10659 SetPanelParms661(struct SiS_Private *SiS_Pr)
10660 {
10661    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10662    unsigned short romptr, temp1, temp2;
10663 
10664    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10665       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10666    }
10667 
10668    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10669       if(SiS_Pr->LVDSHL != -1) {
10670          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10671       }
10672    }
10673 
10674    if(SiS_Pr->SiS_ROMNew) {
10675 
10676       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10677          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10678             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10679 	    temp2 = 0xfc;
10680 	    if(SiS_Pr->LVDSHL != -1) {
10681 	      temp1 &= 0xfc;
10682 	      temp2 = 0xf3;
10683 	    }
10684 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10685          }
10686 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10687             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10688             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10689 	 }
10690       }
10691 
10692    }
10693 }
10694 
10695 static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10696 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10697 {
10698    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10699       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10700       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10701          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10702          SetPanelParms661(SiS_Pr);
10703       }
10704    } else {
10705       SetDelayComp(SiS_Pr,ModeNo);
10706    }
10707 
10708    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10709       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10710       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10711       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10712       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10713          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10714       }
10715    }
10716 }
10717 
10718 static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10719 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10720 			unsigned short ModeIdIndex, unsigned short RRTI)
10721 {
10722    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10723 
10724       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10725 
10726       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10727          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10728          SetPanelParms661(SiS_Pr);
10729       }
10730 
10731       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10732          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10733          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10734          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10735          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10736             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10737          }
10738       }
10739    }
10740 }
10741 
10742 /* FinalizeLCD
10743  * This finalizes some CRT2 registers for the very panel used.
10744  * If we have a backup if these registers, we use it; otherwise
10745  * we set the register according to most BIOSes. However, this
10746  * function looks quite different in every BIOS, so you better
10747  * pray that we have a backup...
10748  */
10749 static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10750 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10751 {
10752   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10753   unsigned short resinfo,modeflag;
10754 
10755   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10756   if(SiS_Pr->SiS_ROMNew) return;
10757 
10758   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10759      if(SiS_Pr->LVDSHL != -1) {
10760         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10761      }
10762   }
10763 
10764   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10765   if(SiS_Pr->UseCustomMode) return;
10766 
10767   switch(SiS_Pr->SiS_CustomT) {
10768   case CUT_COMPAQ1280:
10769   case CUT_COMPAQ12802:
10770   case CUT_CLEVO1400:
10771   case CUT_CLEVO14002:
10772      return;
10773   }
10774 
10775   if(ModeNo <= 0x13) {
10776      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10777      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10778   } else {
10779      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10780      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10781   }
10782 
10783   if(IS_SIS650) {
10784      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10785         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10786 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10787 	} else {
10788            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10789 	}
10790      }
10791   }
10792 
10793   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10794      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10795         /* Maybe all panels? */
10796         if(SiS_Pr->LVDSHL == -1) {
10797            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10798 	}
10799 	return;
10800      }
10801   }
10802 
10803   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10804      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10805         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10806 	   if(SiS_Pr->LVDSHL == -1) {
10807 	      /* Maybe all panels? */
10808               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10809 	   }
10810 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10811 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10812 	      if(tempch == 3) {
10813 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10814 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10815 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10816 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10817 	      }
10818 	   }
10819 	   return;
10820 	}
10821      }
10822   }
10823 
10824   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10825      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10826 	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10827 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10828 #ifdef SET_EMI
10829 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10830 #endif
10831 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10832 	}
10833      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10834         if(SiS_Pr->LVDSHL == -1) {
10835            /* Maybe ACER only? */
10836            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10837 	}
10838      }
10839      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10840      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10841 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10842 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10843 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10844 	   if(tempch == 0x03) {
10845 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10846 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10847 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10848 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10849 	   }
10850 	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10851 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10852 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10853 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10854 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10855 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10856 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10857 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10858 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10859 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10860 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10861 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10862 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10863 	      if(ModeNo <= 0x13) {
10864 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10865 		 if((resinfo == 0) || (resinfo == 2)) return;
10866 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10867 		 if((resinfo == 1) || (resinfo == 3)) return;
10868 	      }
10869 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10870 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10871 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10872 #if 0
10873 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10874 		 tempbx--;
10875 		 temp = tempbx & 0xff;
10876 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10877 		 temp = (tempbx >> 8) & 0x03;
10878 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10879 #endif
10880 	      }
10881 	   } else if(ModeNo <= 0x13) {
10882 	      if(ModeNo <= 1) {
10883 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10884 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10885 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10886 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10887 	      }
10888 	      if(!(modeflag & HalfDCLK)) {
10889 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10890 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10891 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10892 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10893 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10894 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10895 		 if(ModeNo == 0x12) {
10896 		    switch(tempch) {
10897 		       case 0:
10898 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10899 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10900 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10901 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10902 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10903 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10904 			  break;
10905 		       case 2:
10906 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10907 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10908 			  break;
10909 		       case 3:
10910 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10911 			  break;
10912 		    }
10913 		 }
10914 	      }
10915 	   }
10916 	}
10917      } else {
10918         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10919 	tempcl &= 0x0f;
10920 	tempbh &= 0x70;
10921 	tempbh >>= 4;
10922 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10923 	tempbx = (tempbh << 8) | tempbl;
10924 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10925 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10926 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10927 	      	 tempbx = 770;
10928 	      } else {
10929 	         if(tempbx > 770) tempbx = 770;
10930 		 if(SiS_Pr->SiS_VGAVDE < 600) {
10931 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10932 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10933 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10934 		    tempbx -= tempax;
10935 		 }
10936 	      }
10937 	   } else return;
10938 	}
10939 	temp = tempbx & 0xff;
10940 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10941 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10942 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10943      }
10944   }
10945 }
10946 
10947 #endif
10948 
10949 /*  =================  SiS 300 O.E.M. ================== */
10950 
10951 #ifdef CONFIG_FB_SIS_300
10952 
10953 static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10954 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10955 		unsigned short RefTabIndex)
10956 {
10957   unsigned short crt2crtc=0, modeflag, myindex=0;
10958   unsigned char  temp;
10959   int i;
10960 
10961   if(ModeNo <= 0x13) {
10962      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10963      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10964   } else {
10965      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10966      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10967   }
10968 
10969   crt2crtc &= 0x3f;
10970 
10971   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10972      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10973   }
10974 
10975   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10976      if(modeflag & HalfDCLK) myindex = 1;
10977 
10978      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10979         for(i=0; i<7; i++) {
10980            if(barco_p1[myindex][crt2crtc][i][0]) {
10981 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10982 	                      barco_p1[myindex][crt2crtc][i][0],
10983 	   	   	      barco_p1[myindex][crt2crtc][i][2],
10984 			      barco_p1[myindex][crt2crtc][i][1]);
10985 	   }
10986         }
10987      }
10988      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10989      if(temp & 0x80) {
10990         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10991         temp++;
10992         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10993      }
10994   }
10995 }
10996 
10997 static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10998 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10999 {
11000   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11001   unsigned short tempbx=0,romptr=0;
11002   static const unsigned char customtable300[] = {
11003 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11004 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11005   };
11006   static const unsigned char customtable630[] = {
11007 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11008 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11009   };
11010 
11011   if(SiS_Pr->ChipType == SIS_300) {
11012 
11013     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11014     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11015     tempbx -= 2;
11016     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11017     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11018        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11019     }
11020     if(SiS_Pr->SiS_UseROM) {
11021        if(ROMAddr[0x235] & 0x80) {
11022           tempbx = SiS_Pr->SiS_LCDTypeInfo;
11023           if(Flag) {
11024 	     romptr = SISGETROMW(0x255);
11025 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11026 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11027              if(tempbx == 0xFF) return 0xFFFF;
11028           }
11029 	  tempbx <<= 1;
11030 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11031        }
11032     }
11033 
11034   } else {
11035 
11036     if(Flag) {
11037        if(SiS_Pr->SiS_UseROM) {
11038           romptr = SISGETROMW(0x255);
11039 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11040 	  else 	     tempbx = 0xff;
11041        } else {
11042           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11043        }
11044        if(tempbx == 0xFF) return 0xFFFF;
11045        tempbx <<= 2;
11046        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11047        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11048        return tempbx;
11049     }
11050     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11051     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11052     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11053 
11054   }
11055 
11056   return tempbx;
11057 }
11058 
11059 static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11060 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11061 {
11062   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11063   unsigned short index,temp,romptr=0;
11064 
11065   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11066 
11067   if(SiS_Pr->SiS_UseROM) {
11068      if(!(ROMAddr[0x237] & 0x01)) return;
11069      if(!(ROMAddr[0x237] & 0x02)) return;
11070      romptr = SISGETROMW(0x24b);
11071   }
11072 
11073   /* The Panel Compensation Delay should be set according to tables
11074    * here. Unfortunately, various BIOS versions don't care about
11075    * a uniform way using eg. ROM byte 0x220, but use different
11076    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11077    * Thus we don't set this if the user selected a custom pdc or if
11078    * we otherwise detected a valid pdc.
11079    */
11080   if(SiS_Pr->PDC != -1) return;
11081 
11082   temp = GetOEMLCDPtr(SiS_Pr, 0);
11083 
11084   if(SiS_Pr->UseCustomMode)
11085      index = 0;
11086   else
11087      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11088 
11089   if(SiS_Pr->ChipType != SIS_300) {
11090      if(romptr) {
11091 	romptr += (temp * 2);
11092 	romptr = SISGETROMW(romptr);
11093 	romptr += index;
11094 	temp = ROMAddr[romptr];
11095      } else {
11096 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
11097     	   temp = SiS300_OEMLCDDelay2[temp][index];
11098 	} else {
11099            temp = SiS300_OEMLCDDelay3[temp][index];
11100         }
11101      }
11102   } else {
11103      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11104 	if(romptr) {
11105 	   romptr += (temp * 2);
11106 	   romptr = SISGETROMW(romptr);
11107 	   romptr += index;
11108 	   temp = ROMAddr[romptr];
11109 	} else {
11110 	   temp = SiS300_OEMLCDDelay5[temp][index];
11111 	}
11112      } else {
11113         if(SiS_Pr->SiS_UseROM) {
11114 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11115 	   if(romptr) {
11116 	      romptr += (temp * 2);
11117 	      romptr = SISGETROMW(romptr);
11118 	      romptr += index;
11119 	      temp = ROMAddr[romptr];
11120 	   } else {
11121 	      temp = SiS300_OEMLCDDelay4[temp][index];
11122 	   }
11123 	} else {
11124 	   temp = SiS300_OEMLCDDelay4[temp][index];
11125 	}
11126      }
11127   }
11128   temp &= 0x3c;
11129   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11130 }
11131 
11132 static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11133 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11134 {
11135 #if 0  /* Unfinished; Data table missing */
11136   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11137   unsigned short index,temp;
11138 
11139   if((SiS_Pr->SiS_UseROM) {
11140      if(!(ROMAddr[0x237] & 0x01)) return;
11141      if(!(ROMAddr[0x237] & 0x04)) return;
11142      /* No rom pointer in BIOS header! */
11143   }
11144 
11145   temp = GetOEMLCDPtr(SiS_Pr, 1);
11146   if(temp == 0xFFFF) return;
11147 
11148   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11149   for(i=0x14, j=0; i<=0x17; i++, j++) {
11150       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11151   }
11152   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11153 
11154   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11155   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11156   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11157   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11158   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11159       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11160   }
11161 #endif
11162 }
11163 
11164 static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)11165 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11166 {
11167   unsigned short index;
11168 
11169   index = 0;
11170   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11171   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11172      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11173      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11174      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11175   } else {
11176      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11177      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11178   }
11179   return index;
11180 }
11181 
11182 static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11183 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11184 {
11185   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11186   unsigned short index,temp,romptr=0;
11187 
11188   if(SiS_Pr->SiS_UseROM) {
11189      if(!(ROMAddr[0x238] & 0x01)) return;
11190      if(!(ROMAddr[0x238] & 0x02)) return;
11191      romptr = SISGETROMW(0x241);
11192   }
11193 
11194   temp = GetOEMTVPtr(SiS_Pr);
11195 
11196   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11197 
11198   if(romptr) {
11199      romptr += (temp * 2);
11200      romptr = SISGETROMW(romptr);
11201      romptr += index;
11202      temp = ROMAddr[romptr];
11203   } else {
11204      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11205         temp = SiS300_OEMTVDelay301[temp][index];
11206      } else {
11207         temp = SiS300_OEMTVDelayLVDS[temp][index];
11208      }
11209   }
11210   temp &= 0x3c;
11211   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11212 }
11213 
11214 static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11215 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11216 {
11217   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11218   unsigned short index,temp,romptr=0;
11219 
11220   if(SiS_Pr->SiS_UseROM) {
11221      if(!(ROMAddr[0x238] & 0x01)) return;
11222      if(!(ROMAddr[0x238] & 0x04)) return;
11223      romptr = SISGETROMW(0x243);
11224   }
11225 
11226   temp = GetOEMTVPtr(SiS_Pr);
11227 
11228   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11229 
11230   if(romptr) {
11231      romptr += (temp * 2);
11232      romptr = SISGETROMW(romptr);
11233      romptr += index;
11234      temp = ROMAddr[romptr];
11235   } else {
11236      temp = SiS300_OEMTVFlicker[temp][index];
11237   }
11238   temp &= 0x70;
11239   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11240 }
11241 
11242 static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11243 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11244 {
11245   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11246   unsigned short index,i,j,temp,romptr=0;
11247 
11248   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11249 
11250   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11251 
11252   if(SiS_Pr->SiS_UseROM) {
11253      if(!(ROMAddr[0x238] & 0x01)) return;
11254      if(!(ROMAddr[0x238] & 0x08)) return;
11255      romptr = SISGETROMW(0x245);
11256   }
11257 
11258   temp = GetOEMTVPtr(SiS_Pr);
11259 
11260   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11261 
11262   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11263      for(i=0x31, j=0; i<=0x34; i++, j++) {
11264         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11265      }
11266   } else {
11267      if(romptr) {
11268         romptr += (temp * 2);
11269 	romptr = SISGETROMW(romptr);
11270 	romptr += (index * 4);
11271         for(i=0x31, j=0; i<=0x34; i++, j++) {
11272 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11273 	}
11274      } else {
11275         for(i=0x31, j=0; i<=0x34; i++, j++) {
11276            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11277 	}
11278      }
11279   }
11280 }
11281 
11282 static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11283 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11284 {
11285   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11286   unsigned short index,temp,i,j,romptr=0;
11287 
11288   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11289 
11290   if(SiS_Pr->SiS_UseROM) {
11291      if(!(ROMAddr[0x238] & 0x01)) return;
11292      if(!(ROMAddr[0x238] & 0x10)) return;
11293      romptr = SISGETROMW(0x247);
11294   }
11295 
11296   temp = GetOEMTVPtr(SiS_Pr);
11297 
11298   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11299   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11300   /* NTSCJ uses NTSC filters */
11301 
11302   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11303 
11304   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11305       for(i=0x35, j=0; i<=0x38; i++, j++) {
11306        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11307       }
11308       for(i=0x48; i<=0x4A; i++, j++) {
11309      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11310       }
11311   } else {
11312       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11313          romptr += (temp * 2);
11314 	 romptr = SISGETROMW(romptr);
11315 	 romptr += (index * 4);
11316 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11317        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11318          }
11319       } else {
11320          for(i=0x35, j=0; i<=0x38; i++, j++) {
11321        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11322          }
11323       }
11324   }
11325 }
11326 
11327 static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11328 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11329 {
11330    unsigned short ModeIdIndex;
11331    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11332 
11333    if(*ModeNo <= 5) *ModeNo |= 1;
11334 
11335    for(ModeIdIndex=0; ; ModeIdIndex++) {
11336       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11337       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11338    }
11339 
11340    if(*ModeNo != 0x07) {
11341       if(*ModeNo > 0x03) return ModeIdIndex;
11342       if(VGAINFO & 0x80) return ModeIdIndex;
11343       ModeIdIndex++;
11344    }
11345 
11346    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11347 	                               /* else 350 lines */
11348    return ModeIdIndex;
11349 }
11350 
11351 static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11352 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11353 		  unsigned short RefTableIndex)
11354 {
11355   unsigned short OEMModeIdIndex = 0;
11356 
11357   if(!SiS_Pr->UseCustomMode) {
11358      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11359      if(!(OEMModeIdIndex)) return;
11360   }
11361 
11362   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11363      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11364      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11365         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11366      }
11367   }
11368   if(SiS_Pr->UseCustomMode) return;
11369   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11370      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11371      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11372         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11373     	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11374        	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11375      }
11376   }
11377 }
11378 #endif
11379 
11380