xref: /openbmc/linux/drivers/video/fbdev/sis/init301.c (revision 0edbfea5)
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         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 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6852               tempch = 25;
6853            } else {
6854 	      tempch = 25; /* OK */
6855 	   }
6856         }
6857      }
6858   }
6859 
6860   if(!(tempbx & 0x20)) {
6861      if(modeflag & HalfDCLK) tempcl <<= 1;
6862      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6863      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6864      tempax = longtemp / SiS_Pr->SiS_HDE;
6865      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6866      tempbx |= ((tempax >> 8) & 0x1F);
6867      tempcx = tempax >> 13;
6868   }
6869 
6870   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6871   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6872 
6873   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6874 
6875      tempcx &= 0x07;
6876      if(tempbx & 0x20) tempcx = 0;
6877      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6878 
6879      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6880         tempbx = 0x0382;
6881         tempcx = 0x007e;
6882      } else {
6883         tempbx = 0x0369;
6884         tempcx = 0x0061;
6885      }
6886      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6887      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6888      temp = (tempcx & 0x0300) >> 6;
6889      temp |= ((tempbx >> 8) & 0x03);
6890      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6891         temp |= 0x10;
6892 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
6893 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6894      }
6895      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6896 
6897      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6898      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6899 
6900      SiS_SetTVSpecial(SiS_Pr, ModeNo);
6901 
6902      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6903         temp = 0;
6904         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6905         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6906      }
6907 
6908   }
6909 
6910   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6911      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6912         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6913         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6914      }
6915      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6916   }
6917 
6918   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6919      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6920         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6921      }
6922   }
6923 
6924   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6925 
6926   /* From here: Part2 LCD setup */
6927 
6928   tempbx = SiS_Pr->SiS_HDE;
6929   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6930   tempbx--;			         	/* RHACTE = HDE - 1 */
6931   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6932   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6933 
6934   temp = 0x01;
6935   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6936      if(SiS_Pr->SiS_ModeType == ModeEGA) {
6937         if(SiS_Pr->SiS_VGAHDE >= 1024) {
6938            temp = 0x02;
6939            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6940               temp = 0x01;
6941 	   }
6942         }
6943      }
6944   }
6945   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6946 
6947   tempbx = SiS_Pr->SiS_VDE - 1;
6948   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6949   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6950 
6951   tempcx = SiS_Pr->SiS_VT - 1;
6952   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6953   temp = (tempcx >> 3) & 0xE0;
6954   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6955      /* Enable dithering; only do this for 32bpp mode */
6956      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6957         temp |= 0x10;
6958      }
6959   }
6960   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6961 
6962   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6963   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6964 
6965   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6966   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6967 
6968 #ifdef CONFIG_FB_SIS_315
6969   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6970                           			&CRT2Index, &resindex)) {
6971       switch(CRT2Index) {
6972         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
6973 	default:
6974         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
6975       }
6976 
6977       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6978       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6979       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6980         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6981       }
6982       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6983         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6984       }
6985       for(j = 0x1f; j <= 0x21; i++, j++ ) {
6986         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6987       }
6988       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6989       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6990 
6991       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
6992 
6993   } else {
6994 #endif
6995 
6996     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
6997     /*             Clevo dual-link 1024x768 */
6998     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
6999     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7000 
7001     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7002        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7003           tempbx = SiS_Pr->SiS_VDE - 1;
7004           tempcx = SiS_Pr->SiS_VT - 1;
7005        } else {
7006           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7007 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7008        }
7009     } else {
7010        tempbx = SiS_Pr->PanelYRes;
7011        tempcx = SiS_Pr->SiS_VT;
7012        tempax = 1;
7013        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7014           tempax = SiS_Pr->PanelYRes;
7015 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7016           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7017              tempax = tempcx = 0;
7018           } else {
7019              tempax -= SiS_Pr->SiS_VDE;
7020           }
7021           tempax >>= 1;
7022        }
7023        tempcx -= tempax; /* lcdvdes */
7024        tempbx -= tempax; /* lcdvdee */
7025     }
7026 
7027     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7028 
7029     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7030     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7031 
7032     temp = (tempbx >> 5) & 0x38;
7033     temp |= ((tempcx >> 8) & 0x07);
7034     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7035 
7036     tempax = SiS_Pr->SiS_VDE;
7037     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7038        tempax = SiS_Pr->PanelYRes;
7039     }
7040     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7041     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7042        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7043 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7044        }
7045     }
7046 
7047     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7048     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7049        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7050           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7051              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7052 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7053 	     else           { tempax >>= 2;           }
7054              tempbx -= (tempax - 1);
7055 	  } else {
7056 	     tempbx -= 10;
7057 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7058 	  }
7059        }
7060     }
7061     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7062        tempbx++;
7063        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7064           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7065 	     tempbx = 770;
7066 	     tempcx = 3;
7067 	  }
7068        }
7069     }
7070 
7071     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7072 
7073     if(SiS_Pr->UseCustomMode) {
7074        tempbx = SiS_Pr->CVSyncStart;
7075     }
7076 
7077     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7078 
7079     temp = (tempbx >> 4) & 0xF0;
7080     tempbx += (tempcx + 1);
7081     temp |= (tempbx & 0x0F);
7082 
7083     if(SiS_Pr->UseCustomMode) {
7084        temp &= 0xf0;
7085        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7086     }
7087 
7088     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7089 
7090 #ifdef CONFIG_FB_SIS_300
7091     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7092 #endif
7093 
7094     bridgeoffset = 7;
7095     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7096     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7097     if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7098     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7099     /* Higher bridgeoffset shifts to the LEFT */
7100 
7101     temp = 0;
7102     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7103        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7104 	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7105 	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7106        }
7107     }
7108     temp += bridgeoffset;
7109     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7110     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7111 
7112     tempcx = SiS_Pr->SiS_HT;
7113     tempax = tempbx = SiS_Pr->SiS_HDE;
7114     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7115        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7116           tempax = SiS_Pr->PanelXRes;
7117           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7118        }
7119     }
7120     if(SiS_IsDualLink(SiS_Pr)) {
7121        tempcx >>= 1;
7122        tempbx >>= 1;
7123        tempax >>= 1;
7124     }
7125 
7126     tempbx += bridgeoffset;
7127 
7128     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7129     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7130 
7131     tempcx = (tempcx - tempax) >> 2;
7132 
7133     tempbx += tempcx;
7134     push2 = tempbx;
7135 
7136     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7137        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7138           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7139              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7140 	  }
7141        }
7142     }
7143 
7144     if(SiS_Pr->UseCustomMode) {
7145        tempbx = SiS_Pr->CHSyncStart;
7146        if(modeflag & HalfDCLK) tempbx <<= 1;
7147        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7148        tempbx += bridgeoffset;
7149     }
7150 
7151     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7152     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7153 
7154     tempbx = push2;
7155 
7156     tempcx <<= 1;
7157     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7158        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7159     }
7160     tempbx += tempcx;
7161 
7162     if(SiS_Pr->UseCustomMode) {
7163        tempbx = SiS_Pr->CHSyncEnd;
7164        if(modeflag & HalfDCLK) tempbx <<= 1;
7165        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7166        tempbx += bridgeoffset;
7167     }
7168 
7169     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7170 
7171     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7172 
7173 #ifdef CONFIG_FB_SIS_300
7174     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7175 #endif
7176 #ifdef CONFIG_FB_SIS_315
7177   } /* CRT2-LCD from table */
7178 #endif
7179 }
7180 
7181 /*********************************************/
7182 /*         SET PART 3 REGISTER GROUP         */
7183 /*********************************************/
7184 
7185 static void
7186 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7187 {
7188   unsigned short i;
7189   const unsigned char *tempdi;
7190 
7191   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7192 
7193 #ifndef SIS_CP
7194   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7195 #else
7196   SIS_CP_INIT301_CP
7197 #endif
7198 
7199   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7200      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7201      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7202   } else {
7203      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7204      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7205   }
7206 
7207   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7208      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7209      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7210      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7211   }
7212 
7213   tempdi = NULL;
7214   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7215      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7216      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7217         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7218      }
7219   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7220      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7221         tempdi = SiS_HiTVGroup3_1;
7222         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7223      }
7224   }
7225   if(tempdi) {
7226      for(i=0; i<=0x3E; i++) {
7227         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7228      }
7229      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7230 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7231 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7232 	}
7233      }
7234   }
7235 
7236 #ifdef SIS_CP
7237   SIS_CP_INIT301_CP2
7238 #endif
7239 }
7240 
7241 /*********************************************/
7242 /*         SET PART 4 REGISTER GROUP         */
7243 /*********************************************/
7244 
7245 #ifdef CONFIG_FB_SIS_315
7246 #if 0
7247 static void
7248 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7249 {
7250    unsigned short temp, temp1, temp2;
7251 
7252    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7253    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7254    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7255    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7256    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7257    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7258    temp = (unsigned short)((int)(temp) + shift);
7259    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7260    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7261    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7262    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7263    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7264    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7265 }
7266 #endif
7267 
7268 static void
7269 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7270 {
7271    unsigned short temp, temp1;
7272    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7273 
7274    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7275    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7276 
7277    if(SiS_Pr->ChipType >= XGI_20) return;
7278 
7279    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7280       if(!(ROMAddr[0x61] & 0x04)) return;
7281    }
7282 
7283    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7284    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7285    if(!(temp & 0x01)) {
7286       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7287       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7288       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7289          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7290       }
7291       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7292       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7293       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7294       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7295       else					   temp = 0x0402;
7296       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7297          temp1 = 0;
7298 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7299 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7300 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7301 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7302 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7303 	 if(ModeNo > 0x13) {
7304             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7305          }
7306       } else {
7307          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7308 	 if(temp1 == 0x01) temp |= 0x01;
7309 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7310 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7311 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7312 	 if(ModeNo > 0x13) {
7313             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7314          }
7315       }
7316 
7317 #if 0
7318       if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7319          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7320             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7321 	       if(resinfo == SIS_RI_1024x768) {
7322 	          SiS_ShiftXPos(SiS_Pr, 97);
7323 	       } else {
7324 	          SiS_ShiftXPos(SiS_Pr, 111);
7325 	       }
7326 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7327 	       SiS_ShiftXPos(SiS_Pr, 136);
7328 	    }
7329          }
7330       }
7331 #endif
7332 
7333    }
7334 
7335 }
7336 #endif
7337 
7338 static void
7339 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7340                  unsigned short RefreshRateTableIndex)
7341 {
7342   unsigned short vclkindex, temp, reg1, reg2;
7343 
7344   if(SiS_Pr->UseCustomMode) {
7345      reg1 = SiS_Pr->CSR2B;
7346      reg2 = SiS_Pr->CSR2C;
7347   } else {
7348      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7349      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7350      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7351   }
7352 
7353   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7354      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7355         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7356  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7357 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7358      } else {
7359         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7360         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7361      }
7362   } else {
7363      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7364      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7365      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7366   }
7367   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7368   temp = 0x08;
7369   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7370   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7371 }
7372 
7373 static void
7374 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7375 {
7376   if(SiS_Pr->ChipType >= SIS_315H) {
7377      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7378 	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7379 	   (SiS_IsVAMode(SiS_Pr))) {
7380 	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7381 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7382 	   } else {
7383 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7384 	   }
7385 	}
7386      }
7387   }
7388   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7389      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7390 #ifdef SET_EMI
7391      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7392 #endif
7393      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7394   }
7395 }
7396 
7397 static void
7398 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7399 		unsigned short RefreshRateTableIndex)
7400 {
7401   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7402   unsigned int   tempebx, tempeax, templong;
7403 
7404   if(ModeNo <= 0x13) {
7405      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7406      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7407   } else if(SiS_Pr->UseCustomMode) {
7408      modeflag = SiS_Pr->CModeFlag;
7409      resinfo = 0;
7410   } else {
7411      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7412      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7413   }
7414 
7415   if(SiS_Pr->ChipType >= SIS_315H) {
7416      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7417 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7418 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7419 	}
7420      }
7421   }
7422 
7423   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7424      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7425 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7426      }
7427   }
7428 
7429   if(SiS_Pr->ChipType >= SIS_315H) {
7430      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7431 	SiS_SetDualLinkEtc(SiS_Pr);
7432 	return;
7433      }
7434   }
7435 
7436   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7437 
7438   tempbx = SiS_Pr->SiS_RVBHCMAX;
7439   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7440 
7441   temp = (tempbx >> 1) & 0x80;
7442 
7443   tempcx = SiS_Pr->SiS_VGAHT - 1;
7444   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7445 
7446   temp |= ((tempcx >> 5) & 0x78);
7447 
7448   tempcx = SiS_Pr->SiS_VGAVT - 1;
7449   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7450   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7451 
7452   temp |= ((tempcx >> 8) & 0x07);
7453   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7454 
7455   tempbx = SiS_Pr->SiS_VGAHDE;
7456   if(modeflag & HalfDCLK)    tempbx >>= 1;
7457   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7458 
7459   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7460      temp = 0;
7461      if(tempbx > 800)        temp = 0x60;
7462   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7463      temp = 0;
7464      if(tempbx > 1024)       temp = 0xC0;
7465      else if(tempbx >= 960)  temp = 0xA0;
7466   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7467      temp = 0;
7468      if(tempbx >= 1280)      temp = 0x40;
7469      else if(tempbx >= 1024) temp = 0x20;
7470   } else {
7471      temp = 0x80;
7472      if(tempbx >= 1024)      temp = 0xA0;
7473   }
7474 
7475   temp |= SiS_Pr->Init_P4_0E;
7476 
7477   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7478      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7479         temp &= 0xf0;
7480         temp |= 0x0A;
7481      }
7482   }
7483 
7484   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7485 
7486   tempeax = SiS_Pr->SiS_VGAVDE;
7487   tempebx = SiS_Pr->SiS_VDE;
7488   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7489      if(!(temp & 0xE0)) tempebx >>=1;
7490   }
7491 
7492   tempcx = SiS_Pr->SiS_RVBHRS;
7493   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7494   tempcx >>= 8;
7495   tempcx |= 0x40;
7496 
7497   if(tempeax <= tempebx) {
7498      tempcx ^= 0x40;
7499   } else {
7500      tempeax -= tempebx;
7501   }
7502 
7503   tempeax *= (256 * 1024);
7504   templong = tempeax % tempebx;
7505   tempeax /= tempebx;
7506   if(templong) tempeax++;
7507 
7508   temp = (unsigned short)(tempeax & 0x000000FF);
7509   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7510   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7511   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7512   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7513   temp |= (tempcx & 0x4F);
7514   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7515 
7516   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7517 
7518      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7519 
7520      /* Calc Linebuffer max address and set/clear decimode */
7521      tempbx = 0;
7522      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7523      tempax = SiS_Pr->SiS_VGAHDE;
7524      if(modeflag & HalfDCLK)    tempax >>= 1;
7525      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7526      if(tempax > 800) {
7527         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7528 	   tempax -= 800;
7529 	} else {
7530 	   tempbx = 0x08;
7531 	   if(tempax == 960)	   tempax *= 25; /* Correct */
7532            else if(tempax == 1024) tempax *= 25;
7533            else			   tempax *= 20;
7534 	   temp = tempax % 32;
7535 	   tempax /= 32;
7536 	   if(temp) tempax++;
7537 	   tempax++;
7538 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7539 	      if(resinfo == SIS_RI_1024x768 ||
7540 	         resinfo == SIS_RI_1024x576 ||
7541 		 resinfo == SIS_RI_1280x1024 ||
7542 		 resinfo == SIS_RI_1280x720) {
7543 	         /* Otherwise white line or garbage at right edge */
7544 	         tempax = (tempax & 0xff00) | 0x20;
7545 	      }
7546 	   }
7547 	}
7548      }
7549      tempax--;
7550      temp = ((tempax >> 4) & 0x30) | tempbx;
7551      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7552      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7553 
7554      temp = 0x0036; tempbx = 0xD0;
7555      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7556 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7557      }
7558      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7559         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7560 	   temp |= 0x01;
7561 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7562 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7563   	         temp &= ~0x01;
7564 	      }
7565 	   }
7566 	}
7567      }
7568      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7569 
7570      tempbx = SiS_Pr->SiS_HT >> 1;
7571      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7572      tempbx -= 2;
7573      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7574      temp = (tempbx >> 5) & 0x38;
7575      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7576 
7577      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7578 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7579            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7580 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7581 	}
7582      }
7583 
7584      SiS_SetDualLinkEtc(SiS_Pr);
7585 
7586   }  /* 301B */
7587 
7588   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7589 }
7590 
7591 /*********************************************/
7592 /*         SET PART 5 REGISTER GROUP         */
7593 /*********************************************/
7594 
7595 static void
7596 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7597 {
7598 
7599   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7600 
7601   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7602      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7603         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7604         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7605      }
7606   }
7607 }
7608 
7609 /*********************************************/
7610 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7611 /*********************************************/
7612 
7613 static bool
7614 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7615 		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7616 		   unsigned short *DisplayType)
7617  {
7618   unsigned short modeflag = 0;
7619   bool checkhd = true;
7620 
7621   /* Pass 1:1 not supported here */
7622 
7623   if(ModeNo <= 0x13) {
7624      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7625      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7626   } else {
7627      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7628      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7629   }
7630 
7631   (*ResIndex) &= 0x3F;
7632 
7633   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7634 
7635      (*DisplayType) = 80;
7636      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7637       	(*DisplayType) = 82;
7638 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7639 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7640 	}
7641      }
7642      if((*DisplayType) != 84) {
7643         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7644      }
7645 
7646   } else {
7647 
7648      (*DisplayType = 0);
7649      switch(SiS_Pr->SiS_LCDResInfo) {
7650      case Panel_320x240_1: (*DisplayType) = 50;
7651 			   checkhd = false;
7652 			   break;
7653      case Panel_320x240_2: (*DisplayType) = 14;
7654 			   break;
7655      case Panel_320x240_3: (*DisplayType) = 18;
7656 			   break;
7657      case Panel_640x480:   (*DisplayType) = 10;
7658 			   break;
7659      case Panel_1024x600:  (*DisplayType) = 26;
7660 			   break;
7661      default: return true;
7662      }
7663 
7664      if(checkhd) {
7665         if(modeflag & HalfDCLK) (*DisplayType)++;
7666      }
7667 
7668      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7669         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7670      }
7671 
7672   }
7673 
7674   return true;
7675 }
7676 
7677 static void
7678 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7679                 unsigned short RefreshRateTableIndex)
7680 {
7681   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7682   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7683   static const unsigned short CRIdx[] = {
7684 	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7685 	0x07, 0x10, 0x11, 0x15, 0x16
7686   };
7687 
7688   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7689      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7690      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
7691      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7692      return;
7693 
7694   if(SiS_Pr->SiS_IF_DEF_LVDS) {
7695      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7696         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7697      }
7698   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7699      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7700   } else return;
7701 
7702   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7703 
7704   if(SiS_Pr->ChipType < SIS_315H) {
7705      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7706   }
7707 
7708   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7709                           &ResIndex, &DisplayType))) {
7710      return;
7711   }
7712 
7713   switch(DisplayType) {
7714     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
7715     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
7716     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
7717     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
7718     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
7719     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
7720     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
7721 #if 0 /* Works better with calculated numbers */
7722     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7723     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7724     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7725     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7726 #endif
7727     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7728     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7729     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7730     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7731     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
7732   }
7733 
7734   if(LVDSCRT1Ptr) {
7735 
7736      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7737 
7738      for(i = 0; i <= 10; i++) {
7739         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7740         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7741      }
7742 
7743      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7744         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7745         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7746      }
7747 
7748      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7749      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7750 
7751      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7752      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7753 
7754      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7755      if(modeflag & DoubleScanMode) tempah |= 0x80;
7756      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7757 
7758   } else {
7759 
7760      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7761 
7762   }
7763 }
7764 
7765 /*********************************************/
7766 /*              SET CRT2 ECLK                */
7767 /*********************************************/
7768 
7769 static void
7770 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7771            unsigned short RefreshRateTableIndex)
7772 {
7773   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7774   unsigned short clkbase, vclkindex = 0;
7775   unsigned char  sr2b, sr2c;
7776 
7777   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7778      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7779      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7780 	RefreshRateTableIndex--;
7781      }
7782      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7783                                     RefreshRateTableIndex);
7784      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7785   } else {
7786      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7787                                     RefreshRateTableIndex);
7788   }
7789 
7790   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7791   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7792 
7793   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7794      if(SiS_Pr->SiS_UseROM) {
7795 	if(ROMAddr[0x220] & 0x01) {
7796 	   sr2b = ROMAddr[0x227];
7797 	   sr2c = ROMAddr[0x228];
7798 	}
7799      }
7800   }
7801 
7802   clkbase = 0x02B;
7803   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7804      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7805 	clkbase += 3;
7806      }
7807   }
7808 
7809   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7810   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7811   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7812   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7813   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7814   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7815   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7816   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7817   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7818 }
7819 
7820 /*********************************************/
7821 /*           SET UP CHRONTEL CHIPS           */
7822 /*********************************************/
7823 
7824 static void
7825 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7826                unsigned short RefreshRateTableIndex)
7827 {
7828    unsigned short TVType, resindex;
7829    const struct SiS_CHTVRegData *CHTVRegData = NULL;
7830 
7831    if(ModeNo <= 0x13)
7832       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7833    else
7834       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7835 
7836    resindex &= 0x3F;
7837 
7838    TVType = 0;
7839    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7840    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7841       TVType += 2;
7842       if(SiS_Pr->SiS_ModeType > ModeVGA) {
7843 	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7844       }
7845       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7846 	 TVType = 4;
7847 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7848       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7849 	 TVType = 6;
7850 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7851       }
7852    }
7853 
7854    switch(TVType) {
7855       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7856       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7857       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
7858       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7859       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7860       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7861       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7862       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7863       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7864       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7865    }
7866 
7867 
7868    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7869 
7870 #ifdef CONFIG_FB_SIS_300
7871 
7872       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7873 
7874       /* We don't support modes >800x600 */
7875       if (resindex > 5) return;
7876 
7877       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7878 	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7879 	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
7880       } else {
7881 	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7882 	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
7883       }
7884 
7885       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
7886       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
7887       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
7888       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
7889       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
7890 
7891       /* Set minimum flicker filter for Luma channel (SR1-0=00),
7892                 minimum text enhancement (S3-2=10),
7893    	        maximum flicker filter for Chroma channel (S5-4=10)
7894 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7895        */
7896       SiS_SetCH700x(SiS_Pr,0x01,0x28);
7897 
7898       /* Set video bandwidth
7899             High bandwidth Luma composite video filter(S0=1)
7900             low bandwidth Luma S-video filter (S2-1=00)
7901 	    disable peak filter in S-video channel (S3=0)
7902 	    high bandwidth Chroma Filter (S5-4=11)
7903 	    =00110001=0x31
7904       */
7905       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
7906 
7907       /* Register 0x3D does not exist in non-macrovision register map
7908             (Maybe this is a macrovision register?)
7909        */
7910 #ifndef SIS_CP
7911       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7912 #endif
7913 
7914       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7915              all other bits a read-only. Macrovision?
7916        */
7917       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7918 
7919       /* Register 0x11 only contains 3 writable bits (S0-S2) for
7920              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7921        */
7922       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7923 
7924       /* Clear DSEN
7925        */
7926       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7927 
7928       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
7929          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7930             if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
7931       	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7932                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
7933             } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
7934                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
7935                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7936                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7937                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7938                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7939                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7940                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7941                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7942                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
7943                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
7944             }
7945          } else {
7946             if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
7947                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7948                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7949             } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
7950 #if 0
7951                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7952                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
7953                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
7954                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7955                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7956                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7957                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7958                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7959                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
7960                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
7961 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7962 	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
7963                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7964             }
7965          }
7966       } else {						/* ---- PAL ---- */
7967          /* We don't play around with FSCI in PAL mode */
7968          if(resindex == 0x04) {
7969             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7970             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
7971          } else {
7972             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7973             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
7974          }
7975       }
7976 
7977 #endif  /* 300 */
7978 
7979    } else {
7980 
7981       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
7982 
7983 #ifdef CONFIG_FB_SIS_315
7984 
7985       unsigned short temp;
7986 
7987       /* We don't support modes >1024x768 */
7988       if (resindex > 6) return;
7989 
7990       temp = CHTVRegData[resindex].Reg[0];
7991       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
7992       SiS_SetCH701x(SiS_Pr,0x00,temp);
7993 
7994       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
7995       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
7996       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
7997       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
7998       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
7999       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8000 
8001       temp = CHTVRegData[resindex].Reg[7];
8002       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8003       SiS_SetCH701x(SiS_Pr,0x07,temp);
8004 
8005       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8006       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8007       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8008       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8009       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8010       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8011       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8012       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8013 
8014       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8015       /* D1 should be set for PAL, PAL-N and NTSC-J,
8016          but I won't do that for PAL unless somebody
8017 	 tells me to do so. Since the BIOS uses
8018 	 non-default CIV values and blacklevels,
8019 	 this might be compensated anyway.
8020        */
8021       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8022       SiS_SetCH701x(SiS_Pr,0x21,temp);
8023 
8024 #endif	/* 315 */
8025 
8026    }
8027 
8028 #ifdef SIS_CP
8029    SIS_CP_INIT301_CP3
8030 #endif
8031 
8032 }
8033 
8034 #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8035 
8036 void
8037 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8038 {
8039    unsigned short temp;
8040 
8041    /* Enable Chrontel 7019 LCD panel backlight */
8042    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8043       if(SiS_Pr->ChipType == SIS_740) {
8044 	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8045       } else {
8046 	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8047 	 temp |= 0x20;
8048 	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8049       }
8050    }
8051 }
8052 
8053 void
8054 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8055 {
8056    unsigned short temp;
8057 
8058    /* Disable Chrontel 7019 LCD panel backlight */
8059    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8060       temp = SiS_GetCH701x(SiS_Pr,0x66);
8061       temp &= 0xDF;
8062       SiS_SetCH701x(SiS_Pr,0x66,temp);
8063    }
8064 }
8065 
8066 static void
8067 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8068 {
8069   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8070   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8071   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8072   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8073   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8074   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8075   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8076   const unsigned char *tableptr = NULL;
8077   int i;
8078 
8079   /* Set up Power up/down timing */
8080 
8081   if(SiS_Pr->ChipType == SIS_740) {
8082      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8083 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8084 	else    			          tableptr = table1024_740;
8085      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8086 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8087 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8088 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8089         else					  tableptr = table1400_740;
8090      } else return;
8091   } else {
8092      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8093 	tableptr = table1024_650;
8094      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8095 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8096 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8097 	tableptr = table1400_650;
8098      } else return;
8099   }
8100 
8101   for(i=0; i<5; i++) {
8102      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8103   }
8104 }
8105 
8106 static void
8107 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8108 {
8109   const unsigned char *tableptr = NULL;
8110   unsigned short tempbh;
8111   int i;
8112   static const unsigned char regtable[] = {
8113 		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8114 		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8115   };
8116   static const unsigned char table1024_740[] = {
8117 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8118 		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8119   };
8120   static const unsigned char table1280_740[] = {
8121 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8122 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8123   };
8124   static const unsigned char table1400_740[] = {
8125 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8126 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8127   };
8128   static const unsigned char table1600_740[] = {
8129 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8130 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8131   };
8132   static const unsigned char table1024_650[] = {
8133 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8134 		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8135   };
8136   static const unsigned char table1280_650[] = {
8137 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8138 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8139   };
8140   static const unsigned char table1400_650[] = {
8141 		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8142 		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8143   };
8144   static const unsigned char table1600_650[] = {
8145 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8146 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8147   };
8148 
8149   if(SiS_Pr->ChipType == SIS_740) {
8150      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8151      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8152      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8153      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8154      else return;
8155   } else {
8156      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8157      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8158      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8159      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8160      else return;
8161   }
8162 
8163   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8164   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8165      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8166      if(tempbh == 0xc8) {
8167         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8168      } else if(tempbh == 0xdb) {
8169         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8170 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8171      } else if(tempbh == 0xde) {
8172         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8173      }
8174   }
8175 
8176   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8177   else     			  tempbh = 0x0c;
8178 
8179   for(i = 0; i < tempbh; i++) {
8180      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8181   }
8182   SiS_ChrontelPowerSequencing(SiS_Pr);
8183   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8184   tempbh |= 0xc0;
8185   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8186 
8187   if(SiS_Pr->ChipType == SIS_740) {
8188      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8189      tempbh &= 0xfb;
8190      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8191      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8192      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8193      tempbh |= 0x40;
8194      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8195      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8196      tempbh &= 0x3f;
8197      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8198   }
8199 }
8200 
8201 static void
8202 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8203 {
8204   unsigned char temp, temp1;
8205 
8206   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8207   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8208   temp = SiS_GetCH701x(SiS_Pr,0x47);
8209   temp &= 0x7f;	/* Use external VSYNC */
8210   SiS_SetCH701x(SiS_Pr,0x47,temp);
8211   SiS_LongDelay(SiS_Pr, 3);
8212   temp = SiS_GetCH701x(SiS_Pr,0x47);
8213   temp |= 0x80;	/* Use internal VSYNC */
8214   SiS_SetCH701x(SiS_Pr,0x47,temp);
8215   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8216 }
8217 
8218 static void
8219 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8220 {
8221   unsigned short temp;
8222 
8223   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8224      if(SiS_Pr->ChipType == SIS_740) {
8225         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8226         temp |= 0x04;	/* Invert XCLK phase */
8227         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8228      }
8229      if(SiS_IsYPbPr(SiS_Pr)) {
8230         temp = SiS_GetCH701x(SiS_Pr,0x01);
8231 	temp &= 0x3f;
8232 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8233 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8234      }
8235      if(SiS_IsChScart(SiS_Pr)) {
8236         temp = SiS_GetCH701x(SiS_Pr,0x01);
8237 	temp &= 0x3f;
8238 	temp |= 0xc0;	/* Enable SCART + CVBS */
8239 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8240      }
8241      if(SiS_Pr->ChipType == SIS_740) {
8242         SiS_ChrontelResetVSync(SiS_Pr);
8243         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8244      } else {
8245         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8246         temp = SiS_GetCH701x(SiS_Pr,0x49);
8247         if(SiS_IsYPbPr(SiS_Pr)) {
8248            temp = SiS_GetCH701x(SiS_Pr,0x73);
8249 	   temp |= 0x60;
8250 	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8251         }
8252         temp = SiS_GetCH701x(SiS_Pr,0x47);
8253         temp &= 0x7f;
8254         SiS_SetCH701x(SiS_Pr,0x47,temp);
8255         SiS_LongDelay(SiS_Pr, 2);
8256         temp = SiS_GetCH701x(SiS_Pr,0x47);
8257         temp |= 0x80;
8258         SiS_SetCH701x(SiS_Pr,0x47,temp);
8259      }
8260   }
8261 }
8262 
8263 static void
8264 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8265 {
8266   unsigned short temp;
8267 
8268   /* Complete power down of LVDS */
8269   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8270      if(SiS_Pr->ChipType == SIS_740) {
8271         SiS_LongDelay(SiS_Pr, 1);
8272 	SiS_GenericDelay(SiS_Pr, 5887);
8273 	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8274 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8275      } else {
8276         SiS_LongDelay(SiS_Pr, 2);
8277 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8278 	temp &= 0xfc;
8279 	SiS_SetCH701x(SiS_Pr,0x76,temp);
8280 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8281      }
8282   }
8283 }
8284 
8285 static void
8286 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8287 {
8288      unsigned short temp;
8289 
8290      if(SiS_Pr->ChipType == SIS_740) {
8291 
8292         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8293         temp &= 0x01;
8294         if(!temp) {
8295 
8296            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8297 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8298 	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8299 	   }
8300 
8301 	   /* Reset Chrontel 7019 datapath */
8302            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8303            SiS_LongDelay(SiS_Pr, 1);
8304            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8305 
8306 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8307 	      SiS_ChrontelResetVSync(SiS_Pr);
8308 	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8309 	   }
8310 
8311         } else {
8312 
8313 	   /* Clear/set/clear GPIO */
8314            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8315 	   temp &= 0xef;
8316 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8317 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8318 	   temp |= 0x10;
8319 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8320 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8321 	   temp &= 0xef;
8322 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8323 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8324 	   if(!temp) {
8325 	      SiS_SetCH701xForLCD(SiS_Pr);
8326 	   }
8327         }
8328 
8329      } else { /* 650 */
8330         /* Reset Chrontel 7019 datapath */
8331         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8332         SiS_LongDelay(SiS_Pr, 1);
8333         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8334      }
8335 }
8336 
8337 static void
8338 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8339 {
8340      unsigned short temp;
8341 
8342      if(SiS_Pr->ChipType == SIS_740) {
8343 
8344         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8345            SiS_ChrontelResetVSync(SiS_Pr);
8346         }
8347 
8348      } else {
8349 
8350         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8351         temp = SiS_GetCH701x(SiS_Pr,0x49);
8352         temp &= 1;
8353         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8354 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8355 	   temp &= 0x70;
8356 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8357 	   SiS_LongDelay(SiS_Pr, 3);
8358 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8359 	   temp |= 0x80;
8360 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8361         }
8362 
8363      }
8364 }
8365 
8366 static void
8367 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8368 {
8369      unsigned short temp,temp1;
8370 
8371      if(SiS_Pr->ChipType == SIS_740) {
8372 
8373         temp = SiS_GetCH701x(SiS_Pr,0x61);
8374         if(temp < 1) {
8375            temp++;
8376 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8377         }
8378         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8379         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8380         SiS_LongDelay(SiS_Pr, 1);
8381         SiS_GenericDelay(SiS_Pr, 5887);
8382 
8383      } else {  /* 650 */
8384 
8385         temp1 = 0;
8386         temp = SiS_GetCH701x(SiS_Pr,0x61);
8387         if(temp < 2) {
8388            temp++;
8389 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8390 	   temp1 = 1;
8391         }
8392         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8393         temp = SiS_GetCH701x(SiS_Pr,0x66);
8394         temp |= 0x5f;
8395         SiS_SetCH701x(SiS_Pr,0x66,temp);
8396         if(ModeNo > 0x13) {
8397            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8398 	      SiS_GenericDelay(SiS_Pr, 1023);
8399 	   } else {
8400 	      SiS_GenericDelay(SiS_Pr, 767);
8401 	   }
8402         } else {
8403            if(!temp1)
8404 	      SiS_GenericDelay(SiS_Pr, 767);
8405         }
8406         temp = SiS_GetCH701x(SiS_Pr,0x76);
8407         temp |= 0x03;
8408         SiS_SetCH701x(SiS_Pr,0x76,temp);
8409         temp = SiS_GetCH701x(SiS_Pr,0x66);
8410         temp &= 0x7f;
8411         SiS_SetCH701x(SiS_Pr,0x66,temp);
8412         SiS_LongDelay(SiS_Pr, 1);
8413 
8414      }
8415 }
8416 
8417 static void
8418 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8419 {
8420      unsigned short temp;
8421 
8422      SiS_LongDelay(SiS_Pr, 1);
8423 
8424      do {
8425        temp = SiS_GetCH701x(SiS_Pr,0x66);
8426        temp &= 0x04;  /* PLL stable? -> bail out */
8427        if(temp == 0x04) break;
8428 
8429        if(SiS_Pr->ChipType == SIS_740) {
8430           /* Power down LVDS output, PLL normal operation */
8431           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8432        }
8433 
8434        SiS_SetCH701xForLCD(SiS_Pr);
8435 
8436        temp = SiS_GetCH701x(SiS_Pr,0x76);
8437        temp &= 0xfb;  /* Reset PLL */
8438        SiS_SetCH701x(SiS_Pr,0x76,temp);
8439        SiS_LongDelay(SiS_Pr, 2);
8440        temp = SiS_GetCH701x(SiS_Pr,0x76);
8441        temp |= 0x04;  /* PLL normal operation */
8442        SiS_SetCH701x(SiS_Pr,0x76,temp);
8443        if(SiS_Pr->ChipType == SIS_740) {
8444           SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8445        } else {
8446           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8447        }
8448        SiS_LongDelay(SiS_Pr, 2);
8449     } while(0);
8450 
8451     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8452 }
8453 
8454 static void
8455 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8456 {
8457      unsigned short temp;
8458 
8459      temp = SiS_GetCH701x(SiS_Pr,0x03);
8460      temp |= 0x80;	/* Set datapath 1 to TV   */
8461      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8462      SiS_SetCH701x(SiS_Pr,0x03,temp);
8463 
8464      if(SiS_Pr->ChipType == SIS_740) {
8465 
8466         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8467         temp &= 0xfb;	/* Normal XCLK phase */
8468         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8469 
8470         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8471 
8472         temp = SiS_GetCH701x(SiS_Pr,0x64);
8473         temp |= 0x40;	/* ? Bit not defined */
8474         SiS_SetCH701x(SiS_Pr,0x64,temp);
8475 
8476         temp = SiS_GetCH701x(SiS_Pr,0x03);
8477         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8478         SiS_SetCH701x(SiS_Pr,0x03,temp);
8479 
8480 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8481 	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8482 	   SiS_LongDelay(SiS_Pr, 1);
8483 	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8484 	   SiS_ChrontelResetDB(SiS_Pr);
8485 	   SiS_ChrontelDoSomething2(SiS_Pr);
8486 	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8487 	} else {
8488            temp = SiS_GetCH701x(SiS_Pr,0x66);
8489            if(temp != 0x45) {
8490               SiS_ChrontelResetDB(SiS_Pr);
8491               SiS_ChrontelDoSomething2(SiS_Pr);
8492               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8493            }
8494 	}
8495 
8496      } else { /* 650 */
8497 
8498         SiS_ChrontelResetDB(SiS_Pr);
8499         SiS_ChrontelDoSomething2(SiS_Pr);
8500         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8501         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8502         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8503 
8504      }
8505 
8506 }
8507 #endif  /* 315 series  */
8508 
8509 /*********************************************/
8510 /*      MAIN: SET CRT2 REGISTER GROUP        */
8511 /*********************************************/
8512 
8513 bool
8514 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8515 {
8516 #ifdef CONFIG_FB_SIS_300
8517    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8518 #endif
8519    unsigned short ModeIdIndex, RefreshRateTableIndex;
8520 
8521    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8522 
8523    if(!SiS_Pr->UseCustomMode) {
8524       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8525    } else {
8526       ModeIdIndex = 0;
8527    }
8528 
8529    /* Used for shifting CR33 */
8530    SiS_Pr->SiS_SelectCRT2Rate = 4;
8531 
8532    SiS_UnLockCRT2(SiS_Pr);
8533 
8534    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8535 
8536    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8537 
8538    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8539       SiS_DisableBridge(SiS_Pr);
8540       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8541          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8542       }
8543       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8544    }
8545 
8546    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8547       SiS_LockCRT2(SiS_Pr);
8548       SiS_DisplayOn(SiS_Pr);
8549       return true;
8550    }
8551 
8552    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8553 
8554    /* Set up Panel Link for LVDS and LCDA */
8555    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8556    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8557        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8558        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8559       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8560    }
8561 
8562    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8563       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8564    }
8565 
8566    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8567 
8568       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8569 
8570 	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8571 #ifdef CONFIG_FB_SIS_315
8572 	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8573 #endif
8574 	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8575 	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8576 #ifdef CONFIG_FB_SIS_315
8577 	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8578 #endif
8579 	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8580 
8581 	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8582 
8583 	 /* For 301BDH (Panel link initialization): */
8584 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8585 
8586 	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8587 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8588 		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8589 	       }
8590             }
8591 	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8592 	 }
8593       }
8594 
8595    } else {
8596 
8597       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8598 
8599       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8600 
8601       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8602 
8603       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8604 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8605 	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8606 	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8607 #ifdef CONFIG_FB_SIS_315
8608 		  SiS_SetCH701xForLCD(SiS_Pr);
8609 #endif
8610 	       }
8611 	    }
8612 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8613 	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8614 	    }
8615 	 }
8616       }
8617 
8618    }
8619 
8620 #ifdef CONFIG_FB_SIS_300
8621    if(SiS_Pr->ChipType < SIS_315H) {
8622       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8623 	 if(SiS_Pr->SiS_UseOEM) {
8624 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8625 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8626 		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8627 	       }
8628 	    } else {
8629 	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8630 	    }
8631 	 }
8632 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8633 	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8634 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8635 	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8636 	    }
8637 	    SiS_DisplayOn(SiS_Pr);
8638          }
8639       }
8640    }
8641 #endif
8642 
8643 #ifdef CONFIG_FB_SIS_315
8644    if(SiS_Pr->ChipType >= SIS_315H) {
8645       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8646 	 if(SiS_Pr->ChipType < SIS_661) {
8647 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8648 	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8649 	 } else {
8650 	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8651 	 }
8652 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8653       }
8654    }
8655 #endif
8656 
8657    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8658       SiS_EnableBridge(SiS_Pr);
8659    }
8660 
8661    SiS_DisplayOn(SiS_Pr);
8662 
8663    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8664       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8665 	 /* Disable LCD panel when using TV */
8666 	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8667       } else {
8668 	 /* Disable TV when using LCD */
8669 	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8670       }
8671    }
8672 
8673    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8674       SiS_LockCRT2(SiS_Pr);
8675    }
8676 
8677    return true;
8678 }
8679 
8680 
8681 /*********************************************/
8682 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8683 /*********************************************/
8684 
8685 void
8686 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8687 {
8688   /* Switch on LCD backlight on SiS30xLV */
8689   SiS_DDC2Delay(SiS_Pr,0xff00);
8690   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8691      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8692      SiS_WaitVBRetrace(SiS_Pr);
8693   }
8694   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8695      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8696   }
8697 }
8698 
8699 void
8700 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8701 {
8702   /* Switch off LCD backlight on SiS30xLV */
8703   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8704   SiS_DDC2Delay(SiS_Pr,0xff00);
8705 }
8706 
8707 /*********************************************/
8708 /*          DDC RELATED FUNCTIONS            */
8709 /*********************************************/
8710 
8711 static void
8712 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8713 {
8714   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8715   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
8716   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8717      SiS_Pr->SiS_DDC_NData &= 0x0f;
8718      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
8719   }
8720 }
8721 
8722 #ifdef CONFIG_FB_SIS_300
8723 static unsigned char *
8724 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8725 {
8726   int i, j, num;
8727   unsigned short tempah,temp;
8728   unsigned char *mydataptr;
8729 
8730   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8731      mydataptr = dataptr;
8732      num = *mydataptr++;
8733      if(!num) return mydataptr;
8734      if(i) {
8735         SiS_SetStop(SiS_Pr);
8736 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8737      }
8738      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
8739      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8740      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
8741      if(temp) continue;				/*    (ERROR: no ack) */
8742      tempah = *mydataptr++;
8743      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
8744      if(temp) continue;				/*    (ERROR: no ack) */
8745      for(j=0; j<num; j++) {
8746         tempah = *mydataptr++;
8747         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8748 	if(temp) break;
8749      }
8750      if(temp) continue;
8751      if(SiS_SetStop(SiS_Pr)) continue;
8752      return mydataptr;
8753   }
8754   return NULL;
8755 }
8756 
8757 static bool
8758 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8759 {
8760   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
8761   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8762   SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
8763   SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
8764   SiS_SetupDDCN(SiS_Pr);
8765 
8766   SiS_SetSwitchDDC2(SiS_Pr);
8767 
8768   while(*dataptr) {
8769      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8770      if(!dataptr) return false;
8771   }
8772   return true;
8773 }
8774 #endif
8775 
8776 /* The Chrontel 700x is connected to the 630/730 via
8777  * the 630/730's DDC/I2C port.
8778  *
8779  * On 630(S)T chipset, the index changed from 0x11 to
8780  * 0x0a, possibly for working around the DDC problems
8781  */
8782 
8783 static bool
8784 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8785 {
8786   unsigned short temp, i;
8787 
8788   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8789      if(i) {
8790 	SiS_SetStop(SiS_Pr);
8791 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8792      }
8793      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
8794      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
8795      if(temp) continue;							/*    (ERROR: no ack) */
8796      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
8797      if(temp) continue;							/*    (ERROR: no ack) */
8798      temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
8799      if(temp) continue;							/*    (ERROR: no ack) */
8800      if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
8801      SiS_Pr->SiS_ChrontelInit = 1;
8802      return true;
8803   }
8804   return false;
8805 }
8806 
8807 /* Write to Chrontel 700x */
8808 void
8809 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8810 {
8811   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
8812 
8813   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8814 
8815   if(!(SiS_Pr->SiS_ChrontelInit)) {
8816      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
8817      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
8818      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
8819      SiS_SetupDDCN(SiS_Pr);
8820   }
8821 
8822   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8823       (!(SiS_Pr->SiS_ChrontelInit)) ) {
8824      SiS_Pr->SiS_DDC_Index = 0x0a;
8825      SiS_Pr->SiS_DDC_Data  = 0x80;
8826      SiS_Pr->SiS_DDC_Clk   = 0x40;
8827      SiS_SetupDDCN(SiS_Pr);
8828 
8829      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8830   }
8831 }
8832 
8833 /* Write to Chrontel 701x */
8834 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8835 void
8836 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8837 {
8838   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8839   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
8840   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
8841   SiS_SetupDDCN(SiS_Pr);
8842   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
8843   SiS_SetChReg(SiS_Pr, reg, val, 0);
8844 }
8845 
8846 static
8847 void
8848 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8849 {
8850   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8851      SiS_SetCH700x(SiS_Pr, reg, val);
8852   else
8853      SiS_SetCH701x(SiS_Pr, reg, val);
8854 }
8855 
8856 static unsigned short
8857 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8858 {
8859   unsigned short tempah, temp, i;
8860 
8861   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
8862      if(i) {
8863 	SiS_SetStop(SiS_Pr);
8864 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8865      }
8866      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
8867      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
8868      if(temp) continue;							/*        (ERROR: no ack) */
8869      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
8870      if(temp) continue;							/*        (ERROR: no ack) */
8871      if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
8872      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8873      if(temp) continue;							/*        (ERROR: no ack) */
8874      tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
8875      if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
8876      SiS_Pr->SiS_ChrontelInit = 1;
8877      return tempah;
8878   }
8879   return 0xFFFF;
8880 }
8881 
8882 /* Read from Chrontel 700x */
8883 /* Parameter is [Register no (S7-S0)] */
8884 unsigned short
8885 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8886 {
8887   unsigned short result;
8888 
8889   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
8890 
8891   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8892 
8893   if(!(SiS_Pr->SiS_ChrontelInit)) {
8894      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
8895      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
8896      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
8897      SiS_SetupDDCN(SiS_Pr);
8898   }
8899 
8900   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8901 
8902   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8903       (!SiS_Pr->SiS_ChrontelInit) ) {
8904 
8905      SiS_Pr->SiS_DDC_Index = 0x0a;
8906      SiS_Pr->SiS_DDC_Data  = 0x80;
8907      SiS_Pr->SiS_DDC_Clk   = 0x40;
8908      SiS_SetupDDCN(SiS_Pr);
8909 
8910      result = SiS_GetChReg(SiS_Pr,0x80);
8911   }
8912   return result;
8913 }
8914 
8915 /* Read from Chrontel 701x */
8916 /* Parameter is [Register no (S7-S0)] */
8917 unsigned short
8918 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8919 {
8920   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8921   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
8922   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
8923   SiS_SetupDDCN(SiS_Pr);
8924   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
8925 
8926   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8927 
8928   return SiS_GetChReg(SiS_Pr,0);
8929 }
8930 
8931 /* Read from Chrontel 70xx */
8932 /* Parameter is [Register no (S7-S0)] */
8933 static
8934 unsigned short
8935 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8936 {
8937   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8938      return SiS_GetCH700x(SiS_Pr, tempbx);
8939   else
8940      return SiS_GetCH701x(SiS_Pr, tempbx);
8941 }
8942 
8943 void
8944 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8945 		unsigned char myor, unsigned short myand)
8946 {
8947   unsigned short tempbl;
8948 
8949   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8950   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8951 }
8952 
8953 /* Our own DDC functions */
8954 static
8955 unsigned short
8956 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8957                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8958 		unsigned int VBFlags2)
8959 {
8960      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8961      unsigned char flag, cr32;
8962      unsigned short        temp = 0, myadaptnum = adaptnum;
8963 
8964      if(adaptnum != 0) {
8965 	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8966 	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
8967      }
8968 
8969      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
8970 
8971      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
8972 
8973      SiS_Pr->SiS_DDC_SecAddr = 0;
8974      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
8975      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
8976      SiS_Pr->SiS_DDC_Index = 0x11;
8977      flag = 0xff;
8978 
8979      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
8980 
8981 #if 0
8982      if(VBFlags2 & VB2_SISBRIDGE) {
8983 	if(myadaptnum == 0) {
8984 	   if(!(cr32 & 0x20)) {
8985 	      myadaptnum = 2;
8986 	      if(!(cr32 & 0x10)) {
8987 	         myadaptnum = 1;
8988 		 if(!(cr32 & 0x08)) {
8989 		    myadaptnum = 0;
8990 		 }
8991 	      }
8992 	   }
8993         }
8994      }
8995 #endif
8996 
8997      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
8998 
8999         if(myadaptnum != 0) {
9000 	   flag = 0;
9001 	   if(VBFlags2 & VB2_SISBRIDGE) {
9002 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9003               SiS_Pr->SiS_DDC_Index = 0x0f;
9004 	   }
9005         }
9006 
9007 	if(!(VBFlags2 & VB2_301)) {
9008 	   if((cr32 & 0x80) && (checkcr32)) {
9009               if(myadaptnum >= 1) {
9010 	         if(!(cr32 & 0x08)) {
9011 		     myadaptnum = 1;
9012 		     if(!(cr32 & 0x10)) return 0xFFFF;
9013                  }
9014 	      }
9015 	   }
9016 	}
9017 
9018 	temp = 4 - (myadaptnum * 2);
9019 	if(flag) temp = 0;
9020 
9021      } else {						/* 315/330 series */
9022 
9023 	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9024 
9025 	if(VBFlags2 & VB2_SISBRIDGE) {
9026 	   if(myadaptnum == 2) {
9027 	      myadaptnum = 1;
9028 	   }
9029 	}
9030 
9031         if(myadaptnum == 1) {
9032 	   flag = 0;
9033 	   if(VBFlags2 & VB2_SISBRIDGE) {
9034 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9035               SiS_Pr->SiS_DDC_Index = 0x0f;
9036 	   }
9037         }
9038 
9039         if((cr32 & 0x80) && (checkcr32)) {
9040            if(myadaptnum >= 1) {
9041 	      if(!(cr32 & 0x08)) {
9042 	         myadaptnum = 1;
9043 		 if(!(cr32 & 0x10)) return 0xFFFF;
9044 	      }
9045 	   }
9046         }
9047 
9048         temp = myadaptnum;
9049         if(myadaptnum == 1) {
9050            temp = 0;
9051 	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9052         }
9053 
9054 	if(flag) temp = 0;
9055     }
9056 
9057     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9058     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9059 
9060     SiS_SetupDDCN(SiS_Pr);
9061 
9062     return 0;
9063 }
9064 
9065 static unsigned short
9066 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9067 {
9068    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9069    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9070       return 0xFFFF;
9071    }
9072    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9073       return 0xFFFF;
9074    }
9075    return 0;
9076 }
9077 
9078 static unsigned short
9079 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9080 {
9081    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9082    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9083       return 0xFFFF;
9084    }
9085    return 0;
9086 }
9087 
9088 static unsigned short
9089 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9090 {
9091    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9092    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9093    return 0;
9094 }
9095 
9096 static void
9097 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9098 {
9099    SiS_SetSCLKLow(SiS_Pr);
9100    if(yesno) {
9101       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9102 		      SiS_Pr->SiS_DDC_Index,
9103 		      SiS_Pr->SiS_DDC_NData,
9104 		      SiS_Pr->SiS_DDC_Data);
9105    } else {
9106       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9107 		      SiS_Pr->SiS_DDC_Index,
9108 		      SiS_Pr->SiS_DDC_NData,
9109 		      0);
9110    }
9111    SiS_SetSCLKHigh(SiS_Pr);
9112 }
9113 
9114 static unsigned short
9115 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9116 {
9117     unsigned char mask, value;
9118     unsigned short  temp, ret=0;
9119     bool failed = false;
9120 
9121     SiS_SetSwitchDDC2(SiS_Pr);
9122     if(SiS_PrepareDDC(SiS_Pr)) {
9123          SiS_SetStop(SiS_Pr);
9124          return 0xFFFF;
9125     }
9126     mask = 0xf0;
9127     value = 0x20;
9128     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9129        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9130        SiS_SendACK(SiS_Pr, 0);
9131        if(temp == 0) {
9132            mask = 0xff;
9133 	   value = 0xff;
9134        } else {
9135            failed = true;
9136 	   ret = 0xFFFF;
9137        }
9138     }
9139     if(!failed) {
9140        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9141        SiS_SendACK(SiS_Pr, 1);
9142        temp &= mask;
9143        if(temp == value) ret = 0;
9144        else {
9145           ret = 0xFFFF;
9146           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9147              if(temp == 0x30) ret = 0;
9148           }
9149        }
9150     }
9151     SiS_SetStop(SiS_Pr);
9152     return ret;
9153 }
9154 
9155 static
9156 unsigned short
9157 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9158 {
9159    unsigned short flag;
9160 
9161    flag = 0x180;
9162    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9163    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9164    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9165    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9166    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9167    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9168    if(!(flag & 0x1a)) flag = 0;
9169    return flag;
9170 }
9171 
9172 static
9173 unsigned short
9174 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9175 {
9176    unsigned short flag, length, i;
9177    unsigned char chksum,gotcha;
9178 
9179    if(DDCdatatype > 4) return 0xFFFF;
9180 
9181    flag = 0;
9182    SiS_SetSwitchDDC2(SiS_Pr);
9183    if(!(SiS_PrepareDDC(SiS_Pr))) {
9184       length = 127;
9185       if(DDCdatatype != 1) length = 255;
9186       chksum = 0;
9187       gotcha = 0;
9188       for(i=0; i<length; i++) {
9189 	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9190 	 chksum += buffer[i];
9191 	 gotcha |= buffer[i];
9192 	 SiS_SendACK(SiS_Pr, 0);
9193       }
9194       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9195       chksum += buffer[i];
9196       SiS_SendACK(SiS_Pr, 1);
9197       if(gotcha) flag = (unsigned short)chksum;
9198       else flag = 0xFFFF;
9199    } else {
9200       flag = 0xFFFF;
9201    }
9202    SiS_SetStop(SiS_Pr);
9203    return flag;
9204 }
9205 
9206 /* Our private DDC functions
9207 
9208    It complies somewhat with the corresponding VESA function
9209    in arguments and return values.
9210 
9211    Since this is probably called before the mode is changed,
9212    we use our pre-detected pSiS-values instead of SiS_Pr as
9213    regards chipset and video bridge type.
9214 
9215    Arguments:
9216        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9217                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9218 		 LCDA is CRT1, but DDC is read from CRT2 port.
9219        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9220        buffer: ptr to 256 data bytes which will be filled with read data.
9221 
9222    Returns 0xFFFF if error, otherwise
9223        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9224        if DDCdatatype = 0:  Returns supported DDC modes
9225 
9226  */
9227 unsigned short
9228 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9229               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9230 	      unsigned int VBFlags2)
9231 {
9232    unsigned char  sr1f, cr17=1;
9233    unsigned short result;
9234 
9235    if(adaptnum > 2)
9236       return 0xFFFF;
9237 
9238    if(DDCdatatype > 4)
9239       return 0xFFFF;
9240 
9241    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9242       return 0xFFFF;
9243 
9244    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9245       return 0xFFFF;
9246 
9247    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9248    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9249    if(VGAEngine == SIS_300_VGA) {
9250       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9251       if(!cr17) {
9252          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9253          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9254          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9255       }
9256    }
9257    if((sr1f) || (!cr17)) {
9258       SiS_WaitRetrace1(SiS_Pr);
9259       SiS_WaitRetrace1(SiS_Pr);
9260       SiS_WaitRetrace1(SiS_Pr);
9261       SiS_WaitRetrace1(SiS_Pr);
9262    }
9263 
9264    if(DDCdatatype == 0) {
9265       result = SiS_ProbeDDC(SiS_Pr);
9266    } else {
9267       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9268       if((!result) && (DDCdatatype == 1)) {
9269          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9270 	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9271 	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9272 	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9273 	    (buffer[0x12] == 1)) {
9274 	    if(!SiS_Pr->DDCPortMixup) {
9275 	       if(adaptnum == 1) {
9276 	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9277 	       } else {
9278 	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9279 	       }
9280 	    }
9281 	 }
9282       }
9283    }
9284    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9285    if(VGAEngine == SIS_300_VGA) {
9286       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9287    }
9288    return result;
9289 }
9290 
9291 /* Generic I2C functions for Chrontel & DDC --------- */
9292 
9293 static void
9294 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9295 {
9296   SiS_SetSCLKHigh(SiS_Pr);
9297   SiS_WaitRetrace1(SiS_Pr);
9298 
9299   SiS_SetSCLKLow(SiS_Pr);
9300   SiS_WaitRetrace1(SiS_Pr);
9301 }
9302 
9303 unsigned short
9304 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9305 {
9306    SiS_WaitRetrace1(SiS_Pr);
9307    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9308 }
9309 
9310 /* Set I2C start condition */
9311 /* This is done by a SD high-to-low transition while SC is high */
9312 static unsigned short
9313 SiS_SetStart(struct SiS_Private *SiS_Pr)
9314 {
9315   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9316   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9317 		  SiS_Pr->SiS_DDC_Index,
9318 		  SiS_Pr->SiS_DDC_NData,
9319 		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9320   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9321   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9322 		  SiS_Pr->SiS_DDC_Index,
9323 		  SiS_Pr->SiS_DDC_NData,
9324 		  0x00);					/* SD->low = start condition */
9325   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9326   return 0;
9327 }
9328 
9329 /* Set I2C stop condition */
9330 /* This is done by a SD low-to-high transition while SC is high */
9331 static unsigned short
9332 SiS_SetStop(struct SiS_Private *SiS_Pr)
9333 {
9334   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9335   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9336 		  SiS_Pr->SiS_DDC_Index,
9337 		  SiS_Pr->SiS_DDC_NData,
9338 		  0x00);					/* SD->low   */
9339   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9340   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9341 		  SiS_Pr->SiS_DDC_Index,
9342 		  SiS_Pr->SiS_DDC_NData,
9343 		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9344   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9345   return 0;
9346 }
9347 
9348 /* Write 8 bits of data */
9349 static unsigned short
9350 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9351 {
9352   unsigned short i,flag,temp;
9353 
9354   flag = 0x80;
9355   for(i = 0; i < 8; i++) {
9356     SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9357     if(tempax & flag) {
9358       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9359 		      SiS_Pr->SiS_DDC_Index,
9360 		      SiS_Pr->SiS_DDC_NData,
9361 		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9362     } else {
9363       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9364 		      SiS_Pr->SiS_DDC_Index,
9365 		      SiS_Pr->SiS_DDC_NData,
9366 		      0x00);					/* Write bit (0) to SD */
9367     }
9368     SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9369     flag >>= 1;
9370   }
9371   temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9372   return temp;
9373 }
9374 
9375 static unsigned short
9376 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9377 {
9378   unsigned short i, temp, getdata;
9379 
9380   getdata = 0;
9381   for(i = 0; i < 8; i++) {
9382     getdata <<= 1;
9383     SiS_SetSCLKLow(SiS_Pr);
9384     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9385 		    SiS_Pr->SiS_DDC_Index,
9386 		    SiS_Pr->SiS_DDC_NData,
9387 		    SiS_Pr->SiS_DDC_Data);
9388     SiS_SetSCLKHigh(SiS_Pr);
9389     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9390     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9391   }
9392   return getdata;
9393 }
9394 
9395 static unsigned short
9396 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9397 {
9398   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9399 		  SiS_Pr->SiS_DDC_Index,
9400 		  SiS_Pr->SiS_DDC_NClk,
9401 		  0x00);					/* SetSCLKLow()  */
9402   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9403   return 0;
9404 }
9405 
9406 static unsigned short
9407 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9408 {
9409   unsigned short temp, watchdog=1000;
9410 
9411   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9412 		  SiS_Pr->SiS_DDC_Index,
9413 		  SiS_Pr->SiS_DDC_NClk,
9414 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9415   do {
9416     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9417   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9418   if (!watchdog) {
9419   	return 0xFFFF;
9420   }
9421   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9422   return 0;
9423 }
9424 
9425 /* Check I2C acknowledge */
9426 /* Returns 0 if ack ok, non-0 if ack not ok */
9427 static unsigned short
9428 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9429 {
9430   unsigned short tempah;
9431 
9432   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9433   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9434 		  SiS_Pr->SiS_DDC_Index,
9435 		  SiS_Pr->SiS_DDC_NData,
9436 		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9437   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9438   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9439   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9440   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9441   return 0;
9442 }
9443 
9444 /* End of I2C functions ----------------------- */
9445 
9446 
9447 /* =============== SiS 315/330 O.E.M. ================= */
9448 
9449 #ifdef CONFIG_FB_SIS_315
9450 
9451 static unsigned short
9452 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9453 {
9454   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9455   unsigned short romptr;
9456 
9457   if(SiS_Pr->ChipType < SIS_330) {
9458      romptr = SISGETROMW(0x128);
9459      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9460         romptr = SISGETROMW(0x12a);
9461   } else {
9462      romptr = SISGETROMW(0x1a8);
9463      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9464         romptr = SISGETROMW(0x1aa);
9465   }
9466   return romptr;
9467 }
9468 
9469 static unsigned short
9470 GetLCDromptr(struct SiS_Private *SiS_Pr)
9471 {
9472   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9473   unsigned short romptr;
9474 
9475   if(SiS_Pr->ChipType < SIS_330) {
9476      romptr = SISGETROMW(0x120);
9477      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9478         romptr = SISGETROMW(0x122);
9479   } else {
9480      romptr = SISGETROMW(0x1a0);
9481      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9482         romptr = SISGETROMW(0x1a2);
9483   }
9484   return romptr;
9485 }
9486 
9487 static unsigned short
9488 GetTVromptr(struct SiS_Private *SiS_Pr)
9489 {
9490   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9491   unsigned short romptr;
9492 
9493   if(SiS_Pr->ChipType < SIS_330) {
9494      romptr = SISGETROMW(0x114);
9495      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9496         romptr = SISGETROMW(0x11a);
9497   } else {
9498      romptr = SISGETROMW(0x194);
9499      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9500         romptr = SISGETROMW(0x19a);
9501   }
9502   return romptr;
9503 }
9504 
9505 static unsigned short
9506 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9507 {
9508   unsigned short index;
9509 
9510   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9511      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9512         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9513 	   index >>= 4;
9514 	   index *= 3;
9515 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9516            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9517            return index;
9518 	}
9519      }
9520   }
9521 
9522   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9523   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9524   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9525      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9526      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9527   } else {
9528      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9529   }
9530   index--;
9531   index *= 3;
9532   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9533   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9534   return index;
9535 }
9536 
9537 static unsigned short
9538 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9539 {
9540   unsigned short index;
9541 
9542   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9543   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9544   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9545   return index;
9546 }
9547 
9548 static unsigned short
9549 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9550 {
9551   unsigned short index;
9552 
9553   index = 0;
9554   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9555   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9556 
9557   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9558 
9559   index <<= 1;
9560 
9561   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9562      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9563      index++;
9564   }
9565 
9566   return index;
9567 }
9568 
9569 static unsigned int
9570 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9571 {
9572    unsigned short index = 0, temp = 0;
9573 
9574    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9575    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9576    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9577    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9578    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9579       index = 4;
9580       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9581       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9582    }
9583 
9584    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9585       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9586          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9587 	 index += addme;
9588 	 temp++;
9589       }
9590       temp += 0x0100;
9591    }
9592    return (unsigned int)(index | (temp << 16));
9593 }
9594 
9595 static unsigned int
9596 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9597 {
9598    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9599 }
9600 
9601 #if 0
9602 static unsigned int
9603 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9604 {
9605    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9606 }
9607 #endif
9608 
9609 static int
9610 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9611 {
9612    int index = 0;
9613 
9614    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9615    if(SiS_Pr->SiS_ROMNew) {
9616       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9617       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9618       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9619       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9620    } else {
9621       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9622       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9623       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9624       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9625    }
9626 
9627    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9628 
9629    return index;
9630 }
9631 
9632 static void
9633 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9634 {
9635   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9636   unsigned short delay=0,index,myindex,temp,romptr=0;
9637   bool dochiptest = true;
9638 
9639   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9640      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9641   } else {
9642      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9643   }
9644 
9645   /* Find delay (from ROM, internal tables, PCI subsystem) */
9646 
9647   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9648 
9649      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9650         romptr = GetRAMDACromptr(SiS_Pr);
9651      }
9652      if(romptr) delay = ROMAddr[romptr];
9653      else {
9654         delay = 0x04;
9655         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9656 	   if(IS_SIS650) {
9657 	      delay = 0x0a;
9658 	   } else if(IS_SIS740) {
9659 	      delay = 0x00;
9660 	   } else if(SiS_Pr->ChipType < SIS_330) {
9661 	      delay = 0x0c;
9662 	   } else {
9663 	      delay = 0x0c;
9664 	   }
9665 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9666            delay = 0x00;
9667 	}
9668      }
9669 
9670   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9671 
9672      bool gotitfrompci = false;
9673 
9674      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9675 
9676      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9677 	if(SiS_Pr->PDC != -1) {
9678            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9679 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9680 	   return;
9681 	}
9682      } else {
9683 	if(SiS_Pr->PDCA != -1) {
9684 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9685 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9686 	   return;
9687 	}
9688      }
9689 
9690      /* Custom Panel? */
9691 
9692      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9693         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9694 	   delay = 0x00;
9695 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9696 	      delay = 0x20;
9697 	   }
9698 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9699 	} else {
9700 	   delay = 0x0c;
9701 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9702 	      delay = 0x03;
9703 	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9704 	         delay = 0x00;
9705 	      }
9706 	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9707 	      if(IS_SIS740) delay = 0x01;
9708 	      else          delay = 0x03;
9709 	   }
9710 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9711 	}
9712         return;
9713      }
9714 
9715      /* This is a piece of typical SiS crap: They code the OEM LCD
9716       * delay into the code, at no defined place in the BIOS.
9717       * We now have to start doing a PCI subsystem check here.
9718       */
9719 
9720      switch(SiS_Pr->SiS_CustomT) {
9721      case CUT_COMPAQ1280:
9722      case CUT_COMPAQ12802:
9723 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9724 	   gotitfrompci = true;
9725 	   dochiptest = false;
9726 	   delay = 0x03;
9727 	}
9728 	break;
9729      case CUT_CLEVO1400:
9730      case CUT_CLEVO14002:
9731 	gotitfrompci = true;
9732 	dochiptest = false;
9733 	delay = 0x02;
9734 	break;
9735      case CUT_CLEVO1024:
9736      case CUT_CLEVO10242:
9737         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9738 	   gotitfrompci = true;
9739 	   dochiptest = false;
9740 	   delay = 0x33;
9741 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9742 	   delay &= 0x0f;
9743 	}
9744 	break;
9745      }
9746 
9747      /* Could we find it through the PCI ID? If no, use ROM or table */
9748 
9749      if(!gotitfrompci) {
9750 
9751         index = GetLCDPtrIndexBIOS(SiS_Pr);
9752         myindex = GetLCDPtrIndex(SiS_Pr);
9753 
9754         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9755 
9756            if(SiS_IsNotM650orLater(SiS_Pr)) {
9757 
9758               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9759 	         /* Always use the second pointer on 650; some BIOSes */
9760                  /* still carry old 301 data at the first location    */
9761 	         /* romptr = SISGETROMW(0x120);                       */
9762 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
9763 	         romptr = SISGETROMW(0x122);
9764 	         if(!romptr) return;
9765 	         delay = ROMAddr[(romptr + index)];
9766 	      } else {
9767                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9768 	      }
9769 
9770           } else {
9771 
9772              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9773 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9774 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9775 
9776           }
9777 
9778         } else if(SiS_Pr->SiS_UseROM 			      &&
9779 		  (!(SiS_Pr->SiS_ROMNew))		      &&
9780 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9781 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
9782 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
9783 		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
9784 		  ((romptr = GetLCDromptr(SiS_Pr)))) {
9785 
9786 	   /* Data for 1280x1024 wrong in 301B BIOS */
9787 	   /* Data for 1600x1200 wrong in 301C BIOS */
9788 	   delay = ROMAddr[(romptr + index)];
9789 
9790         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9791 
9792 	   if(IS_SIS740) delay = 0x03;
9793 	   else          delay = 0x00;
9794 
9795 	} else {
9796 
9797            delay = SiS310_LCDDelayCompensation_301[myindex];
9798 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9799 	      if(IS_SIS740) delay = 0x01;
9800 	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9801 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9802 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9803 	      if(IS_SIS740) delay = 0x01;  /* ? */
9804 	      else          delay = 0x03;
9805 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9806 	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9807 	      if(IS_SIS740) delay = 0x01;
9808 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9809 	   }
9810 
9811         }
9812 
9813      }  /* got it from PCI */
9814 
9815      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9816 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9817 	dochiptest = false;
9818      }
9819 
9820   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
9821 
9822      index = GetTVPtrIndex(SiS_Pr);
9823 
9824      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9825 
9826         if(SiS_IsNotM650orLater(SiS_Pr)) {
9827 
9828            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9829 	      /* Always use the second pointer on 650; some BIOSes */
9830               /* still carry old 301 data at the first location    */
9831               /* romptr = SISGETROMW(0x114);			   */
9832 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
9833 	      romptr = SISGETROMW(0x11a);
9834 	      if(!romptr) return;
9835 	      delay = ROMAddr[romptr + index];
9836 
9837 	   } else {
9838 
9839 	      delay = SiS310_TVDelayCompensation_301B[index];
9840 
9841 	   }
9842 
9843         } else {
9844 
9845            switch(SiS_Pr->SiS_CustomT) {
9846 	   case CUT_COMPAQ1280:
9847 	   case CUT_COMPAQ12802:
9848 	   case CUT_CLEVO1400:
9849 	   case CUT_CLEVO14002:
9850 	      delay = 0x02;
9851 	      dochiptest = false;
9852 	      break;
9853 	   case CUT_CLEVO1024:
9854 	   case CUT_CLEVO10242:
9855 	      delay = 0x03;
9856 	      dochiptest = false;
9857    	      break;
9858 	   default:
9859               delay = SiS310_TVDelayCompensation_651301LV[index];
9860 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9861 	         delay = SiS310_TVDelayCompensation_651302LV[index];
9862 	      }
9863 	   }
9864         }
9865 
9866      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9867 
9868         romptr = GetTVromptr(SiS_Pr);
9869 	if(!romptr) return;
9870 	delay = ROMAddr[romptr + index];
9871 
9872      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9873 
9874         delay = SiS310_TVDelayCompensation_LVDS[index];
9875 
9876      } else {
9877 
9878 	delay = SiS310_TVDelayCompensation_301[index];
9879         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9880 	   if(IS_SIS740) {
9881 	      delay = SiS310_TVDelayCompensation_740301B[index];
9882 	      /* LV: use 301 data? BIOS bug? */
9883 	   } else {
9884               delay = SiS310_TVDelayCompensation_301B[index];
9885 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9886 	   }
9887 	}
9888 
9889      }
9890 
9891      if(SiS_LCDAEnabled(SiS_Pr)) {
9892 	delay &= 0x0f;
9893 	dochiptest = false;
9894      }
9895 
9896   } else return;
9897 
9898   /* Write delay */
9899 
9900   if(SiS_Pr->SiS_VBType & VB_SISVB) {
9901 
9902      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9903 
9904         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9905         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
9906 	   delay &= 0x0f;
9907 	   delay |= 0xb0;
9908         } else if(temp == 6) {
9909            delay &= 0x0f;
9910 	   delay |= 0xc0;
9911         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
9912 	   delay = 0x35;
9913         }
9914         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9915 
9916      } else {
9917 
9918         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9919 
9920      }
9921 
9922   } else {  /* LVDS */
9923 
9924      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9925         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9926      } else {
9927         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9928            delay <<= 4;
9929            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9930         } else {
9931            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9932         }
9933      }
9934 
9935   }
9936 
9937 }
9938 
9939 static void
9940 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9941 {
9942   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9943   unsigned short index,temp,temp1,romptr=0;
9944 
9945   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9946 
9947   if(ModeNo<=0x13)
9948      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9949   else
9950      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9951 
9952   temp = GetTVPtrIndex(SiS_Pr);
9953   temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9954   temp1 = temp;
9955 
9956   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9957      if(SiS_Pr->ChipType >= SIS_661) {
9958         temp1 = GetOEMTVPtr661(SiS_Pr);
9959         temp1 >>= 1;
9960         romptr = SISGETROMW(0x260);
9961         if(SiS_Pr->ChipType >= SIS_760) {
9962 	   romptr = SISGETROMW(0x360);
9963 	}
9964      } else if(SiS_Pr->ChipType >= SIS_330) {
9965         romptr = SISGETROMW(0x192);
9966      } else {
9967         romptr = SISGETROMW(0x112);
9968      }
9969   }
9970 
9971   if(romptr) {
9972      temp1 <<= 1;
9973      temp = ROMAddr[romptr + temp1 + index];
9974   } else {
9975      temp = SiS310_TVAntiFlick1[temp][index];
9976   }
9977   temp <<= 4;
9978 
9979   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
9980 }
9981 
9982 static void
9983 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
9984 {
9985   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9986   unsigned short index,temp,temp1,romptr=0;
9987 
9988   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9989 
9990   if(ModeNo <= 0x13)
9991      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
9992   else
9993      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
9994 
9995   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9996      if(SiS_Pr->ChipType >= SIS_661) {
9997         romptr = SISGETROMW(0x26c);
9998         if(SiS_Pr->ChipType >= SIS_760) {
9999 	   romptr = SISGETROMW(0x36c);
10000 	}
10001 	temp1 = GetOEMTVPtr661(SiS_Pr);
10002         temp1 >>= 1;
10003      } else if(SiS_Pr->ChipType >= SIS_330) {
10004         romptr = SISGETROMW(0x1a4);
10005      } else {
10006         romptr = SISGETROMW(0x124);
10007      }
10008   }
10009 
10010   if(romptr) {
10011      temp1 <<= 1;
10012      temp = ROMAddr[romptr + temp1 + index];
10013   } else {
10014      temp = SiS310_TVEdge1[temp][index];
10015   }
10016   temp <<= 5;
10017   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10018 }
10019 
10020 static void
10021 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10022 {
10023   unsigned short index, temp, i, j;
10024 
10025   if(ModeNo <= 0x13) {
10026      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10027   } else {
10028      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10029   }
10030 
10031   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10032 
10033   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10034   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10035   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10036   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10037 
10038   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10039      for(i=0x35, j=0; i<=0x38; i++, j++) {
10040         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10041      }
10042      for(i=0x48; i<=0x4A; i++, j++) {
10043         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10044      }
10045   } else {
10046      for(i=0x35, j=0; i<=0x38; i++, j++) {
10047         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10048      }
10049   }
10050 }
10051 
10052 static void
10053 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10054 {
10055   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10056   unsigned short index,temp,i,j,resinfo,romptr=0;
10057   unsigned int  lindex;
10058 
10059   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10060 
10061   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10062   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10063 
10064   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10065      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10066      lindex <<= 2;
10067      for(j=0, i=0x31; i<=0x34; i++, j++) {
10068         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10069      }
10070      return;
10071   }
10072 
10073   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10074   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10075 
10076   if(ModeNo<=0x13) {
10077      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10078   } else {
10079      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10080   }
10081 
10082   temp = GetTVPtrIndex(SiS_Pr);
10083   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10084    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10085    */
10086   if(SiS_Pr->SiS_UseROM) {
10087      romptr = SISGETROMW(0x116);
10088      if(SiS_Pr->ChipType >= SIS_330) {
10089         romptr = SISGETROMW(0x196);
10090      }
10091      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10092         romptr = SISGETROMW(0x11c);
10093 	if(SiS_Pr->ChipType >= SIS_330) {
10094 	   romptr = SISGETROMW(0x19c);
10095 	}
10096 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10097 	   romptr = SISGETROMW(0x116);
10098 	   if(SiS_Pr->ChipType >= SIS_330) {
10099               romptr = SISGETROMW(0x196);
10100            }
10101 	}
10102      }
10103   }
10104   if(romptr) {
10105      romptr += (temp << 2);
10106      for(j=0, i=0x31; i<=0x34; i++, j++) {
10107         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10108      }
10109   } else {
10110      index = temp % 2;
10111      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10112      for(j=0, i=0x31; i<=0x34; i++, j++) {
10113         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10114 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10115         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10116            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10117         else
10118            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10119      }
10120   }
10121 
10122   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10123      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10124         if((resinfo == SIS_RI_640x480) ||
10125 	   (resinfo == SIS_RI_800x600)) {
10126 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10127 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10128 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10129 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10130 	} else if(resinfo == SIS_RI_1024x768) {
10131 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10132 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10133 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10134 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10135 	}
10136      }
10137   }
10138 }
10139 
10140 static void
10141 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10142                 unsigned short ModeIdIndex, unsigned short RTI)
10143 {
10144    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10145    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10146 
10147    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10148       return;
10149 
10150    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10151    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10152 
10153    if(SiS_Pr->SiS_ROMNew) {
10154       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10155          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10156 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10157          index = 25;
10158          if(SiS_Pr->UseCustomMode) {
10159 	    index = SiS_Pr->CSRClock;
10160          } else if(ModeNo > 0x13) {
10161             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10162             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10163          }
10164 	 if(index < 25) index = 25;
10165          index = ((index / 25) - 1) << 1;
10166          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10167 	    index++;
10168 	 }
10169 	 romptr = SISGETROMW(0x104);
10170          delay = ROMAddr[romptr + index];
10171          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10172             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10173             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10174          } else {
10175             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10176 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10177          }
10178          return;
10179       }
10180    }
10181 
10182    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10183 
10184    if(SiS_Pr->UseCustomMode) delay = 0x04;
10185    else if(ModeNo <= 0x13)   delay = 0x04;
10186    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10187    delay |= (delay << 8);
10188 
10189    if(SiS_Pr->ChipType >= XGI_20) {
10190 
10191       delay = 0x0606;
10192       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10193 
10194 	 delay = 0x0404;
10195          if(SiS_Pr->SiS_XGIROM) {
10196 	     index = GetTVPtrIndex(SiS_Pr);
10197 	     if((romptr = SISGETROMW(0x35e))) {
10198 	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10199 		delay |= (delay << 8);
10200 	     }
10201 	 }
10202 
10203 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10204 	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10205 	       delay -= 0x0404;
10206 	    }
10207 	 }
10208       }
10209 
10210    } else if(SiS_Pr->ChipType >= SIS_340) {
10211 
10212       delay = 0x0606;
10213       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10214          delay = 0x0404;
10215       }
10216       /* TODO (eventually) */
10217 
10218    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10219 
10220       /* 3. TV */
10221 
10222       index = GetOEMTVPtr661(SiS_Pr);
10223       if(SiS_Pr->SiS_ROMNew) {
10224          romptr = SISGETROMW(0x106);
10225 	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10226          delay = ROMAddr[romptr + index];
10227       } else {
10228          delay = 0x04;
10229 	 if(index > 3) delay = 0;
10230       }
10231 
10232    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10233 
10234       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10235 
10236       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10237           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10238 
10239 	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10240 
10241 	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10242 	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10243 	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10244 
10245       } else {
10246 
10247          /* TMDS: Set our own, since BIOS has no idea */
10248 	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10249          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10250 	    switch(SiS_Pr->SiS_LCDResInfo) {
10251 	    case Panel_1024x768:  delay = 0x0008; break;
10252 	    case Panel_1280x720:  delay = 0x0004; break;
10253 	    case Panel_1280x768:
10254 	    case Panel_1280x768_2:delay = 0x0004; break;
10255 	    case Panel_1280x800:
10256 	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10257 	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10258 	    case Panel_1280x1024: delay = 0x1e04; break;
10259 	    case Panel_1400x1050: delay = 0x0004; break;
10260 	    case Panel_1600x1200: delay = 0x0400; break;
10261 	    case Panel_1680x1050: delay = 0x0e04; break;
10262 	    default:
10263                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10264 	          delay = 0x0008;
10265 	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10266 	          delay = 0x1e04;
10267                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10268 	          delay = 0x0004;
10269 	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10270 	          delay = 0x0400;
10271                } else
10272 	          delay = 0x0e04;
10273 	       break;
10274 	    }
10275          }
10276 
10277 	 /* Override by detected or user-set values */
10278 	 /* (but only if, for some reason, we can't read value from BIOS) */
10279          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10280             delay = SiS_Pr->PDC & 0x1f;
10281          }
10282          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10283             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10284          }
10285 
10286       }
10287 
10288    }
10289 
10290    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10291       delay >>= 8;
10292       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10293       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10294    } else {
10295       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10296       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10297    }
10298 }
10299 
10300 static void
10301 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10302 {
10303    unsigned short infoflag;
10304    unsigned char  temp;
10305 
10306    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10307 
10308       if(ModeNo <= 0x13) {
10309          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10310       } else if(SiS_Pr->UseCustomMode) {
10311          infoflag = SiS_Pr->CInfoFlag;
10312       } else {
10313          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10314       }
10315 
10316       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10317          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10318       }
10319 
10320       infoflag &= 0xc0;
10321 
10322       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10323          temp = (infoflag >> 6) | 0x0c;
10324          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10325 	    temp ^= 0x04;
10326 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10327 	 }
10328          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10329       } else {
10330          temp = 0x30;
10331          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10332          temp |= infoflag;
10333          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10334          temp = 0;
10335          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10336 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10337 	 }
10338          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10339       }
10340 
10341    }
10342 }
10343 
10344 static void
10345 SetPanelParms661(struct SiS_Private *SiS_Pr)
10346 {
10347    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10348    unsigned short romptr, temp1, temp2;
10349 
10350    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10351       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10352    }
10353 
10354    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10355       if(SiS_Pr->LVDSHL != -1) {
10356          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10357       }
10358    }
10359 
10360    if(SiS_Pr->SiS_ROMNew) {
10361 
10362       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10363          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10364             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10365 	    temp2 = 0xfc;
10366 	    if(SiS_Pr->LVDSHL != -1) {
10367 	      temp1 &= 0xfc;
10368 	      temp2 = 0xf3;
10369 	    }
10370 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10371          }
10372 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10373             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10374             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10375 	 }
10376       }
10377 
10378    }
10379 }
10380 
10381 static void
10382 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10383 {
10384    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10385       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10386       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10387          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10388          SetPanelParms661(SiS_Pr);
10389       }
10390    } else {
10391       SetDelayComp(SiS_Pr,ModeNo);
10392    }
10393 
10394    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10395       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10396       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10397       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10398       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10399          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10400       }
10401    }
10402 }
10403 
10404 static void
10405 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10406 			unsigned short ModeIdIndex, unsigned short RRTI)
10407 {
10408    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10409 
10410       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10411 
10412       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10413          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10414          SetPanelParms661(SiS_Pr);
10415       }
10416 
10417       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10418          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10419          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10420          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10421          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10422             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10423          }
10424       }
10425    }
10426 }
10427 
10428 /* FinalizeLCD
10429  * This finalizes some CRT2 registers for the very panel used.
10430  * If we have a backup if these registers, we use it; otherwise
10431  * we set the register according to most BIOSes. However, this
10432  * function looks quite different in every BIOS, so you better
10433  * pray that we have a backup...
10434  */
10435 static void
10436 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10437 {
10438   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10439   unsigned short resinfo,modeflag;
10440 
10441   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10442   if(SiS_Pr->SiS_ROMNew) return;
10443 
10444   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10445      if(SiS_Pr->LVDSHL != -1) {
10446         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10447      }
10448   }
10449 
10450   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10451   if(SiS_Pr->UseCustomMode) return;
10452 
10453   switch(SiS_Pr->SiS_CustomT) {
10454   case CUT_COMPAQ1280:
10455   case CUT_COMPAQ12802:
10456   case CUT_CLEVO1400:
10457   case CUT_CLEVO14002:
10458      return;
10459   }
10460 
10461   if(ModeNo <= 0x13) {
10462      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10463      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10464   } else {
10465      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10466      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10467   }
10468 
10469   if(IS_SIS650) {
10470      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10471         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10472 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10473 	} else {
10474            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10475 	}
10476      }
10477   }
10478 
10479   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10480      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10481         /* Maybe all panels? */
10482         if(SiS_Pr->LVDSHL == -1) {
10483            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10484 	}
10485 	return;
10486      }
10487   }
10488 
10489   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10490      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10491         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10492 	   if(SiS_Pr->LVDSHL == -1) {
10493 	      /* Maybe all panels? */
10494               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10495 	   }
10496 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10497 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10498 	      if(tempch == 3) {
10499 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10500 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10501 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10502 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10503 	      }
10504 	   }
10505 	   return;
10506 	}
10507      }
10508   }
10509 
10510   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10511      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10512 	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10513 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10514 #ifdef SET_EMI
10515 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10516 #endif
10517 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10518 	}
10519      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10520         if(SiS_Pr->LVDSHL == -1) {
10521            /* Maybe ACER only? */
10522            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10523 	}
10524      }
10525      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10526      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10527 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10528 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10529 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10530 	   if(tempch == 0x03) {
10531 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10532 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10533 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10534 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10535 	   }
10536 	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10537 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10538 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10539 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10540 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10541 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10542 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10543 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10544 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10545 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10546 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10547 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10548 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10549 	      if(ModeNo <= 0x13) {
10550 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10551 		 if((resinfo == 0) || (resinfo == 2)) return;
10552 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10553 		 if((resinfo == 1) || (resinfo == 3)) return;
10554 	      }
10555 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10556 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10557 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10558 #if 0
10559 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10560 		 tempbx--;
10561 		 temp = tempbx & 0xff;
10562 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10563 		 temp = (tempbx >> 8) & 0x03;
10564 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10565 #endif
10566 	      }
10567 	   } else if(ModeNo <= 0x13) {
10568 	      if(ModeNo <= 1) {
10569 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10570 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10571 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10572 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10573 	      }
10574 	      if(!(modeflag & HalfDCLK)) {
10575 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10576 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10577 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10578 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10579 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10580 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10581 		 if(ModeNo == 0x12) {
10582 		    switch(tempch) {
10583 		       case 0:
10584 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10585 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10586 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10587 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10588 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10589 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10590 			  break;
10591 		       case 2:
10592 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10593 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10594 			  break;
10595 		       case 3:
10596 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10597 			  break;
10598 		    }
10599 		 }
10600 	      }
10601 	   }
10602 	}
10603      } else {
10604         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10605 	tempcl &= 0x0f;
10606 	tempbh &= 0x70;
10607 	tempbh >>= 4;
10608 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10609 	tempbx = (tempbh << 8) | tempbl;
10610 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10611 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10612 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10613 	      	 tempbx = 770;
10614 	      } else {
10615 	         if(tempbx > 770) tempbx = 770;
10616 		 if(SiS_Pr->SiS_VGAVDE < 600) {
10617 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10618 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10619 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10620 		    tempbx -= tempax;
10621 		 }
10622 	      }
10623 	   } else return;
10624 	}
10625 	temp = tempbx & 0xff;
10626 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10627 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10628 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10629      }
10630   }
10631 }
10632 
10633 #endif
10634 
10635 /*  =================  SiS 300 O.E.M. ================== */
10636 
10637 #ifdef CONFIG_FB_SIS_300
10638 
10639 static void
10640 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10641 		unsigned short RefTabIndex)
10642 {
10643   unsigned short crt2crtc=0, modeflag, myindex=0;
10644   unsigned char  temp;
10645   int i;
10646 
10647   if(ModeNo <= 0x13) {
10648      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10649      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10650   } else {
10651      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10652      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10653   }
10654 
10655   crt2crtc &= 0x3f;
10656 
10657   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10658      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10659   }
10660 
10661   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10662      if(modeflag & HalfDCLK) myindex = 1;
10663 
10664      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10665         for(i=0; i<7; i++) {
10666            if(barco_p1[myindex][crt2crtc][i][0]) {
10667 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10668 	                      barco_p1[myindex][crt2crtc][i][0],
10669 	   	   	      barco_p1[myindex][crt2crtc][i][2],
10670 			      barco_p1[myindex][crt2crtc][i][1]);
10671 	   }
10672         }
10673      }
10674      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10675      if(temp & 0x80) {
10676         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10677         temp++;
10678         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10679      }
10680   }
10681 }
10682 
10683 static unsigned short
10684 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10685 {
10686   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10687   unsigned short tempbx=0,romptr=0;
10688   static const unsigned char customtable300[] = {
10689 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10690 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10691   };
10692   static const unsigned char customtable630[] = {
10693 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10694 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10695   };
10696 
10697   if(SiS_Pr->ChipType == SIS_300) {
10698 
10699     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10700     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10701     tempbx -= 2;
10702     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10703     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10704        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10705     }
10706     if(SiS_Pr->SiS_UseROM) {
10707        if(ROMAddr[0x235] & 0x80) {
10708           tempbx = SiS_Pr->SiS_LCDTypeInfo;
10709           if(Flag) {
10710 	     romptr = SISGETROMW(0x255);
10711 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10712 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10713              if(tempbx == 0xFF) return 0xFFFF;
10714           }
10715 	  tempbx <<= 1;
10716 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10717        }
10718     }
10719 
10720   } else {
10721 
10722     if(Flag) {
10723        if(SiS_Pr->SiS_UseROM) {
10724           romptr = SISGETROMW(0x255);
10725 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10726 	  else 	     tempbx = 0xff;
10727        } else {
10728           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10729        }
10730        if(tempbx == 0xFF) return 0xFFFF;
10731        tempbx <<= 2;
10732        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10733        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10734        return tempbx;
10735     }
10736     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10737     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10738     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10739 
10740   }
10741 
10742   return tempbx;
10743 }
10744 
10745 static void
10746 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10747 {
10748   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10749   unsigned short index,temp,romptr=0;
10750 
10751   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10752 
10753   if(SiS_Pr->SiS_UseROM) {
10754      if(!(ROMAddr[0x237] & 0x01)) return;
10755      if(!(ROMAddr[0x237] & 0x02)) return;
10756      romptr = SISGETROMW(0x24b);
10757   }
10758 
10759   /* The Panel Compensation Delay should be set according to tables
10760    * here. Unfortunately, various BIOS versions don't care about
10761    * a uniform way using eg. ROM byte 0x220, but use different
10762    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10763    * Thus we don't set this if the user selected a custom pdc or if
10764    * we otherwise detected a valid pdc.
10765    */
10766   if(SiS_Pr->PDC != -1) return;
10767 
10768   temp = GetOEMLCDPtr(SiS_Pr, 0);
10769 
10770   if(SiS_Pr->UseCustomMode)
10771      index = 0;
10772   else
10773      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10774 
10775   if(SiS_Pr->ChipType != SIS_300) {
10776      if(romptr) {
10777 	romptr += (temp * 2);
10778 	romptr = SISGETROMW(romptr);
10779 	romptr += index;
10780 	temp = ROMAddr[romptr];
10781      } else {
10782 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
10783     	   temp = SiS300_OEMLCDDelay2[temp][index];
10784 	} else {
10785            temp = SiS300_OEMLCDDelay3[temp][index];
10786         }
10787      }
10788   } else {
10789      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10790 	if(romptr) {
10791 	   romptr += (temp * 2);
10792 	   romptr = SISGETROMW(romptr);
10793 	   romptr += index;
10794 	   temp = ROMAddr[romptr];
10795 	} else {
10796 	   temp = SiS300_OEMLCDDelay5[temp][index];
10797 	}
10798      } else {
10799         if(SiS_Pr->SiS_UseROM) {
10800 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10801 	   if(romptr) {
10802 	      romptr += (temp * 2);
10803 	      romptr = SISGETROMW(romptr);
10804 	      romptr += index;
10805 	      temp = ROMAddr[romptr];
10806 	   } else {
10807 	      temp = SiS300_OEMLCDDelay4[temp][index];
10808 	   }
10809 	} else {
10810 	   temp = SiS300_OEMLCDDelay4[temp][index];
10811 	}
10812      }
10813   }
10814   temp &= 0x3c;
10815   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
10816 }
10817 
10818 static void
10819 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10820 {
10821 #if 0  /* Unfinished; Data table missing */
10822   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10823   unsigned short index,temp;
10824 
10825   if((SiS_Pr->SiS_UseROM) {
10826      if(!(ROMAddr[0x237] & 0x01)) return;
10827      if(!(ROMAddr[0x237] & 0x04)) return;
10828      /* No rom pointer in BIOS header! */
10829   }
10830 
10831   temp = GetOEMLCDPtr(SiS_Pr, 1);
10832   if(temp == 0xFFFF) return;
10833 
10834   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10835   for(i=0x14, j=0; i<=0x17; i++, j++) {
10836       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10837   }
10838   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10839 
10840   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10841   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10842   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10843   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10844   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10845       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10846   }
10847 #endif
10848 }
10849 
10850 static unsigned short
10851 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10852 {
10853   unsigned short index;
10854 
10855   index = 0;
10856   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
10857   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10858      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
10859      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10860      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
10861   } else {
10862      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10863      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
10864   }
10865   return index;
10866 }
10867 
10868 static void
10869 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10870 {
10871   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10872   unsigned short index,temp,romptr=0;
10873 
10874   if(SiS_Pr->SiS_UseROM) {
10875      if(!(ROMAddr[0x238] & 0x01)) return;
10876      if(!(ROMAddr[0x238] & 0x02)) return;
10877      romptr = SISGETROMW(0x241);
10878   }
10879 
10880   temp = GetOEMTVPtr(SiS_Pr);
10881 
10882   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10883 
10884   if(romptr) {
10885      romptr += (temp * 2);
10886      romptr = SISGETROMW(romptr);
10887      romptr += index;
10888      temp = ROMAddr[romptr];
10889   } else {
10890      if(SiS_Pr->SiS_VBType & VB_SISVB) {
10891         temp = SiS300_OEMTVDelay301[temp][index];
10892      } else {
10893         temp = SiS300_OEMTVDelayLVDS[temp][index];
10894      }
10895   }
10896   temp &= 0x3c;
10897   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10898 }
10899 
10900 static void
10901 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10902 {
10903   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10904   unsigned short index,temp,romptr=0;
10905 
10906   if(SiS_Pr->SiS_UseROM) {
10907      if(!(ROMAddr[0x238] & 0x01)) return;
10908      if(!(ROMAddr[0x238] & 0x04)) return;
10909      romptr = SISGETROMW(0x243);
10910   }
10911 
10912   temp = GetOEMTVPtr(SiS_Pr);
10913 
10914   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10915 
10916   if(romptr) {
10917      romptr += (temp * 2);
10918      romptr = SISGETROMW(romptr);
10919      romptr += index;
10920      temp = ROMAddr[romptr];
10921   } else {
10922      temp = SiS300_OEMTVFlicker[temp][index];
10923   }
10924   temp &= 0x70;
10925   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10926 }
10927 
10928 static void
10929 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10930 {
10931   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10932   unsigned short index,i,j,temp,romptr=0;
10933 
10934   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10935 
10936   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10937 
10938   if(SiS_Pr->SiS_UseROM) {
10939      if(!(ROMAddr[0x238] & 0x01)) return;
10940      if(!(ROMAddr[0x238] & 0x08)) return;
10941      romptr = SISGETROMW(0x245);
10942   }
10943 
10944   temp = GetOEMTVPtr(SiS_Pr);
10945 
10946   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10947 
10948   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10949      for(i=0x31, j=0; i<=0x34; i++, j++) {
10950         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10951      }
10952   } else {
10953      if(romptr) {
10954         romptr += (temp * 2);
10955 	romptr = SISGETROMW(romptr);
10956 	romptr += (index * 4);
10957         for(i=0x31, j=0; i<=0x34; i++, j++) {
10958 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10959 	}
10960      } else {
10961         for(i=0x31, j=0; i<=0x34; i++, j++) {
10962            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
10963 	}
10964      }
10965   }
10966 }
10967 
10968 static void
10969 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10970 {
10971   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10972   unsigned short index,temp,i,j,romptr=0;
10973 
10974   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
10975 
10976   if(SiS_Pr->SiS_UseROM) {
10977      if(!(ROMAddr[0x238] & 0x01)) return;
10978      if(!(ROMAddr[0x238] & 0x10)) return;
10979      romptr = SISGETROMW(0x247);
10980   }
10981 
10982   temp = GetOEMTVPtr(SiS_Pr);
10983 
10984   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
10985   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
10986   /* NTSCJ uses NTSC filters */
10987 
10988   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
10989 
10990   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10991       for(i=0x35, j=0; i<=0x38; i++, j++) {
10992        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10993       }
10994       for(i=0x48; i<=0x4A; i++, j++) {
10995      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10996       }
10997   } else {
10998       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
10999          romptr += (temp * 2);
11000 	 romptr = SISGETROMW(romptr);
11001 	 romptr += (index * 4);
11002 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11003        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11004          }
11005       } else {
11006          for(i=0x35, j=0; i<=0x38; i++, j++) {
11007        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11008          }
11009       }
11010   }
11011 }
11012 
11013 static unsigned short
11014 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11015 {
11016    unsigned short ModeIdIndex;
11017    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11018 
11019    if(*ModeNo <= 5) *ModeNo |= 1;
11020 
11021    for(ModeIdIndex=0; ; ModeIdIndex++) {
11022       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11023       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11024    }
11025 
11026    if(*ModeNo != 0x07) {
11027       if(*ModeNo > 0x03) return ModeIdIndex;
11028       if(VGAINFO & 0x80) return ModeIdIndex;
11029       ModeIdIndex++;
11030    }
11031 
11032    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11033 	                               /* else 350 lines */
11034    return ModeIdIndex;
11035 }
11036 
11037 static void
11038 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11039 		  unsigned short RefTableIndex)
11040 {
11041   unsigned short OEMModeIdIndex = 0;
11042 
11043   if(!SiS_Pr->UseCustomMode) {
11044      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11045      if(!(OEMModeIdIndex)) return;
11046   }
11047 
11048   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11049      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11050      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11051         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11052      }
11053   }
11054   if(SiS_Pr->UseCustomMode) return;
11055   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11056      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11057      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11058         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11059     	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11060        	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11061      }
11062   }
11063 }
11064 #endif
11065 
11066