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