Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 #ifdef HAVE_CONFIG_H
 61 #include "config.h"
 62 #endif
 63 
 64 #if 1
 65 #define SET_EMI         /* 302LV/ELV: Set EMI values */
 66 #endif
 67 
 68 #if 1
 69 #define SET_PWD         /* 301/302LV: Set PWD */
 70 #endif
 71 
 72 #define COMPAL_HACK     /* Needed for Compal 1400x1050 (EMI) */
 73 #define COMPAQ_HACK     /* Needed for Inventec/Compaq 1280x1024 (EMI) */
 74 #define ASUS_HACK       /* Needed for Asus A2H 1024x768 (EMI) */
 75 
 76 #include "init301.h"
 77 
 78 #ifdef SIS300
 79 #include "oem300.h"
 80 #endif
 81 
 82 #ifdef SIS315H
 83 #include "oem310.h"
 84 #endif
 85 
 86 #define SiS_I2CDELAY      1000
 87 #define SiS_I2CDELAYSHORT  150
 88 
 89 static unsigned short   SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
 90 #ifdef SIS_LINUX_KERNEL
 91 static void             SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
 92 #endif
 93 
 94 /*********************************************/
 95 /*         HELPER: Lock/Unlock CRT2          */
 96 /*********************************************/
 97 
 98 void
 99 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
100 {
101    if(SiS_Pr->ChipType == XGI_20)
102       return;
103    else if(SiS_Pr->ChipType >= SIS_315H)
104       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
105    else
106       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
107 }
108 
109 #ifdef SIS_LINUX_KERNEL
110 static
111 #endif
112 void
113 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
114 {
115    if(SiS_Pr->ChipType == XGI_20)
116       return;
117    else if(SiS_Pr->ChipType >= SIS_315H)
118       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
119    else
120       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
121 }
122 
123 /*********************************************/
124 /*            HELPER: Write SR11             */
125 /*********************************************/
126 
127 static void
128 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
129 {
130    if(SiS_Pr->ChipType >= SIS_661) {
131       DataAND &= 0x0f;
132       DataOR  &= 0x0f;
133    }
134    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
135 }
136 
137 /*********************************************/
138 /*    HELPER: Get Pointer to LCD structure   */
139 /*********************************************/
140 
141 #ifdef SIS315H
142 static unsigned char *
143 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
144 {
145    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
146    unsigned char  *myptr = NULL;
147    unsigned short romindex = 0, reg = 0, idx = 0;
148 
149    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
150     * due to the variaty of panels the BIOS doesn't know about.
151     * Exception: If the BIOS has better knowledge (such as in case
152     * of machines with a 301C and a panel that does not support DDC)
153     * use the BIOS data as well.
154     */
155 
156    if((SiS_Pr->SiS_ROMNew) &&
157       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
158 
159       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
160       else                           reg = 0x7d;
161 
162       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
163 
164       if(idx < (8*26)) {
165          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
166       }
167       romindex = SISGETROMW(0x100);
168       if(romindex) {
169          romindex += idx;
170          myptr = &ROMAddr[romindex];
171       }
172    }
173    return myptr;
174 }
175 
176 static unsigned short
177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
178 {
179    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
180    unsigned short romptr = 0;
181 
182    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183     * due to the variaty of panels the BIOS doesn't know about.
184     * Exception: If the BIOS has better knowledge (such as in case
185     * of machines with a 301C and a panel that does not support DDC)
186     * use the BIOS data as well.
187     */
188 
189    if((SiS_Pr->SiS_ROMNew) &&
190       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
191       romptr = SISGETROMW(0x102);
192       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
193    }
194 
195    return romptr;
196 }
197 #endif
198 
199 /*********************************************/
200 /*           Adjust Rate for CRT2            */
201 /*********************************************/
202 
203 static bool
204 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
205                 unsigned short RRTI, unsigned short *i)
206 {
207    unsigned short checkmask=0, modeid, infoflag;
208 
209    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
210 
211    if(SiS_Pr->SiS_VBType & VB_SISVB) {
212 
213       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
214 
215          checkmask |= SupportRAMDAC2;
216          if(SiS_Pr->ChipType >= SIS_315H) {
217             checkmask |= SupportRAMDAC2_135;
218             if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
219                checkmask |= SupportRAMDAC2_162;
220                if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
221                   checkmask |= SupportRAMDAC2_202;
222                }
223             }
224          }
225 
226       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
227 
228          checkmask |= SupportLCD;
229          if(SiS_Pr->ChipType >= SIS_315H) {
230             if(SiS_Pr->SiS_VBType & VB_SISVB) {
231                if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
232                   if(modeid == 0x2e) checkmask |= Support64048060Hz;
233                }
234             }
235          }
236 
237       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
238 
239          checkmask |= SupportHiVision;
240 
241       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
242 
243          checkmask |= SupportTV;
244          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
245             checkmask |= SupportTV1024;
246             if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
247                if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
248                   checkmask |= SupportYPbPr750p;
249                }
250             }
251          }
252 
253       }
254 
255    } else {     /* LVDS */
256 
257       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
258          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
259             checkmask |= SupportCHTV;
260          }
261       }
262 
263       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
264          checkmask |= SupportLCD;
265       }
266 
267    }
268 
269    /* Look backwards in table for matching CRT2 mode */
270    for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
271       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272       if(infoflag & checkmask) return true;
273       if((*i) == 0) break;
274    }
275 
276    /* Look through the whole mode-section of the table from the beginning
277     * for a matching CRT2 mode if no mode was found yet.
278     */
279    for((*i) = 0; ; (*i)++) {
280       if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
281       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
282       if(infoflag & checkmask) return true;
283    }
284    return false;
285 }
286 
287 /*********************************************/
288 /*              Get rate index               */
289 /*********************************************/
290 
291 unsigned short
292 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
293 {
294    unsigned short RRTI,i,backup_i;
295    unsigned short modeflag,index,temp,backupindex;
296    static const unsigned short LCDRefreshIndex[] = {
297                 0x00, 0x00, 0x01, 0x01,
298                 0x01, 0x01, 0x01, 0x01,
299                 0x01, 0x01, 0x01, 0x01,
300                 0x01, 0x01, 0x01, 0x01,
301                 0x00, 0x00, 0x00, 0x00
302    };
303 
304    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
305    if(ModeNo == 0xfe) return 0;
306 
307    if(ModeNo <= 0x13) {
308       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
309    } else {
310       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
311    }
312 
313    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
314       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
315          if(modeflag & HalfDCLK) return 0;
316       }
317    }
318 
319    if(ModeNo < 0x14) return 0xFFFF;
320 
321    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
322    backupindex = index;
323 
324    if(index > 0) index--;
325 
326    if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
327       if(SiS_Pr->SiS_VBType & VB_SISVB) {
328          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
329             if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
330             else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
331          }
332          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
333             if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
334                temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
335                if(index > temp) index = temp;
336             }
337          }
338       } else {
339          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
340          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
341             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
342          }
343       }
344    }
345 
346    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
347    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
348 
349    if(SiS_Pr->ChipType >= SIS_315H) {
350       if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
351          if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
352              (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
353             if(backupindex <= 1) RRTI++;
354          }
355       }
356    }
357 
358    i = 0;
359    do {
360       if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
361       temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
362       temp &= ModeTypeMask;
363       if(temp < SiS_Pr->SiS_ModeType) break;
364       i++;
365       index--;
366    } while(index != 0xFFFF);
367 
368    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
369       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
370          temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
371          if(temp & InterlaceMode) i++;
372       }
373    }
374 
375    i--;
376 
377    if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
378       backup_i = i;
379       if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
380          i = backup_i;
381       }
382    }
383 
384    return (RRTI + i);
385 }
386 
387 /*********************************************/
388 /*            STORE CRT2 INFO in CR34        */
389 /*********************************************/
390 
391 static void
392 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
393 {
394    unsigned short temp1, temp2;
395 
396    /* Store CRT1 ModeNo in CR34 */
397    SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
398    temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
399    temp2 = ~(SetInSlaveMode >> 8);
400    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
401 }
402 
403 /*********************************************/
404 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
405 /*********************************************/
406 
407 #ifdef SIS300
408 static bool
409 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
410 {
411    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
412    unsigned short temp,temp1;
413 
414    if(SiS_Pr->SiS_UseROM) {
415       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
416          temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
417          temp1 = SISGETROMW(0x23b);
418          if(temp1 & temp) return true;
419       }
420    }
421    return false;
422 }
423 
424 static bool
425 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
426 {
427    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
428    unsigned short temp,temp1;
429 
430    if(SiS_Pr->SiS_UseROM) {
431       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
432          temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
433          temp1 = SISGETROMW(0x23d);
434          if(temp1 & temp) return true;
435       }
436    }
437    return false;
438 }
439 #endif
440 
441 /*********************************************/
442 /*          HELPER: DELAY FUNCTIONS          */
443 /*********************************************/
444 
445 void
446 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
447 {
448    while (delaytime-- > 0)
449       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
450 }
451 
452 #if defined(SIS300) || defined(SIS315H)
453 static void
454 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
455 {
456    SiS_DDC2Delay(SiS_Pr, delay * 36);
457 }
458 #endif
459 
460 #ifdef SIS315H
461 static void
462 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
463 {
464    while(delay--) {
465       SiS_GenericDelay(SiS_Pr, 6623);
466    }
467 }
468 #endif
469 
470 #if defined(SIS300) || defined(SIS315H)
471 static void
472 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
473 {
474    while(delay--) {
475       SiS_GenericDelay(SiS_Pr, 66);
476    }
477 }
478 #endif
479 
480 static void
481 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
482 {
483 #if defined(SIS300) || defined(SIS315H)
484    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
485    unsigned short PanelID, DelayIndex, Delay=0;
486 #endif
487 
488    if(SiS_Pr->ChipType < SIS_315H) {
489 
490 #ifdef SIS300
491 
492       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493       if(SiS_Pr->SiS_VBType & VB_SISVB) {
494          if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
495          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
496       }
497       DelayIndex = PanelID >> 4;
498       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
499          Delay = 3;
500       } else {
501          if(DelayTime >= 2) DelayTime -= 2;
502          if(!(DelayTime & 0x01)) {
503             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
504          } else {
505             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
506          }
507          if(SiS_Pr->SiS_UseROM) {
508             if(ROMAddr[0x220] & 0x40) {
509                if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
510                else                    Delay = (unsigned short)ROMAddr[0x226];
511             }
512          }
513       }
514       SiS_ShortDelay(SiS_Pr, Delay);
515 
516 #endif  /* SIS300 */
517 
518    } else {
519 
520 #ifdef SIS315H
521 
522       if((SiS_Pr->ChipType >= SIS_661)    ||
523          (SiS_Pr->ChipType <= SIS_315PRO) ||
524          (SiS_Pr->ChipType == SIS_330)    ||
525          (SiS_Pr->SiS_ROMNew)) {
526 
527          if(!(DelayTime & 0x01)) {
528             SiS_DDC2Delay(SiS_Pr, 0x1000);
529          } else {
530             SiS_DDC2Delay(SiS_Pr, 0x4000);
531          }
532 
533       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
534          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
535          (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {                  /* 315 series, LVDS; Special */
536 
537          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
538             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
539             if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
540                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
541             }
542             if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
543                DelayIndex = PanelID & 0x0f;
544             } else {
545                DelayIndex = PanelID >> 4;
546             }
547             if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
548                Delay = 3;
549             } else {
550                if(DelayTime >= 2) DelayTime -= 2;
551                if(!(DelayTime & 0x01)) {
552                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
553                 } else {
554                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
555                }
556                if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
557                   if(ROMAddr[0x13c] & 0x40) {
558                      if(!(DelayTime & 0x01)) {
559                         Delay = (unsigned short)ROMAddr[0x17e];
560                      } else {
561                         Delay = (unsigned short)ROMAddr[0x17f];
562                      }
563                   }
564                }
565             }
566             SiS_ShortDelay(SiS_Pr, Delay);
567          }
568 
569       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                        /* 315 series, all bridges */
570 
571          DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
572          if(!(DelayTime & 0x01)) {
573             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
574          } else {
575             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
576          }
577          Delay <<= 8;
578          SiS_DDC2Delay(SiS_Pr, Delay);
579 
580       }
581 
582 #endif /* SIS315H */
583 
584    }
585 }
586 
587 #ifdef SIS315H
588 static void
589 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
590 {
591    int i;
592    for(i = 0; i < DelayLoop; i++) {
593       SiS_PanelDelay(SiS_Pr, DelayTime);
594    }
595 }
596 #endif
597 
598 /*********************************************/
599 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
600 /*********************************************/
601 
602 void
603 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
604 {
605    unsigned short watchdog;
606 
607    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
608    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
609 
610    watchdog = 65535;
611    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
612    watchdog = 65535;
613    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
614 }
615 
616 #if defined(SIS300) || defined(SIS315H)
617 static void
618 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
619 {
620    unsigned short watchdog;
621 
622    watchdog = 65535;
623    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
624    watchdog = 65535;
625    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
626 }
627 #endif
628 
629 static void
630 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
631 {
632    if(SiS_Pr->ChipType < SIS_315H) {
633 #ifdef SIS300
634       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
635          if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
636       }
637       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
638          SiS_WaitRetrace1(SiS_Pr);
639       } else {
640          SiS_WaitRetrace2(SiS_Pr, 0x25);
641       }
642 #endif
643    } else {
644 #ifdef SIS315H
645       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
646          SiS_WaitRetrace1(SiS_Pr);
647       } else {
648          SiS_WaitRetrace2(SiS_Pr, 0x30);
649       }
650 #endif
651    }
652 }
653 
654 static void
655 SiS_VBWait(struct SiS_Private *SiS_Pr)
656 {
657    unsigned short tempal,temp,i,j;
658 
659    temp = 0;
660    for(i = 0; i < 3; i++) {
661      for(j = 0; j < 100; j++) {
662         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
663         if(temp & 0x01) {
664            if((tempal & 0x08))  continue;
665            else break;
666         } else {
667            if(!(tempal & 0x08)) continue;
668            else break;
669         }
670      }
671      temp ^= 0x01;
672    }
673 }
674 
675 static void
676 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
677 {
678    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
679       SiS_VBWait(SiS_Pr);
680    } else {
681       SiS_WaitRetrace1(SiS_Pr);
682    }
683 }
684 
685 /*********************************************/
686 /*               HELPER: MISC                */
687 /*********************************************/
688 
689 #ifdef SIS300
690 static bool
691 SiS_Is301B(struct SiS_Private *SiS_Pr)
692 {
693    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
694    return false;
695 }
696 #endif
697 
698 static bool
699 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
700 {
701    if(SiS_Pr->ChipType == SIS_730) {
702       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
703    }
704    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
705    return false;
706 }
707 
708 bool
709 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
710 {
711 #ifdef SIS315H
712    if(SiS_Pr->ChipType >= SIS_315H) {
713       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
714          if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
715       }
716    }
717 #endif
718    return false;
719 }
720 
721 bool
722 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
723 {
724 #ifdef SIS315H
725    unsigned short flag;
726 
727    if(SiS_Pr->ChipType >= SIS_315H) {
728       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
729       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
730    }
731 #endif
732    return false;
733 }
734 
735 #ifdef SIS315H
736 static bool
737 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
738 {
739    if(SiS_IsVAMode(SiS_Pr))  return true;
740    if(SiS_CRT2IsLCD(SiS_Pr)) return true;
741    return false;
742 }
743 #endif
744 
745 static bool
746 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
747 {
748 #ifdef SIS315H
749    if(SiS_Pr->ChipType >= SIS_315H) {
750       if((SiS_CRT2IsLCD(SiS_Pr)) ||
751          (SiS_IsVAMode(SiS_Pr))) {
752          if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
753       }
754    }
755 #endif
756    return false;
757 }
758 
759 #ifdef SIS315H
760 static bool
761 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
762 {
763    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
764    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
765       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
766    }
767    return false;
768 }
769 #endif
770 
771 #ifdef SIS315H
772 static bool
773 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
774 {
775    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
776    return false;
777 }
778 #endif
779 
780 #ifdef SIS315H
781 static bool
782 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
783 {
784    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
785       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
786    }
787    return false;
788 }
789 #endif
790 
791 #ifdef SIS315H
792 static bool
793 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
794 {
795    unsigned short flag;
796 
797    if(SiS_Pr->ChipType == SIS_650) {
798       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
799       /* Check for revision != A0 only */
800       if((flag == 0xe0) || (flag == 0xc0) ||
801          (flag == 0xb0) || (flag == 0x90)) return false;
802    } else if(SiS_Pr->ChipType >= SIS_661) return false;
803    return true;
804 }
805 #endif
806 
807 #ifdef SIS315H
808 static bool
809 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
810 {
811    if(SiS_Pr->ChipType >= SIS_315H) {
812       /* YPrPb = 0x08 */
813       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
814    }
815    return false;
816 }
817 #endif
818 
819 #ifdef SIS315H
820 static bool
821 SiS_IsChScart(struct SiS_Private *SiS_Pr)
822 {
823    if(SiS_Pr->ChipType >= SIS_315H) {
824       /* Scart = 0x04 */
825       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
826    }
827    return false;
828 }
829 #endif
830 
831 #ifdef SIS315H
832 static bool
833 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
834 {
835    unsigned short flag;
836 
837    if(SiS_Pr->ChipType >= SIS_315H) {
838       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
839       if(flag & SetCRT2ToTV)        return true;
840       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
841       if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
842       if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
843    } else {
844       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
845       if(flag & SetCRT2ToTV)        return true;
846    }
847    return false;
848 }
849 #endif
850 
851 #ifdef SIS315H
852 static bool
853 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
854 {
855    unsigned short flag;
856 
857    if(SiS_Pr->ChipType >= SIS_315H) {
858       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859       if(flag & SetCRT2ToLCD) return true;
860       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
861       if(flag & SetToLCDA)    return true;
862    } else {
863       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
864       if(flag & SetCRT2ToLCD) return true;
865    }
866    return false;
867 }
868 #endif
869 
870 static bool
871 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
872 {
873    unsigned short flag;
874 
875    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
876       return true;
877    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
878       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
879       if((flag == 1) || (flag == 2)) return true;
880    }
881    return false;
882 }
883 
884 static bool
885 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
886 {
887    unsigned short flag;
888 
889    if(SiS_HaveBridge(SiS_Pr)) {
890       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
891       if(SiS_Pr->ChipType < SIS_315H) {
892         flag &= 0xa0;
893         if((flag == 0x80) || (flag == 0x20)) return true;
894       } else {
895         flag &= 0x50;
896         if((flag == 0x40) || (flag == 0x10)) return true;
897       }
898    }
899    return false;
900 }
901 
902 static bool
903 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
904 {
905    unsigned short flag1;
906 
907    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
908    if(flag1 & (SetInSlaveMode >> 8)) return true;
909    return false;
910 }
911 
912 /*********************************************/
913 /*       GET VIDEO BRIDGE CONFIG INFO        */
914 /*********************************************/
915 
916 /* Setup general purpose IO for Chrontel communication */
917 #ifdef SIS300
918 void
919 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
920 {
921    unsigned int   acpibase;
922    unsigned short temp;
923 
924    if(!(SiS_Pr->SiS_ChSW)) return;
925 
926 #ifdef SIS_LINUX_KERNEL
927    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
928 #else
929    acpibase = pciReadLong(0x00000800, 0x74);
930 #endif
931    acpibase &= 0xFFFF;
932    if(!acpibase) return;
933    temp = SiS_GetRegShort((acpibase + 0x3c));   /* ACPI register 0x3c: GP Event 1 I/O mode select */
934    temp &= 0xFEFF;
935    SiS_SetRegShort((acpibase + 0x3c), temp);
936    temp = SiS_GetRegShort((acpibase + 0x3c));
937    temp = SiS_GetRegShort((acpibase + 0x3a));   /* ACPI register 0x3a: GP Pin Level (low/high) */
938    temp &= 0xFEFF;
939    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
940    SiS_SetRegShort((acpibase + 0x3a), temp);
941    temp = SiS_GetRegShort((acpibase + 0x3a));
942 }
943 #endif
944 
945 void
946 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
947                 unsigned short ModeIdIndex, int checkcrt2mode)
948 {
949    unsigned short tempax, tempbx, temp;
950    unsigned short modeflag, resinfo = 0;
951 
952    SiS_Pr->SiS_SetFlag = 0;
953 
954    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
955 
956    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
957 
958    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
959       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
960    }
961 
962    tempbx = 0;
963 
964    if(SiS_HaveBridge(SiS_Pr)) {
965 
966         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
967         tempbx |= temp;
968         tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
969         tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
970         tempbx |= tempax;
971 
972 #ifdef SIS315H
973         if(SiS_Pr->ChipType >= SIS_315H) {
974            if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
975               if(ModeNo == 0x03) {
976                  /* Mode 0x03 is never in driver mode */
977                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
978               }
979               if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
980                  /* Reset LCDA setting if not driver mode */
981                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
982               }
983               if(IS_SIS650) {
984                  if(SiS_Pr->SiS_UseLCDA) {
985                     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
986                        if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
987                           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
988                        }
989                     }
990                  }
991               }
992               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
993               if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
994                  tempbx |= SetCRT2ToLCDA;
995               }
996            }
997 
998            if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
999               tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1000               if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1001                  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1002                  if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1003                  else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1004                     tempbx |= SetCRT2ToYPbPr525750;
1005                  }
1006               }
1007            }
1008 
1009            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1010               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1011               if(temp & SetToLCDA) {
1012                  tempbx |= SetCRT2ToLCDA;
1013               }
1014               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1015                  if(temp & EnableCHYPbPr) {
1016                     tempbx |= SetCRT2ToCHYPbPr;
1017                  }
1018               }
1019            }
1020         }
1021 
1022 #endif  /* SIS315H */
1023 
1024         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1025            tempbx &= ~(SetCRT2ToRAMDAC);
1026         }
1027 
1028         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1029            temp = SetCRT2ToSVIDEO   |
1030                   SetCRT2ToAVIDEO   |
1031                   SetCRT2ToSCART    |
1032                   SetCRT2ToLCDA     |
1033                   SetCRT2ToLCD      |
1034                   SetCRT2ToRAMDAC   |
1035                   SetCRT2ToHiVision |
1036                   SetCRT2ToYPbPr525750;
1037         } else {
1038            if(SiS_Pr->ChipType >= SIS_315H) {
1039               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040                  temp = SetCRT2ToAVIDEO |
1041                         SetCRT2ToSVIDEO |
1042                         SetCRT2ToSCART  |
1043                         SetCRT2ToLCDA   |
1044                         SetCRT2ToLCD    |
1045                         SetCRT2ToCHYPbPr;
1046               } else {
1047                  temp = SetCRT2ToLCDA   |
1048                         SetCRT2ToLCD;
1049               }
1050            } else {
1051               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1052                  temp = SetCRT2ToTV | SetCRT2ToLCD;
1053               } else {
1054                  temp = SetCRT2ToLCD;
1055               }
1056            }
1057         }
1058 
1059         if(!(tempbx & temp)) {
1060            tempax = DisableCRT2Display;
1061            tempbx = 0;
1062         }
1063 
1064         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1065 
1066            unsigned short clearmask = ( DriverMode |
1067                                 DisableCRT2Display |
1068                                 LoadDACFlag        |
1069                                 SetNotSimuMode     |
1070                                 SetInSlaveMode     |
1071                                 SetPALTV           |
1072                                 SwitchCRT2         |
1073                                 SetSimuScanMode );
1074 
1075            if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1076            if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1077            if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1078            if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1079            if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1080            if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1081 
1082         } else {
1083 
1084            if(SiS_Pr->ChipType >= SIS_315H) {
1085               if(tempbx & SetCRT2ToLCDA) {
1086                  tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1087               }
1088            }
1089            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1090               if(tempbx & SetCRT2ToTV) {
1091                  tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1092               }
1093            }
1094            if(tempbx & SetCRT2ToLCD) {
1095               tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1096            }
1097            if(SiS_Pr->ChipType >= SIS_315H) {
1098               if(tempbx & SetCRT2ToLCDA) {
1099                  tempbx |= SetCRT2ToLCD;
1100               }
1101            }
1102 
1103         }
1104 
1105         if(tempax & DisableCRT2Display) {
1106            if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1107               tempbx = SetSimuScanMode | DisableCRT2Display;
1108            }
1109         }
1110 
1111         if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1112 
1113         /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1114         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1115            if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1116                ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1117               modeflag &= (~CRT2Mode);
1118            }
1119         }
1120 
1121         if(!(tempbx & SetSimuScanMode)) {
1122            if(tempbx & SwitchCRT2) {
1123               if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1124                  if(resinfo != SIS_RI_1600x1200) {
1125                     tempbx |= SetSimuScanMode;
1126                  }
1127               }
1128            } else {
1129               if(SiS_BridgeIsEnabled(SiS_Pr)) {
1130                  if(!(tempbx & DriverMode)) {
1131                     if(SiS_BridgeInSlavemode(SiS_Pr)) {
1132                        tempbx |= SetSimuScanMode;
1133                     }
1134                  }
1135               }
1136            }
1137         }
1138 
1139         if(!(tempbx & DisableCRT2Display)) {
1140            if(tempbx & DriverMode) {
1141               if(tempbx & SetSimuScanMode) {
1142                  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1143                     if(resinfo != SIS_RI_1600x1200) {
1144                        tempbx |= SetInSlaveMode;
1145                     }
1146                  }
1147               }
1148            } else {
1149               tempbx |= SetInSlaveMode;
1150            }
1151         }
1152 
1153    }
1154 
1155    SiS_Pr->SiS_VBInfo = tempbx;
1156 
1157 #ifdef SIS300
1158    if(SiS_Pr->ChipType == SIS_630) {
1159       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1160    }
1161 #endif
1162 
1163 #ifdef SIS_LINUX_KERNEL
1164 #if 0
1165    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1166       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1167 #endif
1168 #endif
1169 #ifdef SIS_XORG_XF86
1170 #ifdef TWDEBUG
1171    xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1172       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1173 #endif
1174 #endif
1175 }
1176 
1177 /*********************************************/
1178 /*           DETERMINE YPbPr MODE            */
1179 /*********************************************/
1180 
1181 void
1182 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1183 {
1184 
1185    unsigned char temp;
1186 
1187    /* Note: This variable is only used on 30xLV systems.
1188     * CR38 has a different meaning on LVDS/CH7019 systems.
1189     * On 661 and later, these bits moved to CR35.
1190     *
1191     * On 301, 301B, only HiVision 1080i is supported.
1192     * On 30xLV, 301C, only YPbPr 1080i is supported.
1193     */
1194 
1195    SiS_Pr->SiS_YPbPr = 0;
1196    if(SiS_Pr->ChipType >= SIS_661) return;
1197 
1198    if(SiS_Pr->SiS_VBType) {
1199       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1200          SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1201       }
1202    }
1203 
1204    if(SiS_Pr->ChipType >= SIS_315H) {
1205       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1206          temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1207          if(temp & 0x08) {
1208             switch((temp >> 4)) {
1209             case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1210             case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1211             case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1212             case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1213             }
1214          }
1215       }
1216    }
1217 
1218 }
1219 
1220 /*********************************************/
1221 /*           DETERMINE TVMode flag           */
1222 /*********************************************/
1223 
1224 void
1225 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1226 {
1227    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1228    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1229    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1230 
1231    SiS_Pr->SiS_TVMode = 0;
1232 
1233    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1234    if(SiS_Pr->UseCustomMode) return;
1235 
1236    if(ModeNo > 0x13) {
1237       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1238    }
1239 
1240    if(SiS_Pr->ChipType < SIS_661) {
1241 
1242       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1243 
1244       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1245          temp = 0;
1246          if((SiS_Pr->ChipType == SIS_630) ||
1247             (SiS_Pr->ChipType == SIS_730)) {
1248             temp = 0x35;
1249             romindex = 0xfe;
1250          } else if(SiS_Pr->ChipType >= SIS_315H) {
1251             temp = 0x38;
1252             if(SiS_Pr->ChipType < XGI_20) {
1253                romindex = 0xf3;
1254                if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1255             }
1256          }
1257          if(temp) {
1258             if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1259                OutputSelect = ROMAddr[romindex];
1260                if(!(OutputSelect & EnablePALMN)) {
1261                   SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1262                }
1263             }
1264             temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1265             if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1266                if(temp1 & EnablePALM) {         /* 0x40 */
1267                   SiS_Pr->SiS_TVMode |= TVSetPALM;
1268                   SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1269                } else if(temp1 & EnablePALN) {  /* 0x80 */
1270                   SiS_Pr->SiS_TVMode |= TVSetPALN;
1271                }
1272             } else {
1273                if(temp1 & EnableNTSCJ) {        /* 0x40 */
1274                   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1275                }
1276             }
1277          }
1278          /* Translate HiVision/YPbPr to our new flags */
1279          if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1280             if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1281             else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1282             else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1283             else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1284             if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1285                SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1286                SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1287             } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1288                SiS_Pr->SiS_TVMode |= TVSetPAL;
1289             }
1290          }
1291       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1292          if(SiS_Pr->SiS_CHOverScan) {
1293             if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1294                temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1295                if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1296                   SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1297                }
1298             } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1299                temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1300                if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1301                   SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1302                }
1303             }
1304             if(SiS_Pr->SiS_CHSOverScan) {
1305                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1306             }
1307          }
1308          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1309             temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1310             if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1311                if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1312                else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1313             } else {
1314                if(temp & EnableNTSCJ) {
1315                   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1316                }
1317             }
1318          }
1319       }
1320 
1321    } else {  /* 661 and later */
1322 
1323       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1324       if(temp1 & 0x01) {
1325          SiS_Pr->SiS_TVMode |= TVSetPAL;
1326          if(temp1 & 0x08) {
1327             SiS_Pr->SiS_TVMode |= TVSetPALN;
1328          } else if(temp1 & 0x04) {
1329             if(SiS_Pr->SiS_VBType & VB_SISVB) {
1330                SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1331             }
1332             SiS_Pr->SiS_TVMode |= TVSetPALM;
1333          }
1334       } else {
1335          if(temp1 & 0x02) {
1336             SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1337          }
1338       }
1339       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1340          if(SiS_Pr->SiS_CHOverScan) {
1341             if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1342                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1343             }
1344          }
1345       }
1346       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1347          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1348             temp1 &= 0xe0;
1349             if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1350             else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1351             else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1352          } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1353             SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1354          }
1355          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1356             if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1357                SiS_Pr->SiS_TVMode |= TVAspect169;
1358             } else {
1359                temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1360                if(temp1 & 0x02) {
1361                   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1362                      SiS_Pr->SiS_TVMode |= TVAspect169;
1363                   } else {
1364                      SiS_Pr->SiS_TVMode |= TVAspect43LB;
1365                   }
1366                } else {
1367                   SiS_Pr->SiS_TVMode |= TVAspect43;
1368                }
1369             }
1370          }
1371       }
1372    }
1373 
1374    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1375 
1376    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377 
1378       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1379          SiS_Pr->SiS_TVMode |= TVSetPAL;
1380          SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1381       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1382          if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1383             SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1384          }
1385       }
1386 
1387       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1388          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1389             SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1390          }
1391       }
1392 
1393       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1394          if(resinfo == SIS_RI_1024x768) {
1395             if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1396                SiS_Pr->SiS_TVMode |= TVSet525p1024;
1397             } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1398                SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1399             }
1400          }
1401       }
1402 
1403       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1404       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1405          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1406          SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1407       } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1408          SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1409       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1410          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1411             SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1412          }
1413       }
1414 
1415    }
1416 
1417    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1418 
1419 #ifdef SIS_XORG_XF86
1420 #ifdef TWDEBUG
1421    xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1422 #endif
1423 #endif
1424 }
1425 
1426 /*********************************************/
1427 /*               GET LCD INFO                */
1428 /*********************************************/
1429 
1430 static unsigned short
1431 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1432 {
1433    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1434    /* Translate my LCDResInfo to BIOS value */
1435    switch(temp) {
1436    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1437    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1438    case Panel_1280x854:   temp = Panel661_1280x854; break;
1439    }
1440    return temp;
1441 }
1442 
1443 static void
1444 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1445 {
1446 #ifdef SIS315H
1447    unsigned char  *ROMAddr;
1448    unsigned short temp;
1449 
1450 #ifdef SIS_XORG_XF86
1451 #ifdef TWDEBUG
1452    xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1453         SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1454         SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1455         SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1456         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1457         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1458         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1459 #endif
1460 #endif
1461 
1462    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1463       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1464          SiS_Pr->SiS_NeedRomModeData = true;
1465          SiS_Pr->PanelHT  = temp;
1466       }
1467       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1468          SiS_Pr->SiS_NeedRomModeData = true;
1469          SiS_Pr->PanelVT  = temp;
1470       }
1471       SiS_Pr->PanelHRS = SISGETROMW(10);
1472       SiS_Pr->PanelHRE = SISGETROMW(12);
1473       SiS_Pr->PanelVRS = SISGETROMW(14);
1474       SiS_Pr->PanelVRE = SISGETROMW(16);
1475       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1476       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1477          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1478       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1479          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1480       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1481          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1482 
1483 #ifdef SIS_XORG_XF86
1484 #ifdef TWDEBUG
1485       xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1486         SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1487         SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1488         SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1489         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1490         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1491         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1492 #endif
1493 #endif
1494 
1495    }
1496 #endif
1497 }
1498 
1499 static void
1500 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1501                         const unsigned char *nonscalingmodes)
1502 {
1503    int i = 0;
1504    while(nonscalingmodes[i] != 0xff) {
1505       if(nonscalingmodes[i++] == resinfo) {
1506          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1507             (SiS_Pr->UsePanelScaler == -1)) {
1508             SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1509          }
1510          break;
1511       }
1512    }
1513 }
1514 
1515 void
1516 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1517 {
1518   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1519   bool panelcanscale = false;
1520 #ifdef SIS300
1521   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1522   static const unsigned char SiS300SeriesLCDRes[] =
1523           { 0,  1,  2,  3,  7,  4,  5,  8,
1524             0,  0, 10,  0,  0,  0,  0, 15 };
1525 #endif
1526 #ifdef SIS315H
1527   unsigned char   *myptr = NULL;
1528 #endif
1529 
1530   SiS_Pr->SiS_LCDResInfo  = 0;
1531   SiS_Pr->SiS_LCDTypeInfo = 0;
1532   SiS_Pr->SiS_LCDInfo     = 0;
1533   SiS_Pr->PanelHRS        = 999; /* HSync start */
1534   SiS_Pr->PanelHRE        = 999; /* HSync end */
1535   SiS_Pr->PanelVRS        = 999; /* VSync start */
1536   SiS_Pr->PanelVRE        = 999; /* VSync end */
1537   SiS_Pr->SiS_NeedRomModeData = false;
1538 
1539   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1540   SiS_Pr->Alternate1600x1200 = false;
1541 
1542   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1543 
1544   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1545 
1546   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1547      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1548      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1549      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1550   }
1551 
1552   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1553 
1554   /* For broken BIOSes: Assume 1024x768 */
1555   if(temp == 0) temp = 0x02;
1556 
1557   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1558      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1559   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1560      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1561   } else {
1562      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1563   }
1564   temp &= 0x0f;
1565 #ifdef SIS300
1566   if(SiS_Pr->ChipType < SIS_315H) {
1567      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1568      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1569         if(temp < 0x0f) temp &= 0x07;
1570      }
1571      /* Translate 300 series LCDRes to 315 series for unified usage */
1572      temp = SiS300SeriesLCDRes[temp];
1573   }
1574 #endif
1575 
1576   /* Translate to our internal types */
1577 #ifdef SIS315H
1578   if(SiS_Pr->ChipType == SIS_550) {
1579      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1580      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1581      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1582   } else if(SiS_Pr->ChipType >= SIS_661) {
1583      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1584   }
1585 #endif
1586 
1587   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {         /* SiS LVDS */
1588      if(temp == Panel310_1280x768) {
1589         temp = Panel_1280x768_2;
1590      }
1591      if(SiS_Pr->SiS_ROMNew) {
1592         if(temp == Panel661_1280x800) {
1593            temp = Panel_1280x800_2;
1594         }
1595      }
1596   }
1597 
1598   SiS_Pr->SiS_LCDResInfo = temp;
1599 
1600 #ifdef SIS300
1601   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1602      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1603         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1604      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1605         SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1606      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1607         SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1608      }
1609   }
1610 #endif
1611 
1612   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1613      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1614         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1615   } else {
1616      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1617         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1618   }
1619 
1620   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1621   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1622   /* Need temp below! */
1623 
1624   /* These must/can't scale no matter what */
1625   switch(SiS_Pr->SiS_LCDResInfo) {
1626   case Panel_320x240_1:
1627   case Panel_320x240_2:
1628   case Panel_320x240_3:
1629   case Panel_1280x960:
1630       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1631       break;
1632   case Panel_640x480:
1633       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1634   }
1635 
1636   panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1637 
1638   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1640 
1641   /* Dual link, Pass 1:1 BIOS default, etc. */
1642 #ifdef SIS315H
1643   if(SiS_Pr->ChipType >= SIS_661) {
1644      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1645         if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1646      }
1647      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1648         if(SiS_Pr->SiS_ROMNew) {
1649            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1650         } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1651            if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1652         }
1653      }
1654   } else if(SiS_Pr->ChipType >= SIS_315H) {
1655      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1656         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1657      }
1658      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1659         SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1660         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1661         if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1662         if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1663            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1664         }
1665      } else if(!(SiS_Pr->SiS_ROMNew)) {
1666         if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1667            if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1668               (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1669               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1670            }
1671            if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1672               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1673               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1674               (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1675               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1676            }
1677         }
1678      }
1679   }
1680 #endif
1681 
1682   /* Pass 1:1 */
1683   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1684      /* Always center screen on LVDS (if scaling is disabled) */
1685      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1686   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1687      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1688         /* Always center screen on SiS LVDS (if scaling is disabled) */
1689         SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1690      } else {
1691         /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1692         if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1693         if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1694      }
1695   }
1696 
1697   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1699 
1700   switch(SiS_Pr->SiS_LCDResInfo) {
1701      case Panel_320x240_1:
1702      case Panel_320x240_2:
1703      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1704                             SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1705                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1706                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1707                             break;
1708      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1709                                                       SiS_Pr->PanelVRE  =    3;
1710                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1711                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1712                             break;
1713      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1714                             SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1715                             SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1716                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1717                             SiS_Pr->PanelVCLKIdx300 = VCLK40;
1718                             SiS_Pr->PanelVCLKIdx315 = VCLK40;
1719                             break;
1720      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1721                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1722                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1723                             SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1724                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1725                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1726                             break;
1727      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1728                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1729                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1730                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1731                             if(SiS_Pr->ChipType < SIS_315H) {
1732                                SiS_Pr->PanelHRS = 23;
1733                                                       SiS_Pr->PanelVRE  =    5;
1734                             }
1735                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1736                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1737                             SiS_GetLCDInfoBIOS(SiS_Pr);
1738                             break;
1739      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
1740                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1741                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1742                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1743                             if(SiS_Pr->ChipType < SIS_315H) {
1744                                SiS_Pr->PanelHRS = 23;
1745                                                       SiS_Pr->PanelVRE  =    5;
1746                             }
1747                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1748                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1749                             break;
1750      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
1751                             break;
1752      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
1753                             SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
1754                             SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
1755                             SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
1756                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1757                             /* Data above for TMDS (projector); get from BIOS for LVDS */
1758                             SiS_GetLCDInfoBIOS(SiS_Pr);
1759                             break;
1760      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1761                             if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1762                                SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
1763                                SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1764                                SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1765                             } else {
1766                                SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
1767                                SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
1768                                SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1769                                SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1770                                SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1771                             }
1772                             break;
1773      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1774                             SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
1775                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1776                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1777                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1778                             SiS_GetLCDInfoBIOS(SiS_Pr);
1779                             break;
1780      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1781                             SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
1782                             SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
1783                             SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1784                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1785                             SiS_GetLCDInfoBIOS(SiS_Pr);
1786                             break;
1787      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1788                             SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
1789                             SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
1790                             SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1791                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1792                             SiS_GetLCDInfoBIOS(SiS_Pr);
1793                             break;
1794      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
1795                             SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
1796                             SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
1797                             SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
1798                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1799                             SiS_GetLCDInfoBIOS(SiS_Pr);
1800                             break;
1801      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
1802                             SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
1803                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1804                             SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1805                             if(resinfo == SIS_RI_1280x1024) {
1806                                SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1807                                SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1808                             }
1809                             break;
1810      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1811                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1812                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1813                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1814                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1815                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1816                             SiS_GetLCDInfoBIOS(SiS_Pr);
1817                             break;
1818      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1819                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1820                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1821                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1822                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1823                             SiS_GetLCDInfoBIOS(SiS_Pr);
1824                             break;
1825      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1826                             SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
1827                             SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
1828                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1829                             SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1830                             if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1831                                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1832                                   SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
1833                                   SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
1834                                   SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
1835                                   SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1836                                   SiS_Pr->Alternate1600x1200 = true;
1837                                }
1838                             } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1839                                SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
1840                                SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1841                                SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1842                             }
1843                             SiS_GetLCDInfoBIOS(SiS_Pr);
1844                             break;
1845      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1846                             SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
1847                             SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
1848                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1849                             SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1850                             SiS_GetLCDInfoBIOS(SiS_Pr);
1851                             break;
1852      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1853                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1854                             break;
1855      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
1856                             SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1857                             break;
1858      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
1859                             SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1860                             break;
1861      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1862                             SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1863                             SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
1864                             SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
1865                             if(SiS_Pr->CP_PreferredIndex != -1) {
1866                                SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1867                                SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1868                                SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1869                                SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1870                                SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1871                                SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1872                                SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1873                                SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1874                                SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1875                                SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1876                                SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1877                                SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1878                                if(SiS_Pr->CP_PrefClock) {
1879                                   int idx;
1880                                   SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1881                                   SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1882                                   if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1883                                   else                             idx = VCLK_CUSTOM_315;
1884                                   SiS_Pr->SiS_VCLKData[idx].CLOCK =
1885                                      SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1886                                   SiS_Pr->SiS_VCLKData[idx].SR2B =
1887                                      SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1888                                   SiS_Pr->SiS_VCLKData[idx].SR2C =
1889                                      SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1890                                }
1891                             }
1892                             break;
1893      default:               SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1894                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1895                             break;
1896   }
1897 
1898   /* Special cases */
1899   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
1900       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
1901       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1902       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1903       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1904       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1905      SiS_Pr->PanelHRS = 999;
1906      SiS_Pr->PanelHRE = 999;
1907   }
1908 
1909   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1910       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1911       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1912       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1913      SiS_Pr->PanelVRS = 999;
1914      SiS_Pr->PanelVRE = 999;
1915   }
1916 
1917   /* DontExpand overrule */
1918   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1919 
1920      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1921         /* No scaling for this mode on any panel (LCD=CRT2)*/
1922         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1923      }
1924 
1925      switch(SiS_Pr->SiS_LCDResInfo) {
1926 
1927      case Panel_Custom:
1928      case Panel_1152x864:
1929      case Panel_1280x768:       /* TMDS only */
1930         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1931         break;
1932 
1933      case Panel_800x600: {
1934         static const unsigned char nonscalingmodes[] = {
1935            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1936         };
1937         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1938         break;
1939      }
1940      case Panel_1024x768: {
1941         static const unsigned char nonscalingmodes[] = {
1942            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1943            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1944            0xff
1945         };
1946         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1947         break;
1948      }
1949      case Panel_1280x720: {
1950         static const unsigned char nonscalingmodes[] = {
1951            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1952            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1953            0xff
1954         };
1955         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1956         if(SiS_Pr->PanelHT == 1650) {
1957            SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1958         }
1959         break;
1960      }
1961      case Panel_1280x768_2: {  /* LVDS only */
1962         static const unsigned char nonscalingmodes[] = {
1963            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1964            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1965            SIS_RI_1152x768,0xff
1966         };
1967         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1968         switch(resinfo) {
1969         case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
1970                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1971                                }
1972                                break;
1973         }
1974         break;
1975      }
1976      case Panel_1280x800: {     /* SiS TMDS special (Averatec 6200 series) */
1977         static const unsigned char nonscalingmodes[] = {
1978            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1979            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1980            SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1981         };
1982         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1983         break;
1984      }
1985      case Panel_1280x800_2:  {  /* SiS LVDS */
1986         static const unsigned char nonscalingmodes[] = {
1987            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1988            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1989            SIS_RI_1152x768,0xff
1990         };
1991         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1992         switch(resinfo) {
1993         case SIS_RI_1280x720:
1994         case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
1995                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1996                                }
1997                                break;
1998         }
1999         break;
2000      }
2001      case Panel_1280x854: {     /* SiS LVDS */
2002         static const unsigned char nonscalingmodes[] = {
2003            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2004            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2005            SIS_RI_1152x768,0xff
2006         };
2007         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2008         switch(resinfo) {
2009         case SIS_RI_1280x720:
2010         case SIS_RI_1280x768:
2011         case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2012                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2013                                }
2014                                break;
2015         }
2016         break;
2017      }
2018      case Panel_1280x960: {
2019         static const unsigned char nonscalingmodes[] = {
2020            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2021            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2022            SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2023            SIS_RI_1280x854,0xff
2024         };
2025         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2026         break;
2027      }
2028      case Panel_1280x1024: {
2029         static const unsigned char nonscalingmodes[] = {
2030            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2031            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2032            SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2033            SIS_RI_1280x854,SIS_RI_1280x960,0xff
2034         };
2035         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2036         break;
2037      }
2038      case Panel_1400x1050: {
2039         static const unsigned char nonscalingmodes[] = {
2040              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2041              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2042              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2043              SIS_RI_1280x960,0xff
2044         };
2045         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2046         switch(resinfo) {
2047         case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2048                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2049                                }
2050                                break;
2051         case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2052                                break;
2053         }
2054         break;
2055      }
2056      case Panel_1600x1200: {
2057         static const unsigned char nonscalingmodes[] = {
2058              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2059              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2060              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2061              SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2062         };
2063         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2064         break;
2065      }
2066      case Panel_1680x1050: {
2067         static const unsigned char nonscalingmodes[] = {
2068              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2069              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2070              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2071              SIS_RI_1360x1024,0xff
2072         };
2073         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2074         break;
2075      }
2076      }
2077   }
2078 
2079 #ifdef SIS300
2080   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2081      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2082         SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2083      }
2084   }
2085 
2086   if(SiS_Pr->ChipType < SIS_315H) {
2087      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2088         if(SiS_Pr->SiS_UseROM) {
2089            if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2090               if(!(ROMAddr[0x235] & 0x02)) {
2091                  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2092               }
2093            }
2094         }
2095      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2096         if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2097            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2098         }
2099      }
2100   }
2101 #endif
2102 
2103   /* Special cases */
2104 
2105   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2106      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2107   }
2108 
2109   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2110      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2111   }
2112 
2113   switch(SiS_Pr->SiS_LCDResInfo) {
2114   case Panel_640x480:
2115      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2116      break;
2117   case Panel_1280x800:
2118      /* Don't pass 1:1 by default (TMDS special) */
2119      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2120      break;
2121   case Panel_1280x960:
2122      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2123      break;
2124   case Panel_Custom:
2125      if((!SiS_Pr->CP_PrefClock) ||
2126         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2127         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2128      }
2129      break;
2130   }
2131 
2132   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2133      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2134   }
2135 
2136   /* (In)validate LCDPass11 flag */
2137   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2138      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2139   }
2140 
2141   /* LVDS DDA */
2142   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2143 
2144      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2145         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2146            if(ModeNo == 0x12) {
2147               if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2148                  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2149               }
2150            } else if(ModeNo > 0x13) {
2151               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2152                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2153                     if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2154                        SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2155                     }
2156                  }
2157               }
2158            }
2159         }
2160      }
2161 
2162      if(modeflag & HalfDCLK) {
2163         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2164            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2165         } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2166            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2167         } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2168            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2169         } else if(ModeNo > 0x13) {
2170            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2171               if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2172            } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2173               if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2174            }
2175         }
2176      }
2177 
2178   }
2179 
2180   /* VESA timing */
2181   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2182      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2183         SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2184      }
2185   } else {
2186      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2187   }
2188 
2189 #ifdef SIS_LINUX_KERNEL
2190 #if 0
2191   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2192         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2193 #endif
2194 #endif
2195 #ifdef SIS_XORG_XF86
2196   xf86DrvMsgVerb(0, X_PROBED, 4,
2197         "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2198         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2199 #endif
2200 }
2201 
2202 /*********************************************/
2203 /*                 GET VCLK                  */
2204 /*********************************************/
2205 
2206 unsigned short
2207 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2208                 unsigned short RefreshRateTableIndex)
2209 {
2210   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2211   unsigned short modeflag, resinfo, tempbx;
2212   const unsigned char *CHTVVCLKPtr = NULL;
2213 
2214   if(ModeNo <= 0x13) {
2215      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2216      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2217      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2218      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2219      VCLKIndexGENCRT = VCLKIndexGEN;
2220   } else {
2221      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2222      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2223      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2224      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2225      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2226                 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2227   }
2228 
2229   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2230 
2231      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2232 
2233         CRT2Index >>= 6;
2234         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {       /*  LCD */
2235 
2236            if(SiS_Pr->ChipType < SIS_315H) {
2237               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2238               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2239                  VCLKIndex = VCLKIndexGEN;
2240               }
2241            } else {
2242               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2243               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2244                  switch(resinfo) {
2245                  /* Correct those whose IndexGEN doesn't match VBVCLK array */
2246                  case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2247                  case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2248                  case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2249                  case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2250                  case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2251                  case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2252                  case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2253                  case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2254                  case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2255                  case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2256                  default:              VCLKIndex = VCLKIndexGEN;
2257                  }
2258 
2259                  if(ModeNo <= 0x13) {
2260                     if(SiS_Pr->ChipType <= SIS_315PRO) {
2261                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2262                     } else {
2263                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2264                     }
2265                  }
2266                  if(SiS_Pr->ChipType <= SIS_315PRO) {
2267                     if(VCLKIndex == 0) VCLKIndex = 0x41;
2268                     if(VCLKIndex == 1) VCLKIndex = 0x43;
2269                     if(VCLKIndex == 4) VCLKIndex = 0x44;
2270                  }
2271               }
2272            }
2273 
2274         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                   /*  TV */
2275 
2276            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2277               if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)        VCLKIndex = HiTVVCLKDIV2;
2278               else                                         VCLKIndex = HiTVVCLK;
2279               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2280            } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2281            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2282            else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2283            else                                            VCLKIndex = TVVCLK;
2284 
2285            if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2286            else                            VCLKIndex += TVCLKBASE_315;
2287 
2288         } else {                                                        /* VGA2 */
2289 
2290            VCLKIndex = VCLKIndexGENCRT;
2291            if(SiS_Pr->ChipType < SIS_315H) {
2292               if(ModeNo > 0x13) {
2293                  if( (SiS_Pr->ChipType == SIS_630) &&
2294                      (SiS_Pr->ChipRevision >= 0x30)) {
2295                     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2296                  }
2297                  /* Better VGA2 clock for 1280x1024@75 */
2298                  if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2299               }
2300            }
2301         }
2302 
2303      } else {   /* If not programming CRT2 */
2304 
2305         VCLKIndex = VCLKIndexGENCRT;
2306         if(SiS_Pr->ChipType < SIS_315H) {
2307            if(ModeNo > 0x13) {
2308               if( (SiS_Pr->ChipType != SIS_630) &&
2309                   (SiS_Pr->ChipType != SIS_300) ) {
2310                  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2311               }
2312            }
2313         }
2314      }
2315 
2316   } else {       /*   LVDS  */
2317 
2318      VCLKIndex = CRT2Index;
2319 
2320      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2321 
2322         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2323 
2324            VCLKIndex &= 0x1f;
2325            tempbx = 0;
2326            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2327            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2328               tempbx += 2;
2329               if(SiS_Pr->SiS_ModeType > ModeVGA) {
2330                  if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2331               }
2332               if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2333                  tempbx = 4;
2334                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2335               } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2336                  tempbx = 6;
2337                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2338               }
2339            }
2340            switch(tempbx) {
2341              case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2342              case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2343              case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2344              case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2345              case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2346              case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2347              case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2348              case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2349              case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2350              default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2351            }
2352            VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2353 
2354         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2355 
2356            if(SiS_Pr->ChipType < SIS_315H) {
2357               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2358            } else {
2359               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2360            }
2361 
2362 #ifdef SIS300
2363            /* Special Timing: Barco iQ Pro R series */
2364            if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2365 
2366            /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2367            if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2368               if(SiS_Pr->ChipType < SIS_315H) {
2369                  VCLKIndex = VCLK34_300;
2370                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2371               } else {
2372                  VCLKIndex = VCLK34_315;
2373                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2374               }
2375            }
2376 #endif
2377 
2378         } else {
2379 
2380            VCLKIndex = VCLKIndexGENCRT;
2381            if(SiS_Pr->ChipType < SIS_315H) {
2382               if(ModeNo > 0x13) {
2383                  if( (SiS_Pr->ChipType == SIS_630) &&
2384                      (SiS_Pr->ChipRevision >= 0x30) ) {
2385                     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2386                  }
2387               }
2388            }
2389         }
2390 
2391      } else {  /* if not programming CRT2 */
2392 
2393         VCLKIndex = VCLKIndexGENCRT;
2394         if(SiS_Pr->ChipType < SIS_315H) {
2395            if(ModeNo > 0x13) {
2396               if( (SiS_Pr->ChipType != SIS_630) &&
2397                   (SiS_Pr->ChipType != SIS_300) ) {
2398                  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2399               }
2400 #if 0
2401               if(SiS_Pr->ChipType == SIS_730) {
2402                  if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2403                  if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2404               }
2405 #endif
2406            }
2407         }
2408 
2409      }
2410 
2411   }
2412 
2413 #ifdef SIS_XORG_XF86
2414 #ifdef TWDEBUG
2415   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2416 #endif
2417 #endif
2418 
2419   return VCLKIndex;
2420 }
2421 
2422 /*********************************************/
2423 /*        SET CRT2 MODE TYPE REGISTERS       */
2424 /*********************************************/
2425 
2426 static void
2427 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2428 {
2429   unsigned short i, j, modeflag, tempah=0;
2430   short tempcl;
2431 #if defined(SIS300) || defined(SIS315H)
2432   unsigned short tempbl;
2433 #endif
2434 #ifdef SIS315H
2435   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2436   unsigned short tempah2, tempbl2;
2437 #endif
2438 
2439   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2440 
2441   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2442 
2443      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2444      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2445 
2446   } else {
2447 
2448      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2449      if(SiS_Pr->ChipType >= SIS_315H) {
2450         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2451      }
2452 
2453      tempcl = SiS_Pr->SiS_ModeType;
2454 
2455      if(SiS_Pr->ChipType < SIS_315H) {
2456 
2457 #ifdef SIS300    /* ---- 300 series ---- */
2458 
2459         /* For 301BDH: (with LCD via LVDS) */
2460         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2461            tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2462            tempbl &= 0xef;
2463            tempbl |= 0x02;
2464            if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2465               tempbl |= 0x10;
2466               tempbl &= 0xfd;
2467            }
2468            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2469         }
2470 
2471         if(ModeNo > 0x13) {
2472            tempcl -= ModeVGA;
2473            if(tempcl >= 0) {
2474               tempah = ((0x10 >> tempcl) | 0x80);
2475            }
2476         } else tempah = 0x80;
2477 
2478         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2479 
2480 #endif  /* SIS300 */
2481 
2482      } else {
2483 
2484 #ifdef SIS315H    /* ------- 315/330 series ------ */
2485 
2486         if(ModeNo > 0x13) {
2487            tempcl -= ModeVGA;
2488            if(tempcl >= 0) {
2489               tempah = (0x08 >> tempcl);
2490               if (tempah == 0) tempah = 1;
2491               tempah |= 0x40;
2492            }
2493         } else tempah = 0x40;
2494 
2495         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2496 
2497 #endif  /* SIS315H */
2498 
2499      }
2500 
2501      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2502 
2503      if(SiS_Pr->ChipType < SIS_315H) {
2504         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2505      } else {
2506 #ifdef SIS315H
2507         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2508            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2509         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2510            if(IS_SIS740) {
2511               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2512            } else {
2513               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2514            }
2515         }
2516 #endif
2517      }
2518 
2519      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2520 
2521         tempah = 0x01;
2522         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2523            tempah |= 0x02;
2524         }
2525         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2526            tempah ^= 0x05;
2527            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2528               tempah ^= 0x01;
2529            }
2530         }
2531 
2532         if(SiS_Pr->ChipType < SIS_315H) {
2533 
2534            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2535 
2536            tempah = (tempah << 5) & 0xFF;
2537            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2538            tempah = (tempah >> 5) & 0xFF;
2539 
2540         } else {
2541 
2542            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2543            else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2544            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2545            tempah &= ~0x08;
2546 
2547         }
2548 
2549         if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2550            tempah |= 0x10;
2551         }
2552 
2553         tempah |= 0x80;
2554         if(SiS_Pr->SiS_VBType & VB_SIS301) {
2555            if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2556         }
2557 
2558         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2559            if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2560               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2561                  tempah |= 0x20;
2562               }
2563            }
2564         }
2565 
2566         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2567 
2568         tempah = 0x80;
2569         if(SiS_Pr->SiS_VBType & VB_SIS301) {
2570            if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2571         }
2572 
2573         if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2574 
2575         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2576            if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2577               tempah |= 0x40;
2578            }
2579         }
2580 
2581         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2582 
2583      } else {  /* LVDS */
2584 
2585         if(SiS_Pr->ChipType >= SIS_315H) {
2586 
2587 #ifdef SIS315H
2588            /* LVDS can only be slave in 8bpp modes */
2589            tempah = 0x80;
2590            if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2591               if(SiS_Pr->SiS_VBInfo & DriverMode) {
2592                  tempah |= 0x02;
2593               }
2594            }
2595 
2596            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2597 
2598            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2599 
2600            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2601 
2602            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2603 #endif
2604 
2605         } else {
2606 
2607 #ifdef SIS300
2608            tempah = 0;
2609            if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2610               tempah |= 0x02;
2611            }
2612            tempah <<= 5;
2613 
2614            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2615 
2616            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2617 #endif
2618 
2619         }
2620 
2621      }
2622 
2623   }  /* LCDA */
2624 
2625   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2626 
2627      if(SiS_Pr->ChipType >= SIS_315H) {
2628 
2629 #ifdef SIS315H
2630         /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2631 
2632         /* The following is nearly unpreditable and varies from machine
2633          * to machine. Especially the 301DH seems to be a real trouble
2634          * maker. Some BIOSes simply set the registers (like in the
2635          * NoLCD-if-statements here), some set them according to the
2636          * LCDA stuff. It is very likely that some machines are not
2637          * treated correctly in the following, very case-orientated
2638          * code. What do I do then...?
2639          */
2640 
2641         /* 740 variants match for 30xB, 301B-DH, 30xLV */
2642 
2643         if(!(IS_SIS740)) {
2644            tempah = 0x04;                                                  /* For all bridges */
2645            tempbl = 0xfb;
2646            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2647               tempah = 0x00;
2648               if(SiS_IsDualEdge(SiS_Pr)) {
2649                  tempbl = 0xff;
2650               }
2651            }
2652            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2653         }
2654 
2655         /* The following two are responsible for eventually wrong colors
2656          * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2657          * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2658          * in a 650 box (Jake). What is the criteria?
2659          * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2660          * treatment like the 651+301B-DH(b0) case. Seems more to be the
2661          * chipset than the bridge revision.
2662          */
2663 
2664         if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2665            tempah = 0x30;
2666            tempbl = 0xc0;
2667            if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2668               ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2669               tempah = 0x00;
2670               tempbl = 0x00;
2671            }
2672            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2673            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2674         } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2675            /* Fixes "TV-blue-bug" on 315+301 */
2676            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);      /* For 301   */
2677            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2678         } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2679            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);       /* For 30xLV */
2680            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2681         } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {              /* For 301B-DH */
2682            tempah = 0x30; tempah2 = 0xc0;
2683            tempbl = 0xcf; tempbl2 = 0x3f;
2684            if(SiS_Pr->SiS_TVBlue == 0) {
2685                  tempah = tempah2 = 0x00;
2686            } else if(SiS_Pr->SiS_TVBlue == -1) {
2687               /* Set on 651/M650, clear on 315/650 */
2688               if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2689                  tempah = tempah2 = 0x00;
2690               }
2691            }
2692            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2693            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2694         } else {
2695            tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB, 301C */
2696            tempbl = 0xcf; tempbl2 = 0x3f;
2697            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2698               tempah = tempah2 = 0x00;
2699               if(SiS_IsDualEdge(SiS_Pr)) {
2700                  tempbl = tempbl2 = 0xff;
2701               }
2702            }
2703            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2704            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2705         }
2706 
2707         if(IS_SIS740) {
2708            tempah = 0x80;
2709            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2710            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2711         } else {
2712            tempah = 0x00;
2713            tempbl = 0x7f;
2714            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2715               tempbl = 0xff;
2716               if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2717            }
2718            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2719         }
2720 
2721 #endif /* SIS315H */
2722 
2723      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2724 
2725 #ifdef SIS300
2726         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2727 
2728         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2729            ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2730             (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2731            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2732         } else {
2733            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2734         }
2735 #endif
2736 
2737      }
2738 
2739      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2740         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2741         if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2742            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2743         }
2744      }
2745 
2746   } else {  /* LVDS */
2747 
2748 #ifdef SIS315H
2749      if(SiS_Pr->ChipType >= SIS_315H) {
2750 
2751         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2752 
2753            tempah = 0x04;
2754            tempbl = 0xfb;
2755            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2756               tempah = 0x00;
2757               if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2758            }
2759            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2760 
2761            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2762               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2763            }
2764 
2765            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2766 
2767         } else if(SiS_Pr->ChipType == SIS_550) {
2768 
2769            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2770            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2771 
2772         }
2773 
2774      }
2775 #endif
2776 
2777   }
2778 
2779 }
2780 
2781 /*********************************************/
2782 /*            GET RESOLUTION DATA            */
2783 /*********************************************/
2784 
2785 unsigned short
2786 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2787 {
2788    if(ModeNo <= 0x13)
2789       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2790    else
2791       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2792 }
2793 
2794 static void
2795 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2796 {
2797    unsigned short xres, yres, modeflag=0, resindex;
2798 
2799    if(SiS_Pr->UseCustomMode) {
2800       xres = SiS_Pr->CHDisplay;
2801       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2802       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2803       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2804       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2805       return;
2806    }
2807 
2808    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2809 
2810    if(ModeNo <= 0x13) {
2811       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2812       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2813    } else {
2814       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2815       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2816       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2817    }
2818 
2819    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2820 
2821       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2822          if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2823             if(yres == 350) yres = 400;
2824          }
2825          if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2826             if(ModeNo == 0x12) yres = 400;
2827          }
2828       }
2829 
2830       if(modeflag & HalfDCLK)       xres <<= 1;
2831       if(modeflag & DoubleScanMode) yres <<= 1;
2832 
2833    }
2834 
2835    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2836 
2837       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2838          switch(SiS_Pr->SiS_LCDResInfo) {
2839            case Panel_1024x768:
2840               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2841                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2842                     if(yres == 350) yres = 357;
2843                     if(yres == 400) yres = 420;
2844                     if(yres == 480) yres = 525;
2845                  }
2846               }
2847               break;
2848            case Panel_1280x1024:
2849               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2850                  /* BIOS bug - does this regardless of scaling */
2851                  if(yres == 400) yres = 405;
2852               }
2853               if(yres == 350) yres = 360;
2854               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2855                  if(yres == 360) yres = 375;
2856               }
2857               break;
2858            case Panel_1600x1200:
2859               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2860                  if(yres == 1024) yres = 1056;
2861               }
2862               break;
2863          }
2864       }
2865 
2866    } else {
2867 
2868       if(SiS_Pr->SiS_VBType & VB_SISVB) {
2869          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2870             if(xres == 720) xres = 640;
2871          }
2872       } else if(xres == 720) xres = 640;
2873 
2874       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2875          yres = 400;
2876          if(SiS_Pr->ChipType >= SIS_315H) {
2877             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2878          } else {
2879             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2880          }
2881          if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2882       }
2883 
2884    }
2885    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2886    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2887 }
2888 
2889 /*********************************************/
2890 /*           GET CRT2 TIMING DATA            */
2891 /*********************************************/
2892 
2893 static void
2894 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2895                unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2896                unsigned short *ResIndex)
2897 {
2898   unsigned short tempbx=0, tempal=0, resinfo=0;
2899 
2900   if(ModeNo <= 0x13) {
2901      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2902   } else {
2903      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2904      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2905   }
2906 
2907   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2908 
2909      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2910 
2911         tempbx = SiS_Pr->SiS_LCDResInfo;
2912         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2913 
2914         /* patch index */
2915         if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2916            if     (resinfo == SIS_RI_1280x800)  tempal =  9;
2917            else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2918         } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2919                   (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2920                   (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2921            if     (resinfo == SIS_RI_1280x768)  tempal =  9;
2922         }
2923 
2924         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2925            /* Pass 1:1 only (center-screen handled outside) */
2926            /* This is never called for the panel's native resolution */
2927            /* since Pass1:1 will not be set in this case */
2928            tempbx = 100;
2929            if(ModeNo >= 0x13) {
2930               tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2931            }
2932         }
2933 
2934 #ifdef SIS315H
2935         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2936            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2937               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2938                  tempbx = 200;
2939                  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2940               }
2941            }
2942         }
2943 #endif
2944 
2945      } else {                                                   /* TV */
2946 
2947         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2948            /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2949            tempbx = 2;
2950            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2951               tempbx = 13;
2952               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2953            }
2954         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2955            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
2956            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2957            else                                         tempbx = 5;
2958            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2959         } else {
2960            if(SiS_Pr->SiS_TVMode & TVSetPAL)            tempbx = 3;
2961            else                                         tempbx = 4;
2962            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2963         }
2964 
2965      }
2966 
2967      tempal &= 0x3F;
2968 
2969      if(ModeNo > 0x13) {
2970         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2971            switch(resinfo) {
2972            case SIS_RI_720x480:
2973               tempal = 6;
2974               if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))   tempal = 9;
2975               break;
2976            case SIS_RI_720x576:
2977            case SIS_RI_768x576:
2978            case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2979               tempal = 6;
2980               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2981                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 8;
2982               }
2983               break;
2984            case SIS_RI_800x480:
2985               tempal = 4;
2986               break;
2987            case SIS_RI_512x384:
2988            case SIS_RI_1024x768:
2989               tempal = 7;
2990               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2991                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)        tempal = 8;
2992               }
2993               break;
2994            case SIS_RI_1280x720:
2995               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2996                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 9;
2997               }
2998               break;
2999            }
3000         }
3001      }
3002 
3003      *CRT2Index = tempbx;
3004      *ResIndex = tempal;
3005 
3006   } else {   /* LVDS, 301B-DH (if running on LCD) */
3007 
3008      tempbx = 0;
3009      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3010 
3011         tempbx = 90;
3012         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3013            tempbx = 92;
3014            if(SiS_Pr->SiS_ModeType > ModeVGA) {
3015               if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3016            }
3017            if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3018            else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3019         }
3020         if(tempbx != 99) {
3021            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3022         }
3023 
3024      } else {
3025 
3026         switch(SiS_Pr->SiS_LCDResInfo) {
3027         case Panel_640x480:   tempbx = 12; break;
3028         case Panel_320x240_1: tempbx = 10; break;
3029         case Panel_320x240_2:
3030         case Panel_320x240_3: tempbx = 14; break;
3031         case Panel_800x600:   tempbx = 16; break;
3032         case Panel_1024x600:  tempbx = 18; break;
3033         case Panel_1152x768:
3034         case Panel_1024x768:  tempbx = 20; break;
3035         case Panel_1280x768:  tempbx = 22; break;
3036         case Panel_1280x1024: tempbx = 24; break;
3037         case Panel_1400x1050: tempbx = 26; break;
3038         case Panel_1600x1200: tempbx = 28; break;
3039 #ifdef SIS300
3040         case Panel_Barco1366: tempbx = 80; break;
3041 #endif
3042         }
3043 
3044         switch(SiS_Pr->SiS_LCDResInfo) {
3045         case Panel_320x240_1:
3046         case Panel_320x240_2:
3047         case Panel_320x240_3:
3048         case Panel_640x480:
3049            break;
3050         default:
3051            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3052         }
3053 
3054         if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3055 
3056 #ifdef SIS300
3057         if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3058            tempbx = 82;
3059            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3060         } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3061            tempbx = 84;
3062            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3063         }
3064 #endif
3065 
3066      }
3067 
3068      (*CRT2Index) = tempbx;
3069      (*ResIndex) = tempal & 0x1F;
3070   }
3071 }
3072 
3073 static void
3074 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3075                 unsigned short RefreshRateTableIndex)
3076 {
3077   unsigned short tempax=0, tempbx=0, index, dotclock;
3078   unsigned short temp1=0, modeflag=0, tempcx=0;
3079 
3080   SiS_Pr->SiS_RVBHCMAX  = 1;
3081   SiS_Pr->SiS_RVBHCFACT = 1;
3082 
3083   if(ModeNo <= 0x13) {
3084 
3085      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3086      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3087 
3088      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3089      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3090      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3091 
3092      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3093 
3094   } else {
3095 
3096      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3097      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3098 
3099      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3100      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3101      tempax &= 0x03FF;
3102      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3103      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3104      tempcx &= 0x0100;
3105      tempcx <<= 2;
3106      tempbx |= tempcx;
3107      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3108 
3109      dotclock = 8;
3110 
3111   }
3112 
3113   if(temp1 & 0x01) tempbx |= 0x0100;
3114   if(temp1 & 0x20) tempbx |= 0x0200;
3115 
3116   tempax += 5;
3117   tempax *= dotclock;
3118   if(modeflag & HalfDCLK) tempax <<= 1;
3119 
3120   tempbx++;
3121 
3122   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3123   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3124 }
3125 
3126 static void
3127 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3128                 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3129 {
3130    unsigned short ResIndex;
3131 
3132    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3133       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3134          if(SiS_Pr->UseCustomMode) {
3135             ResIndex = SiS_Pr->CHTotal;
3136             if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3137             SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3138             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3139          } else {
3140             if(ModeNo < 0x13) {
3141                ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3142             } else {
3143                ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3144             }
3145             if(ResIndex == 0x09) {
3146                if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3147                else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3148             }
3149             SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3150             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3151             SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3152             SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3153          }
3154       } else {
3155          SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3156          SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3157       }
3158    } else {
3159       /* This handles custom modes and custom panels */
3160       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3161       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3162       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3163       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3164       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3165       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3166    }
3167 }
3168 
3169 static void
3170 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3171                     unsigned short RefreshRateTableIndex)
3172 {
3173    unsigned short CRT2Index, ResIndex, backup;
3174    const struct SiS_LVDSData *LVDSData = NULL;
3175 
3176    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3177 
3178    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3179       SiS_Pr->SiS_RVBHCMAX  = 1;
3180       SiS_Pr->SiS_RVBHCFACT = 1;
3181       SiS_Pr->SiS_NewFlickerMode = 0;
3182       SiS_Pr->SiS_RVBHRS = 50;
3183       SiS_Pr->SiS_RY1COE = 0;
3184       SiS_Pr->SiS_RY2COE = 0;
3185       SiS_Pr->SiS_RY3COE = 0;
3186       SiS_Pr->SiS_RY4COE = 0;
3187       SiS_Pr->SiS_RVBHRS2 = 0;
3188    }
3189 
3190    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3191 
3192 #ifdef SIS315H
3193       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3194       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3195 #endif
3196 
3197    } else {
3198 
3199       /* 301BDH needs LVDS Data */
3200       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3201       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3202          SiS_Pr->SiS_IF_DEF_LVDS = 1;
3203       }
3204 
3205       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3206                                             &CRT2Index, &ResIndex);
3207 
3208       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3209 
3210       switch(CRT2Index) {
3211          case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3212          case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3213          case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3214          case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3215          case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3216          case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3217 #ifdef SIS300
3218          case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3219          case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3220          case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3221          case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3222          case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3223 #endif
3224          case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3225          case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3226          case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3227          case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3228          case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3229          case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3230          case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3231          case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3232          case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;
3233       }
3234 
3235       if(LVDSData) {
3236          SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3237          SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3238          SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3239          SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3240       } else {
3241          SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3242       }
3243 
3244       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3245           (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3246           (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3247          if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3248              (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3249             SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3250             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3251 #ifdef SIS300
3252             if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3253                if(ResIndex < 0x08) {
3254                   SiS_Pr->SiS_HDE = 1280;
3255                   SiS_Pr->SiS_VDE = 1024;
3256                }
3257             }
3258 #endif
3259          }
3260       }
3261    }
3262 }
3263 
3264 static void
3265 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3266                 unsigned short RefreshRateTableIndex)
3267 {
3268   unsigned char  *ROMAddr = NULL;
3269   unsigned short tempax, tempbx, modeflag, romptr=0;
3270   unsigned short resinfo, CRT2Index, ResIndex;
3271   const struct SiS_LCDData *LCDPtr = NULL;
3272   const struct SiS_TVData  *TVPtr  = NULL;
3273 #ifdef SIS315H
3274   short resinfo661;
3275 #endif
3276 
3277   if(ModeNo <= 0x13) {
3278      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3279      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3280   } else if(SiS_Pr->UseCustomMode) {
3281      modeflag = SiS_Pr->CModeFlag;
3282      resinfo = 0;
3283   } else {
3284      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3285      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3286 #ifdef SIS315H
3287      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3288      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3289          (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3290          (resinfo661 >= 0)                     &&
3291          (SiS_Pr->SiS_NeedRomModeData) ) {
3292         if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3293            if((romptr = (SISGETROMW(21)))) {
3294               romptr += (resinfo661 * 10);
3295               ROMAddr = SiS_Pr->VirtualRomBase;
3296            }
3297         }
3298      }
3299 #endif
3300   }
3301 
3302   SiS_Pr->SiS_NewFlickerMode = 0;
3303   SiS_Pr->SiS_RVBHRS = 50;
3304   SiS_Pr->SiS_RY1COE = 0;
3305   SiS_Pr->SiS_RY2COE = 0;
3306   SiS_Pr->SiS_RY3COE = 0;
3307   SiS_Pr->SiS_RY4COE = 0;
3308   SiS_Pr->SiS_RVBHRS2 = 0;
3309 
3310   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3311 
3312   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3313 
3314      if(SiS_Pr->UseCustomMode) {
3315 
3316         SiS_Pr->SiS_RVBHCMAX  = 1;
3317         SiS_Pr->SiS_RVBHCFACT = 1;
3318         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3319         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3320 
3321         tempax = SiS_Pr->CHTotal;
3322         if(modeflag & HalfDCLK) tempax <<= 1;
3323         SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3324         SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3325 
3326      } else {
3327 
3328         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3329 
3330      }
3331 
3332   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3333 
3334      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3335                     &CRT2Index,&ResIndex);
3336 
3337      switch(CRT2Index) {
3338         case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3339         case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3340         case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3341         case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3342         case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3343         case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3344         case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3345         case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3346         case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3347         case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3348         case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3349         case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3350         case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3351         default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3352      }
3353 
3354      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3355      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3356      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3357      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3358      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3359      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3360      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3361      if(modeflag & HalfDCLK) {
3362         SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3363         if(SiS_Pr->SiS_RVBHRS2) {
3364            SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3365            tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3366            if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3367            else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3368         }
3369      } else {
3370         SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3371      }
3372      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3373 
3374      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3375 
3376         if((resinfo == SIS_RI_960x600)   ||
3377            (resinfo == SIS_RI_1024x768)  ||
3378            (resinfo == SIS_RI_1280x1024) ||
3379            (resinfo == SIS_RI_1280x720)) {
3380            SiS_Pr->SiS_NewFlickerMode = 0x40;
3381         }
3382 
3383         if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3384 
3385         SiS_Pr->SiS_HT = ExtHiTVHT;
3386         SiS_Pr->SiS_VT = ExtHiTVVT;
3387         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3388            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3389               SiS_Pr->SiS_HT = StHiTVHT;
3390               SiS_Pr->SiS_VT = StHiTVVT;
3391            }
3392         }
3393 
3394      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3395 
3396         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3397            SiS_Pr->SiS_HT = 1650;
3398            SiS_Pr->SiS_VT = 750;
3399         } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3400            SiS_Pr->SiS_HT = NTSCHT;
3401            if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3402            SiS_Pr->SiS_VT = NTSCVT;
3403         } else {
3404            SiS_Pr->SiS_HT = NTSCHT;
3405            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3406            SiS_Pr->SiS_VT = NTSCVT;
3407         }
3408 
3409      } else {
3410 
3411         SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3412         SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3413         SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3414         SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3415 
3416         if(modeflag & HalfDCLK) {
3417            SiS_Pr->SiS_RY1COE = 0x00;
3418            SiS_Pr->SiS_RY2COE = 0xf4;
3419            SiS_Pr->SiS_RY3COE = 0x10;
3420            SiS_Pr->SiS_RY4COE = 0x38;
3421         }
3422 
3423         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3424            SiS_Pr->SiS_HT = NTSCHT;
3425            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3426            SiS_Pr->SiS_VT = NTSCVT;
3427         } else {
3428            SiS_Pr->SiS_HT = PALHT;
3429            SiS_Pr->SiS_VT = PALVT;
3430         }
3431 
3432      }
3433 
3434   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3435 
3436      SiS_Pr->SiS_RVBHCMAX  = 1;
3437      SiS_Pr->SiS_RVBHCFACT = 1;
3438 
3439      if(SiS_Pr->UseCustomMode) {
3440 
3441         SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3442         SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3443 
3444         tempax = SiS_Pr->CHTotal;
3445         if(modeflag & HalfDCLK) tempax <<= 1;
3446         SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3447         SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3448 
3449      } else {
3450 
3451         bool gotit = false;
3452 
3453         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3454 
3455            SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3456            SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3457            SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3458            SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3459            gotit = true;
3460 
3461         } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3462 
3463 #ifdef SIS315H
3464            SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3465            SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3466            SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3467            SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3468            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3469            SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3470            SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3471            if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3472               SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3473               tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3474               if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3475               else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3476            }
3477            if(SiS_Pr->SiS_VGAHT) gotit = true;
3478            else {
3479               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3480               SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3481               SiS_Pr->SiS_RVBHCMAX  = 1;
3482               SiS_Pr->SiS_RVBHCFACT = 1;
3483               SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3484               SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3485               SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3486               SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3487               SiS_Pr->SiS_RVBHRS2 = 0;
3488               gotit = true;
3489            }
3490 #endif
3491 
3492         }
3493 
3494         if(!gotit) {
3495 
3496            SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3497                           &CRT2Index,&ResIndex);
3498 
3499            switch(CRT2Index) {
3500               case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3501               case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3502               case Panel_1280x720      :
3503               case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3504               case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3505               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3506               case Panel_1280x800      :
3507               case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3508               case Panel_1280x800_2    :
3509               case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3510               case Panel_1280x854      :
3511               case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3512               case Panel_1280x960      :
3513               case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3514               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3515               case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3516               case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3517               case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3518               case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3519               case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3520               case Panel_1680x1050     :
3521               case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3522               case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
3523 #ifdef SIS315H
3524               case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3525               case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3526 #endif
3527               default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3528            }
3529 
3530 #ifdef SIS_XORG_XF86
3531 #ifdef TWDEBUG
3532            xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3533 #endif
3534 #endif
3535 
3536            SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3537            SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3538            SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3539            SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3540            SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3541            SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3542 
3543         }
3544 
3545         tempax = SiS_Pr->PanelXRes;
3546         tempbx = SiS_Pr->PanelYRes;
3547 
3548         switch(SiS_Pr->SiS_LCDResInfo) {
3549         case Panel_1024x768:
3550            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3551               if(SiS_Pr->ChipType < SIS_315H) {
3552                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3553                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3554               }
3555            } else {
3556               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3557               else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3558               else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3559               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3560               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3561               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3562            }
3563            break;
3564         case Panel_1280x960:
3565            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3566            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3567            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3568            break;
3569         case Panel_1280x1024:
3570            if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3571            else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3572            else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3573            break;
3574         case Panel_1600x1200:
3575            if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3576               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3577               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3578            }
3579            break;
3580         }
3581 
3582         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3583            tempax = SiS_Pr->SiS_VGAHDE;
3584            tempbx = SiS_Pr->SiS_VGAVDE;
3585         }
3586 
3587         SiS_Pr->SiS_HDE = tempax;
3588         SiS_Pr->SiS_VDE = tempbx;
3589      }
3590   }
3591 }
3592 
3593 static void
3594 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3595                 unsigned short RefreshRateTableIndex)
3596 {
3597 
3598    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3599 
3600       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3601          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3602       } else {
3603          if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3604             /* Need LVDS Data for LCD on 301B-DH */
3605             SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3606          } else {
3607             SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3608          }
3609       }
3610 
3611    } else {
3612 
3613       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3614 
3615    }
3616 }
3617 
3618 /*********************************************/
3619 /*         GET LVDS DES (SKEW) DATA          */
3620 /*********************************************/
3621 
3622 static const struct SiS_LVDSDes *
3623 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3624 {
3625    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3626 
3627 #ifdef SIS300
3628    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3629 
3630       if(SiS_Pr->ChipType < SIS_315H) {
3631          if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3632             if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3633                PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3634                if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3635                   PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3636                }
3637             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3638                PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3639                if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3640                   PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3641                }
3642             }
3643          }
3644       }
3645    }
3646 #endif
3647    return PanelDesPtr;
3648 }
3649 
3650 static void
3651 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3652                    unsigned short RefreshRateTableIndex)
3653 {
3654   unsigned short modeflag, ResIndex;
3655   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3656 
3657   SiS_Pr->SiS_LCDHDES = 0;
3658   SiS_Pr->SiS_LCDVDES = 0;
3659 
3660   /* Some special cases */
3661   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3662 
3663      /* Trumpion */
3664      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3665         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3666            if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3667               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3668            }
3669         }
3670         return;
3671      }
3672 
3673      /* 640x480 on LVDS */
3674      if(SiS_Pr->ChipType < SIS_315H) {
3675         if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3676            SiS_Pr->SiS_LCDHDES = 8;
3677            if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3678            else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3679            else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3680            return;
3681         }
3682      }
3683 
3684   } /* LCD */
3685 
3686   if( (SiS_Pr->UseCustomMode)                    ||
3687       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3688       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3689       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3690       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3691      return;
3692   }
3693 
3694   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3695   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3696 
3697   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3698 
3699 #ifdef SIS315H
3700      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3701         /* non-pass 1:1 only, see above */
3702         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3703            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3704         }
3705         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3706            SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3707         }
3708      }
3709      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3710         switch(SiS_Pr->SiS_CustomT) {
3711         case CUT_UNIWILL1024:
3712         case CUT_UNIWILL10242:
3713         case CUT_CLEVO1400:
3714            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3715               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3716            }
3717            break;
3718         }
3719         switch(SiS_Pr->SiS_LCDResInfo) {
3720         case Panel_1280x1024:
3721            if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3722               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3723            }
3724            break;
3725         case Panel_1280x800:    /* Verified for Averatec 6240 */
3726         case Panel_1280x800_2:  /* Verified for Asus A4L */
3727         case Panel_1280x854:    /* Not verified yet FIXME */
3728            SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3729            break;
3730         }
3731      }
3732 #endif
3733 
3734   } else {
3735 
3736      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3737 
3738         if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3739            if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3740         }
3741 
3742      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3743 
3744         SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3745         SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3746 
3747      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3748 
3749         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3750            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3751         }
3752         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3753            SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3754         } else {
3755            if(SiS_Pr->ChipType < SIS_315H) {
3756               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3757            } else {
3758               switch(SiS_Pr->SiS_LCDResInfo) {
3759               case Panel_800x600:
3760               case Panel_1024x768:
3761               case Panel_1280x1024:
3762                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3763                  break;
3764               case Panel_1400x1050:
3765                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3766                  break;
3767               }
3768            }
3769         }
3770 
3771      } else {
3772 
3773         if(SiS_Pr->ChipType < SIS_315H) {
3774 #ifdef SIS300
3775            switch(SiS_Pr->SiS_LCDResInfo) {
3776            case Panel_800x600:
3777               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3778                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3779               } else {
3780                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3781                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3782                  if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3783                  else                          SiS_Pr->SiS_LCDVDES -= 4;
3784               }
3785               break;
3786            case Panel_1024x768:
3787               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3788                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3789               } else {
3790                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3791                  if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3792                  if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3793               }
3794               break;
3795            case Panel_1024x600:
3796            default:
3797               if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3798                   (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3799                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3800               } else {
3801                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3802               }
3803               break;
3804            }
3805 
3806            switch(SiS_Pr->SiS_LCDTypeInfo) {
3807            case 1:
3808               SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3809               break;
3810            case 3: /* 640x480 only? */
3811               SiS_Pr->SiS_LCDHDES = 8;
3812               if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3813               else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3814               else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3815               break;
3816            }
3817 #endif
3818         } else {
3819 #ifdef SIS315H
3820            switch(SiS_Pr->SiS_LCDResInfo) {
3821            case Panel_1024x768:
3822            case Panel_1280x1024:
3823               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3824                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3825               }
3826               break;
3827            case Panel_320x240_1:
3828            case Panel_320x240_2:
3829            case Panel_320x240_3:
3830               SiS_Pr->SiS_LCDVDES = 524;
3831               break;
3832            }
3833 #endif
3834         }
3835      }
3836 
3837      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3838         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3839         if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3840            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3841         } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3842            if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3843               if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3844                  if(SiS_Pr->ChipType < SIS_315H) {
3845                     if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3846                  } else {
3847 #ifdef SIS315H
3848                     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
3849                     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3850                     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3851                     if(!(modeflag & HalfDCLK)) {
3852                        SiS_Pr->SiS_LCDHDES = 320;
3853                        if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3854                        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3855                     }
3856 #endif
3857                  }
3858               }
3859            }
3860         }
3861      }
3862   }
3863 }
3864 
3865 /*********************************************/
3866 /*           DISABLE VIDEO BRIDGE            */
3867 /*********************************************/
3868 
3869 #ifdef SIS315H
3870 static int
3871 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3872 {
3873    int ret = 0;
3874 #ifdef SET_PWD
3875    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3876    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3877    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3878    unsigned short temp;
3879 
3880    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3881        (romptr)                         &&
3882        (SiS_Pr->SiS_PWDOffset) ) {
3883       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3884       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3885       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3886       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3887       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3888       temp = 0x00;
3889       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3890          temp = 0x80;
3891          ret = 1;
3892       }
3893       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3894 #ifdef SIS_XORG_XF86
3895 #ifdef TWDEBUG
3896       xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3897 #endif
3898 #endif
3899    }
3900 #endif
3901    return ret;
3902 }
3903 #endif
3904 
3905 /* NEVER use any variables (VBInfo), this will be called
3906  * from outside the context of modeswitch!
3907  * MUST call getVBType before calling this
3908  */
3909 void
3910 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3911 {
3912 #ifdef SIS315H
3913   unsigned short tempah, pushax=0, modenum;
3914 #endif
3915   unsigned short temp=0;
3916 
3917   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3918 
3919      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {            /* ===== For 30xB/C/LV ===== */
3920 
3921         if(SiS_Pr->ChipType < SIS_315H) {
3922 
3923 #ifdef SIS300      /* 300 series */
3924 
3925            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3926               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3927                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3928               } else {
3929                  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3930               }
3931               SiS_PanelDelay(SiS_Pr, 3);
3932            }
3933            if(SiS_Is301B(SiS_Pr)) {
3934               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3935               SiS_ShortDelay(SiS_Pr,1);
3936            }
3937            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3938            SiS_DisplayOff(SiS_Pr);
3939            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3940            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3941            SiS_UnLockCRT2(SiS_Pr);
3942            if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3943               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3944               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3945            }
3946            if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3947                (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3948               SiS_PanelDelay(SiS_Pr, 2);
3949               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3950                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3951               } else {
3952                  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3953               }
3954            }
3955 
3956 #endif  /* SIS300 */
3957 
3958         } else {
3959 
3960 #ifdef SIS315H     /* 315 series */
3961 
3962            int didpwd = 0;
3963            bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3964                           (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3965 
3966            modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3967 
3968            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3969 
3970 #ifdef SET_EMI
3971               if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3972                  if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3973                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3974                  }
3975               }
3976 #endif
3977 
3978               didpwd = SiS_HandlePWD(SiS_Pr);
3979 
3980               if( (modenum <= 0x13)           ||
3981                   (SiS_IsVAMode(SiS_Pr))      ||
3982                   (!(SiS_IsDualEdge(SiS_Pr))) ) {
3983                  if(!didpwd) {
3984                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3985                     if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3986                  } else {
3987                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3988                  }
3989               }
3990 
3991               if(!custom1) {
3992                  SiS_DDC2Delay(SiS_Pr,0xff00);
3993                  SiS_DDC2Delay(SiS_Pr,0xe000);
3994                  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3995                  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3996                  if(IS_SIS740) {
3997                     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3998                  }
3999                  SiS_PanelDelay(SiS_Pr, 3);
4000               }
4001 
4002            }
4003 
4004            if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4005               /* if(SiS_Pr->ChipType < SIS_340) {*/
4006                  tempah = 0xef;
4007                  if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4008                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4009               /*}*/
4010            }
4011 
4012            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4013               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4014            }
4015 
4016            tempah = 0x3f;
4017            if(SiS_IsDualEdge(SiS_Pr)) {
4018               tempah = 0x7f;
4019               if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4020            }
4021            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4022 
4023            if((SiS_IsVAMode(SiS_Pr)) ||
4024               ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4025 
4026               SiS_DisplayOff(SiS_Pr);
4027               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4028                  SiS_PanelDelay(SiS_Pr, 2);
4029               }
4030               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4031               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4032 
4033            }
4034 
4035            if((!(SiS_IsVAMode(SiS_Pr))) ||
4036               ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4037 
4038               if(!(SiS_IsDualEdge(SiS_Pr))) {
4039                  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4040                  SiS_DisplayOff(SiS_Pr);
4041               }
4042               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4043 
4044               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4045                  SiS_PanelDelay(SiS_Pr, 2);
4046               }
4047 
4048               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4049               temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4050               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4051               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4052               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4053 
4054            }
4055 
4056            if(SiS_IsNotM650orLater(SiS_Pr)) {
4057               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4058            }
4059 
4060            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4061 
4062               if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4063                   (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4064                   (!(SiS_IsDualEdge(SiS_Pr))) ) {
4065 
4066                  if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4067                  if(!didpwd) {
4068                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4069                  }
4070                  if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4071               }
4072 
4073               if(!custom1) {
4074                  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4075                  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4076                     if(SiS_IsVAorLCD(SiS_Pr)) {
4077                        SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4078                     }
4079                  }
4080               }
4081 
4082            }
4083 
4084 #endif /* SIS315H */
4085 
4086         }
4087 
4088      } else {     /* ============ For 301 ================ */
4089 
4090         if(SiS_Pr->ChipType < SIS_315H) {
4091 #ifdef SIS300
4092            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4093               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4094               SiS_PanelDelay(SiS_Pr, 3);
4095            }
4096 #endif
4097         }
4098 
4099         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4100         SiS_DisplayOff(SiS_Pr);
4101 
4102         if(SiS_Pr->ChipType >= SIS_315H) {
4103            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4104         }
4105 
4106         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4107 
4108         if(SiS_Pr->ChipType >= SIS_315H) {
4109             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4110             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4111             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4112             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4113         } else {
4114 #ifdef SIS300
4115             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4116             if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4117                 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4118                 SiS_PanelDelay(SiS_Pr, 2);
4119                 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4120             }
4121 #endif
4122         }
4123 
4124       }
4125 
4126   } else {     /* ============ For LVDS =============*/
4127 
4128     if(SiS_Pr->ChipType < SIS_315H) {
4129 
4130 #ifdef SIS300   /* 300 series */
4131 
4132         if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4133            SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4134         }
4135 
4136         if(SiS_Pr->ChipType == SIS_730) {
4137            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4138               SiS_WaitVBRetrace(SiS_Pr);
4139            }
4140            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4141               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4142               SiS_PanelDelay(SiS_Pr, 3);
4143            }
4144         } else {
4145            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4146               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4147                  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4148                     SiS_WaitVBRetrace(SiS_Pr);
4149                     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4150                        SiS_DisplayOff(SiS_Pr);
4151                     }
4152                     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4153                     SiS_PanelDelay(SiS_Pr, 3);
4154                  }
4155               }
4156            }
4157         }
4158 
4159         SiS_DisplayOff(SiS_Pr);
4160 
4161         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4162 
4163         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4164         SiS_UnLockCRT2(SiS_Pr);
4165         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4166         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4167 
4168         if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4169             (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4170            SiS_PanelDelay(SiS_Pr, 2);
4171            SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4172         }
4173 
4174 #endif  /* SIS300 */
4175 
4176     } else {
4177 
4178 #ifdef SIS315H  /* 315 series */
4179 
4180         if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4181            /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4182               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4183            /* } */
4184         }
4185 
4186         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4187 
4188            if(SiS_Pr->ChipType == SIS_740) {
4189               temp = SiS_GetCH701x(SiS_Pr,0x61);
4190               if(temp < 1) {
4191                  SiS_SetCH701x(SiS_Pr,0x76,0xac);
4192                  SiS_SetCH701x(SiS_Pr,0x66,0x00);
4193               }
4194 
4195               if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4196                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4197                  SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4198               }
4199            }
4200 
4201            if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4202                (SiS_IsVAMode(SiS_Pr)) ) {
4203               SiS_Chrontel701xBLOff(SiS_Pr);
4204               SiS_Chrontel701xOff(SiS_Pr);
4205            }
4206 
4207            if(SiS_Pr->ChipType != SIS_740) {
4208               if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4209                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4210                  SiS_SetCH701x(SiS_Pr,0x49,0x01);
4211               }
4212            }
4213 
4214         }
4215 
4216         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4217            SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4218            SiS_PanelDelay(SiS_Pr, 3);
4219         }
4220 
4221         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4222             (!(SiS_IsDualEdge(SiS_Pr))) ||
4223             (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4224            SiS_DisplayOff(SiS_Pr);
4225         }
4226 
4227         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4228             (!(SiS_IsDualEdge(SiS_Pr))) ||
4229             (!(SiS_IsVAMode(SiS_Pr))) ) {
4230            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4231         }
4232 
4233         if(SiS_Pr->ChipType == SIS_740) {
4234            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4235         }
4236 
4237         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4238 
4239         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4240             (!(SiS_IsDualEdge(SiS_Pr))) ||
4241             (!(SiS_IsVAMode(SiS_Pr))) ) {
4242            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4243         }
4244 
4245         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4246            if(SiS_CRT2IsLCD(SiS_Pr)) {
4247               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4248               if(SiS_Pr->ChipType == SIS_550) {
4249                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4250                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4251               }
4252            }
4253         } else {
4254            if(SiS_Pr->ChipType == SIS_740) {
4255               if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4256                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4257               }
4258            } else if(SiS_IsVAMode(SiS_Pr)) {
4259               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4260            }
4261         }
4262 
4263         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4264            if(SiS_IsDualEdge(SiS_Pr)) {
4265               /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4266            } else {
4267               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4268            }
4269         }
4270 
4271         SiS_UnLockCRT2(SiS_Pr);
4272 
4273         if(SiS_Pr->ChipType == SIS_550) {
4274            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4275            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4276         } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4277                    (!(SiS_IsDualEdge(SiS_Pr))) ||
4278                    (!(SiS_IsVAMode(SiS_Pr))) ) {
4279            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4280         }
4281 
4282         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4283            if(SiS_CRT2IsLCD(SiS_Pr)) {
4284               if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4285                  SiS_PanelDelay(SiS_Pr, 2);
4286                  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4287               }
4288            }
4289         }
4290 
4291 #endif  /* SIS315H */
4292 
4293     }  /* 315 series */
4294 
4295   }  /* LVDS */
4296 
4297 }
4298 
4299 /*********************************************/
4300 /*            ENABLE VIDEO BRIDGE            */
4301 /*********************************************/
4302 
4303 /* NEVER use any variables (VBInfo), this will be called
4304  * from outside the context of a mode switch!
4305  * MUST call getVBType before calling this
4306  */
4307 #ifdef SIS_LINUX_KERNEL
4308 static
4309 #endif
4310 void
4311 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4312 {
4313   unsigned short temp=0, tempah;
4314 #ifdef SIS315H
4315   unsigned short temp1, pushax=0;
4316   bool delaylong = false;
4317 #endif
4318 
4319   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4320 
4321     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {             /* ====== For 301B et al  ====== */
4322 
4323       if(SiS_Pr->ChipType < SIS_315H) {
4324 
4325 #ifdef SIS300     /* 300 series */
4326 
4327          if(SiS_CRT2IsLCD(SiS_Pr)) {
4328             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4329                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4330             } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4331                SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4332             }
4333             if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4334                if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4335                   SiS_PanelDelay(SiS_Pr, 0);
4336                }
4337             }
4338          }
4339 
4340          if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4341             (SiS_CRT2IsLCD(SiS_Pr))) {
4342 
4343             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* Enable CRT2 */
4344             SiS_DisplayOn(SiS_Pr);
4345             SiS_UnLockCRT2(SiS_Pr);
4346             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4347             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4348                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4349             } else {
4350                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4351             }
4352             if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4353                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4354                   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4355                      SiS_PanelDelay(SiS_Pr, 1);
4356                   }
4357                   SiS_WaitVBRetrace(SiS_Pr);
4358                   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4359                }
4360             }
4361 
4362          } else {
4363 
4364             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4365             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4366                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4367                if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4368             }
4369             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4370             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4371             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4372             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4373             SiS_DisplayOn(SiS_Pr);
4374             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4375                if(SiS_CRT2IsLCD(SiS_Pr)) {
4376                   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4377                      if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4378                         SiS_PanelDelay(SiS_Pr, 1);
4379                      }
4380                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4381                   }
4382                }
4383             }
4384 
4385          }
4386 
4387 
4388 #endif /* SIS300 */
4389 
4390       } else {
4391 
4392 #ifdef SIS315H    /* 315 series */
4393 
4394 #ifdef SET_EMI
4395          unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4396          int didpwd = 0;
4397          /* unsigned short  emidelay=0; */
4398 #endif
4399 
4400          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4401             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4402 #ifdef SET_EMI
4403             if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4404                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4405             }
4406 #endif
4407          }
4408 
4409          if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4410             /*if(SiS_Pr->ChipType < SIS_340) { */
4411                tempah = 0x10;
4412                if(SiS_LCDAEnabled(SiS_Pr)) {
4413                   if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4414                   else                      tempah = 0x08;
4415                }
4416                SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4417             /*}*/
4418          }
4419 
4420          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4421 
4422             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4423             SiS_DisplayOff(SiS_Pr);
4424             pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4425             if(IS_SIS740) {
4426                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4427             }
4428 
4429             didpwd = SiS_HandlePWD(SiS_Pr);
4430 
4431             if(SiS_IsVAorLCD(SiS_Pr)) {
4432                if(!didpwd) {
4433                   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4434                      SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4435                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4436                      SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4437                      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4438                         SiS_GenericDelay(SiS_Pr, 17664);
4439                      }
4440                   }
4441                } else {
4442                   SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4443                   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4444                      SiS_GenericDelay(SiS_Pr, 17664);
4445                   }
4446                }
4447             }
4448 
4449             if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4450                SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4451                delaylong = true;
4452             }
4453 
4454          }
4455 
4456          if(!(SiS_IsVAMode(SiS_Pr))) {
4457 
4458             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4459             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4460                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4461                if(!(tempah & SetCRT2ToRAMDAC)) {
4462                   if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4463                }
4464             }
4465             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4466 
4467             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4468 
4469             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4470             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4471 
4472             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4473                SiS_PanelDelay(SiS_Pr, 2);
4474             }
4475 
4476          } else {
4477 
4478             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4479 
4480          }
4481 
4482          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4483          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4484 
4485          if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4486             if( (SiS_LCDAEnabled(SiS_Pr)) ||
4487                 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4488                /* Enable "LVDS PLL power on" (even on 301C) */
4489                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4490                /* Enable "LVDS Driver Power on" (even on 301C) */
4491                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4492             }
4493          }
4494 
4495          tempah = 0xc0;
4496          if(SiS_IsDualEdge(SiS_Pr)) {
4497             tempah = 0x80;
4498             if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4499          }
4500          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4501 
4502          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4503 
4504             SiS_PanelDelay(SiS_Pr, 2);
4505 
4506             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4507             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4508 
4509             if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4510 #ifdef SET_EMI
4511                if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4512                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4513                   SiS_GenericDelay(SiS_Pr, 2048);
4514                }
4515 #endif
4516                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4517 
4518                if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4519 #ifdef SET_EMI
4520                   cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4521 
4522                   if(SiS_Pr->SiS_ROMNew) {
4523                      unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4524                      unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4525                      if(romptr) {
4526                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4527                         SiS_Pr->EMI_30 = 0;
4528                         SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4529                         SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4530                         SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4531                         if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4532                         /* emidelay = SISGETROMW((romptr + 0x22)); */
4533                         SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4534                      }
4535                   }
4536 
4537                   /*                                              (P4_30|0x40)  */
4538                   /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4539                   /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4540                   /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4541                   /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4542                   /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4543                   /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4544                   /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4545                   /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4546                   /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4547 
4548                   if(SiS_Pr->HaveEMI) {
4549                      r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4550                      r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4551                   } else {
4552                      r30 = 0;
4553                   }
4554 
4555                   /* EMI_30 is read at driver start; however, the BIOS sets this
4556                    * (if it is used) only if the LCD is in use. In case we caught
4557                    * the machine while on TV output, this bit is not set and we
4558                    * don't know if it should be set - hence our detection is wrong.
4559                    * Work-around this here:
4560                    */
4561 
4562                   if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4563                      switch((cr36 & 0x0f)) {
4564                      case 2:
4565                         r30 |= 0x40;
4566                         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4567                         if(!SiS_Pr->HaveEMI) {
4568                            r31 = 0x05; r32 = 0x60; r33 = 0x33;
4569                            if((cr36 & 0xf0) == 0x30) {
4570                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4571                            }
4572                         }
4573                         break;
4574                      case 3:  /* 1280x1024 */
4575                         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4576                         if(!SiS_Pr->HaveEMI) {
4577                            r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4578                            if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4579                               r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4580                            }
4581                         }
4582                         break;
4583                      case 9:  /* 1400x1050 */
4584                         r30 |= 0x40;
4585                         if(!SiS_Pr->HaveEMI) {
4586                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4587                            if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4588                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4589                            }
4590                         }
4591                         break;
4592                      case 11: /* 1600x1200 - unknown */
4593                         r30 |= 0x40;
4594                         if(!SiS_Pr->HaveEMI) {
4595                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4596                         }
4597                      }
4598                   }
4599 
4600                   /* BIOS values don't work so well sometimes */
4601                   if(!SiS_Pr->OverruleEMI) {
4602 #ifdef COMPAL_HACK
4603                      if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4604                         if((cr36 & 0x0f) == 0x09) {
4605                            r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4606                         }
4607                      }
4608 #endif
4609 #ifdef COMPAQ_HACK
4610                      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4611                         if((cr36 & 0x0f) == 0x03) {
4612                            r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4613                         }
4614                      }
4615 #endif
4616 #ifdef ASUS_HACK
4617                      if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4618                         if((cr36 & 0x0f) == 0x02) {
4619                            /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4620                            /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4621                            /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4622                            /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4623                         }
4624                      }
4625 #endif
4626                   }
4627 
4628                   if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4629                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4630                      SiS_GenericDelay(SiS_Pr, 2048);
4631                   }
4632                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4633                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4634                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4635 #endif  /* SET_EMI */
4636 
4637                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4638 
4639 #ifdef SET_EMI
4640                   if( (SiS_LCDAEnabled(SiS_Pr)) ||
4641                       (SiS_CRT2IsLCD(SiS_Pr)) ) {
4642                      if(r30 & 0x40) {
4643                         /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4644                         SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4645                         if(delaylong) {
4646                            SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4647                            delaylong = false;
4648                         }
4649                         SiS_WaitVBRetrace(SiS_Pr);
4650                         SiS_WaitVBRetrace(SiS_Pr);
4651                         if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4652                            SiS_GenericDelay(SiS_Pr, 1280);
4653                         }
4654                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4655                         /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4656                      }
4657                   }
4658 #endif
4659                }
4660             }
4661 
4662             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4663                if(SiS_IsVAorLCD(SiS_Pr)) {
4664                   SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4665                   if(delaylong) {
4666                      SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4667                   }
4668                   SiS_WaitVBRetrace(SiS_Pr);
4669                   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4670                      SiS_GenericDelay(SiS_Pr, 2048);
4671                      SiS_WaitVBRetrace(SiS_Pr);
4672                   }
4673                   if(!didpwd) {
4674                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4675                   } else {
4676                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4677                   }
4678                }
4679             }
4680 
4681             SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4682             SiS_DisplayOn(SiS_Pr);
4683             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4684 
4685          }
4686 
4687          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4688             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4689          }
4690 
4691 #endif /* SIS315H */
4692 
4693       }
4694 
4695     } else {    /* ============  For 301 ================ */
4696 
4697        if(SiS_Pr->ChipType < SIS_315H) {
4698           if(SiS_CRT2IsLCD(SiS_Pr)) {
4699              SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4700              SiS_PanelDelay(SiS_Pr, 0);
4701           }
4702        }
4703 
4704        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4705        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707           if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4708        }
4709        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4710 
4711        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4712 
4713        if(SiS_Pr->ChipType >= SIS_315H) {
4714           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4715           if(!(temp & 0x80)) {
4716              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4717           }
4718        }
4719 
4720        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4721 
4722        SiS_VBLongWait(SiS_Pr);
4723        SiS_DisplayOn(SiS_Pr);
4724        if(SiS_Pr->ChipType >= SIS_315H) {
4725           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4726        }
4727        SiS_VBLongWait(SiS_Pr);
4728 
4729        if(SiS_Pr->ChipType < SIS_315H) {
4730           if(SiS_CRT2IsLCD(SiS_Pr)) {
4731              SiS_PanelDelay(SiS_Pr, 1);
4732              SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4733           }
4734        }
4735 
4736     }
4737 
4738   } else {   /* =================== For LVDS ================== */
4739 
4740     if(SiS_Pr->ChipType < SIS_315H) {
4741 
4742 #ifdef SIS300    /* 300 series */
4743 
4744        if(SiS_CRT2IsLCD(SiS_Pr)) {
4745           if(SiS_Pr->ChipType == SIS_730) {
4746              SiS_PanelDelay(SiS_Pr, 1);
4747              SiS_PanelDelay(SiS_Pr, 1);
4748              SiS_PanelDelay(SiS_Pr, 1);
4749           }
4750           SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4751           if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4752              SiS_PanelDelay(SiS_Pr, 0);
4753           }
4754        }
4755 
4756        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4757        SiS_DisplayOn(SiS_Pr);
4758        SiS_UnLockCRT2(SiS_Pr);
4759        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4760        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4761           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4762        } else {
4763           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4764        }
4765 
4766        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4767           if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4768              SiS_WaitVBRetrace(SiS_Pr);
4769              SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4770           }
4771        }
4772 
4773        if(SiS_CRT2IsLCD(SiS_Pr)) {
4774           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4775              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4776                 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4777                    SiS_PanelDelay(SiS_Pr, 1);
4778                    SiS_PanelDelay(SiS_Pr, 1);
4779                 }
4780                 SiS_WaitVBRetrace(SiS_Pr);
4781                 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4782              }
4783           }
4784        }
4785 
4786 #endif  /* SIS300 */
4787 
4788     } else {
4789 
4790 #ifdef SIS315H    /* 315 series */
4791 
4792        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4793           /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
4794              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4795           /*}*/
4796        }
4797 
4798        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4799           if(SiS_CRT2IsLCD(SiS_Pr)) {
4800              SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4801              SiS_PanelDelay(SiS_Pr, 0);
4802           }
4803        }
4804 
4805        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4806        SiS_UnLockCRT2(SiS_Pr);
4807 
4808        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4809 
4810        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4811           temp = SiS_GetCH701x(SiS_Pr,0x66);
4812           temp &= 0x20;
4813           SiS_Chrontel701xBLOff(SiS_Pr);
4814        }
4815 
4816        if(SiS_Pr->ChipType != SIS_550) {
4817           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4818        }
4819 
4820        if(SiS_Pr->ChipType == SIS_740) {
4821           if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4822              if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4823                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4824              }
4825           }
4826        }
4827 
4828        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4829        if(!(temp1 & 0x80)) {
4830           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4831        }
4832 
4833        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4834           if(temp) {
4835              SiS_Chrontel701xBLOn(SiS_Pr);
4836           }
4837        }
4838 
4839        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4840           if(SiS_CRT2IsLCD(SiS_Pr)) {
4841              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4842              if(SiS_Pr->ChipType == SIS_550) {
4843                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4844                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4845              }
4846           }
4847        } else if(SiS_IsVAMode(SiS_Pr)) {
4848           if(SiS_Pr->ChipType != SIS_740) {
4849              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4850           }
4851        }
4852 
4853        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4854           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4855        }
4856 
4857        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4858           if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4859              SiS_Chrontel701xOn(SiS_Pr);
4860           }
4861           if( (SiS_IsVAMode(SiS_Pr)) ||
4862               (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4863              SiS_ChrontelDoSomething1(SiS_Pr);
4864           }
4865        }
4866 
4867        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4868           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4869              if( (SiS_IsVAMode(SiS_Pr)) ||
4870                  (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4871                 SiS_Chrontel701xBLOn(SiS_Pr);
4872                 SiS_ChrontelInitTVVSync(SiS_Pr);
4873              }
4874           }
4875        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4876           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4877              if(SiS_CRT2IsLCD(SiS_Pr)) {
4878                 SiS_PanelDelay(SiS_Pr, 1);
4879                 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4880              }
4881           }
4882        }
4883 
4884 #endif  /* SIS315H */
4885 
4886     } /* 310 series */
4887 
4888   }  /* LVDS */
4889 
4890 }
4891 
4892 /*********************************************/
4893 /*         SET PART 1 REGISTER GROUP         */
4894 /*********************************************/
4895 
4896 /* Set CRT2 OFFSET / PITCH */
4897 static void
4898 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4899                 unsigned short RRTI)
4900 {
4901    unsigned short offset;
4902    unsigned char  temp;
4903 
4904    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4905 
4906    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4907 
4908    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4909    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4910 
4911    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4912    if(offset & 0x07) temp++;
4913    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4914 }
4915 
4916 /* Set CRT2 sync and PanelLink mode */
4917 static void
4918 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4919 {
4920    unsigned short tempah=0, tempbl, infoflag;
4921 
4922    tempbl = 0xC0;
4923 
4924    if(SiS_Pr->UseCustomMode) {
4925       infoflag = SiS_Pr->CInfoFlag;
4926    } else {
4927       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4928    }
4929 
4930    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                   /* LVDS */
4931 
4932       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4933          tempah = 0;
4934       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4935          tempah = SiS_Pr->SiS_LCDInfo;
4936       } else tempah = infoflag >> 8;
4937       tempah &= 0xC0;
4938       tempah |= 0x20;
4939       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4940       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4941          if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4942             (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4943             tempah |= 0xf0;
4944          }
4945          if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4946              (SiS_Pr->SiS_IF_DEF_DSTN) ||
4947              (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4948              (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4949              (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4950             tempah |= 0x30;
4951          }
4952          if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4953              (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4954             tempah &= ~0xc0;
4955          }
4956       }
4957       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4958          if(SiS_Pr->ChipType >= SIS_315H) {
4959             tempah >>= 3;
4960             tempah &= 0x18;
4961             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4962             /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4963          } else {
4964             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4965          }
4966       } else {
4967          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4968       }
4969 
4970    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4971 
4972       if(SiS_Pr->ChipType < SIS_315H) {
4973 
4974 #ifdef SIS300  /* ---- 300 series --- */
4975 
4976          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {                        /* 630 - 301B(-DH) */
4977 
4978             tempah = infoflag >> 8;
4979             tempbl = 0;
4980             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4981                if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4982                   tempah = SiS_Pr->SiS_LCDInfo;
4983                   tempbl = (tempah >> 6) & 0x03;
4984                }
4985             }
4986             tempah &= 0xC0;
4987             tempah |= 0x20;
4988             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4989             tempah |= 0xc0;
4990             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4991             if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4992                SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4993             }
4994 
4995          } else {                                                       /* 630 - 301 */
4996 
4997             tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4998             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4999             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5000 
5001          }
5002 
5003 #endif /* SIS300 */
5004 
5005       } else {
5006 
5007 #ifdef SIS315H  /* ------- 315 series ------ */
5008 
5009          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {                  /* 315 - LVDS */
5010 
5011             tempbl = 0;
5012             if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5013                (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5014                tempah = infoflag >> 8;
5015                if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5016                  tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5017                }
5018             } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5019                       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5020                tempah = infoflag >> 8;
5021                tempbl = 0x03;
5022             } else {
5023                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5024                tempbl = (tempah >> 6) & 0x03;
5025                tempbl |= 0x08;
5026                if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5027             }
5028             tempah &= 0xC0;
5029             tempah |= 0x20;
5030             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5031             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5032             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5033             if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5034                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5035                   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5036                }
5037             }
5038 
5039          } else {                                                       /* 315 - TMDS */
5040 
5041             tempah = tempbl = infoflag >> 8;
5042             if(!SiS_Pr->UseCustomMode) {
5043                tempbl = 0;
5044                if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5045                   if(ModeNo <= 0x13) {
5046                      tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5047                   }
5048                }
5049                if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5050                   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5051                     if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5052                        tempah = SiS_Pr->SiS_LCDInfo;
5053                        tempbl = (tempah >> 6) & 0x03;
5054                     }
5055                   }
5056                }
5057             }
5058             tempah &= 0xC0;
5059             tempah |= 0x20;
5060             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5061             if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5062                /* Imitate BIOS bug */
5063                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5064             }
5065             if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5066                tempah >>= 3;
5067                tempah &= 0x18;
5068                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5069             } else {
5070                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5071                if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5072                   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5073                      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5074                   }
5075                }
5076             }
5077 
5078          }
5079 #endif  /* SIS315H */
5080       }
5081    }
5082 }
5083 
5084 /* Set CRT2 FIFO on 300/540/630/730 */
5085 #ifdef SIS300
5086 static void
5087 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5088 {
5089   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5090   unsigned short temp, index, modeidindex, refreshratetableindex;
5091   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5092   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5093   unsigned int   data, pci50, pciA0;
5094   static const unsigned char colortharray[] = {
5095         1, 1, 2, 2, 3, 4
5096   };
5097 
5098   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5099 
5100   if(!SiS_Pr->CRT1UsesCustomMode) {
5101 
5102      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5103      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5104      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5105      SiS_Pr->SiS_SelectCRT2Rate = 0;
5106      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5107 
5108      if(CRT1ModeNo >= 0x13) {
5109         /* Get VCLK */
5110         index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5111         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5112 
5113         /* Get colordepth */
5114         colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5115         if(!colorth) colorth++;
5116      }
5117 
5118   } else {
5119 
5120      CRT1ModeNo = 0xfe;
5121 
5122      /* Get VCLK */
5123      VCLK = SiS_Pr->CSRClock_CRT1;
5124 
5125      /* Get color depth */
5126      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5127 
5128   }
5129 
5130   if(CRT1ModeNo >= 0x13) {
5131      /* Get MCLK */
5132      if(SiS_Pr->ChipType == SIS_300) {
5133         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5134      } else {
5135         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5136      }
5137      index &= 0x07;
5138      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5139 
5140      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5141      if(!temp) temp++;
5142      temp <<= 2;
5143 
5144      data2 = temp - ((colorth * VCLK) / MCLK);
5145 
5146      temp = (28 * 16) % data2;
5147      data2 = (28 * 16) / data2;
5148      if(temp) data2++;
5149 
5150      if(SiS_Pr->ChipType == SIS_300) {
5151 
5152         SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5153         data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5154 
5155      } else {
5156 
5157 #ifdef SIS_LINUX_KERNEL
5158         pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5159         pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5160 #else
5161         pci50 = pciReadLong(0x00000000, 0x50);
5162         pciA0 = pciReadLong(0x00000000, 0xA0);
5163 #endif
5164 
5165         if(SiS_Pr->ChipType == SIS_730) {
5166 
5167            index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5168            index += (unsigned short)(((pci50 >> 9)) & 0x03);
5169 
5170            /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5171            index = 0;  /* -- do it like the BIOS anyway... */
5172 
5173         } else {
5174 
5175            pci50 >>= 24;
5176            pciA0 >>= 24;
5177 
5178            index = (pci50 >> 1) & 0x07;
5179 
5180            if(pci50 & 0x01)    index += 6;
5181            if(!(pciA0 & 0x01)) index += 24;
5182 
5183            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5184 
5185         }
5186 
5187         data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5188         if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5189 
5190      }
5191 
5192      data += data2;                                             /* CRT1 Request Period */
5193 
5194      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5195      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5196 
5197      if(!SiS_Pr->UseCustomMode) {
5198 
5199         CRT2ModeNo = ModeNo;
5200         SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5201 
5202         refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5203 
5204         /* Get VCLK  */
5205         index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5206         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5207 
5208         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5209            if(SiS_Pr->SiS_UseROM) {
5210               if(ROMAddr[0x220] & 0x01) {
5211                  VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5212               }
5213            }
5214         }
5215 
5216      } else {
5217 
5218         /* Get VCLK */
5219         CRT2ModeNo = 0xfe;
5220         VCLK = SiS_Pr->CSRClock;
5221 
5222      }
5223 
5224      /* Get colordepth */
5225      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5226      if(!colorth) colorth++;
5227 
5228      data = data * VCLK * colorth;
5229      temp = data % (MCLK << 4);
5230      data = data / (MCLK << 4);
5231      if(temp) data++;
5232 
5233      if(data < 6) data = 6;
5234      else if(data > 0x14) data = 0x14;
5235 
5236      if(SiS_Pr->ChipType == SIS_300) {
5237         temp = 0x16;
5238         if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5239            temp = 0x13;
5240      } else {
5241         temp = 0x16;
5242         if(( (SiS_Pr->ChipType == SIS_630) ||
5243              (SiS_Pr->ChipType == SIS_730) )  &&
5244            (SiS_Pr->ChipRevision >= 0x30))
5245            temp = 0x1b;
5246      }
5247      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5248 
5249      if((SiS_Pr->ChipType == SIS_630) &&
5250         (SiS_Pr->ChipRevision >= 0x30)) {
5251         if(data > 0x13) data = 0x13;
5252      }
5253      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5254 
5255   } else {  /* If mode <= 0x13, we just restore everything */
5256 
5257      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5258      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5259 
5260   }
5261 }
5262 #endif
5263 
5264 /* Set CRT2 FIFO on 315/330 series */
5265 #ifdef SIS315H
5266 static void
5267 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5268 {
5269   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5270   if( (SiS_Pr->ChipType == SIS_760)      &&
5271       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5272       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5273       (SiS_Pr->SiS_VGAHDE >= 1280)        &&
5274       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5275      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5276      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5277      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5278      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5279      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5280      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5281   } else {
5282      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5283   }
5284 
5285 }
5286 #endif
5287 
5288 static unsigned short
5289 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5290 {
5291   unsigned int tempax,tempbx;
5292 
5293   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5294   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5295   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5296   return (unsigned short)tempax;
5297 }
5298 
5299 /* Set Part 1 / SiS bridge slave mode */
5300 static void
5301 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5302                   unsigned short RefreshRateTableIndex)
5303 {
5304   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5305   static const unsigned short CRTranslation[] = {
5306        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5307           0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5308        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5309           0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5310        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5311           0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5312   };
5313 
5314   if(ModeNo <= 0x13) {
5315      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5316   } else if(SiS_Pr->UseCustomMode) {
5317      modeflag = SiS_Pr->CModeFlag;
5318      xres = SiS_Pr->CHDisplay;
5319   } else {
5320      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5321      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5322   }
5323 
5324   /* The following is only done if bridge is in slave mode: */
5325 
5326   if(SiS_Pr->ChipType >= SIS_315H) {
5327      if(xres >= 1600) {  /* BIOS: == 1600 */
5328         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5329      }
5330   }
5331 
5332   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5333 
5334   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5335   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5336 
5337   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5338   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5339      SiS_Pr->CHBlankStart += 16;
5340   }
5341 
5342   SiS_Pr->CHBlankEnd = 32;
5343   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5344      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5345   }
5346 
5347   temp = SiS_Pr->SiS_VGAHT - 96;
5348   if(!(modeflag & HalfDCLK)) temp -= 32;
5349   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5350      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5351      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5352      temp -= 3;
5353      temp <<= 3;
5354   } else {
5355      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5356   }
5357   SiS_Pr->CHSyncStart = temp;
5358 
5359   SiS_Pr->CHSyncEnd = 0xffe8;   /* results in 0x2000 in registers */
5360 
5361   SiS_Pr->CVTotal = 2049;       /* Max VT, 0x0801, results in 0x7ff in registers */
5362 
5363   VGAVDE = SiS_Pr->SiS_VGAVDE;
5364   if     (VGAVDE ==  357) VGAVDE =  350;
5365   else if(VGAVDE ==  360) VGAVDE =  350;
5366   else if(VGAVDE ==  375) VGAVDE =  350;
5367   else if(VGAVDE ==  405) VGAVDE =  400;
5368   else if(VGAVDE ==  420) VGAVDE =  400;
5369   else if(VGAVDE ==  525) VGAVDE =  480;
5370   else if(VGAVDE == 1056) VGAVDE = 1024;
5371   SiS_Pr->CVDisplay = VGAVDE;
5372 
5373   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5374 
5375   SiS_Pr->CVBlankEnd = 1;
5376   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5377 
5378   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5379   SiS_Pr->CVSyncStart = VGAVDE + temp;
5380 
5381   temp >>= 3;
5382   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5383 
5384   SiS_CalcCRRegisters(SiS_Pr, 0);
5385   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5386 
5387   for(i = 0; i <= 7; i++) {
5388      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5389   }
5390   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5391      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5392   }
5393   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5394      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5395   }
5396   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5397      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5398   }
5399 
5400   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5401   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5402 
5403   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5404   if(modeflag & DoubleScanMode) temp |= 0x80;
5405   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5406 
5407   temp = 0;
5408   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5409   if(modeflag & HalfDCLK) temp |= 0x08;
5410   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5411 
5412   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                  /* CR14: (text mode: underline location) */
5413   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                  /* CR17: n/a */
5414 
5415   temp = 0;
5416   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5417      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5418   }
5419   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* SR0E, dither[7] */
5420 
5421   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5422   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);                  /* ? */
5423 
5424 #ifdef SIS_XORG_XF86
5425 #ifdef TWDEBUG
5426    xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
5427         SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5428         SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5429         SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5430 
5431    xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5432         SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5433         SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5434         SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5435         SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5436    xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5437         SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5438         SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5439         SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5440         SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5441    xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5442 #endif
5443 #endif
5444 }
5445 
5446 /* Setup panel link
5447  * This is used for LVDS, LCDA and Chrontel TV output
5448  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5449  */
5450 static void
5451 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5452                 unsigned short RefreshRateTableIndex)
5453 {
5454   unsigned short modeflag, resinfo = 0;
5455   unsigned short push2, tempax, tempbx, tempcx, temp;
5456   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5457   bool islvds = false, issis  = false, chkdclkfirst = false;
5458 #ifdef SIS300
5459   unsigned short crt2crtc = 0;
5460 #endif
5461 #ifdef SIS315H
5462   unsigned short pushcx;
5463 #endif
5464 
5465   if(ModeNo <= 0x13) {
5466      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5467      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5468 #ifdef SIS300
5469      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5470 #endif
5471   } else if(SiS_Pr->UseCustomMode) {
5472      modeflag = SiS_Pr->CModeFlag;
5473   } else {
5474      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5475      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5476 #ifdef SIS300
5477      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5478 #endif
5479   }
5480 
5481   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5482   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5483      islvds = true;
5484   }
5485 
5486   /* is really sis if sis bridge, but not 301B-DH */
5487   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5488      issis = true;
5489   }
5490 
5491   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5492      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5493         chkdclkfirst = true;
5494      }
5495   }
5496 
5497 #ifdef SIS315H
5498   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5499      if(IS_SIS330) {
5500         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5501      } else if(IS_SIS740) {
5502         if(islvds) {
5503            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5504            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5505         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5506            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5507         }
5508      } else {
5509         if(islvds) {
5510            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5511            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5512         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5513            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5514            if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5515               if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5516                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5517                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5518               }
5519            }
5520         }
5521      }
5522   }
5523 #endif
5524 
5525   /* Horizontal */
5526 
5527   tempax = SiS_Pr->SiS_LCDHDES;
5528   if(islvds) {
5529      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5530         if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5531            if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5532               (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5533               tempax -= 8;
5534            }
5535         }
5536      }
5537   }
5538 
5539   temp = (tempax & 0x0007);
5540   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* BPLHDESKEW[2:0]   */
5541   temp = (tempax >> 3) & 0x00FF;
5542   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* BPLHDESKEW[10:3]  */
5543 
5544   tempbx = SiS_Pr->SiS_HDE;
5545   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5546      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5547         tempbx = SiS_Pr->PanelXRes;
5548      }
5549      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5550         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5551         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5552         tempbx >>= 1;
5553      }
5554   }
5555 
5556   tempax += tempbx;
5557   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5558 
5559   temp = tempax;
5560   if(temp & 0x07) temp += 8;
5561   temp >>= 3;
5562   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                  /* BPLHDEE  */
5563 
5564   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5565 
5566   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5567      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5568         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5569      }
5570   }
5571 
5572   tempcx += tempax;
5573   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5574 
5575   temp = (tempcx >> 3) & 0x00FF;
5576   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5577      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5578         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5579            switch(ModeNo) {
5580            case 0x04:
5581            case 0x05:
5582            case 0x0d: temp = 0x56; break;
5583            case 0x10: temp = 0x60; break;
5584            case 0x13: temp = 0x5f; break;
5585            case 0x40:
5586            case 0x41:
5587            case 0x4f:
5588            case 0x43:
5589            case 0x44:
5590            case 0x62:
5591            case 0x56:
5592            case 0x53:
5593            case 0x5d:
5594            case 0x5e: temp = 0x54; break;
5595            }
5596         }
5597      }
5598   }
5599   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                  /* BPLHRS */
5600 
5601   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5602      temp += 2;
5603      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5604         temp += 8;
5605         if(SiS_Pr->PanelHRE != 999) {
5606            temp = tempcx + SiS_Pr->PanelHRE;
5607            if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5608            temp >>= 3;
5609         }
5610      }
5611   } else {
5612      temp += 10;
5613   }
5614 
5615   temp &= 0x1F;
5616   temp |= ((tempcx & 0x07) << 5);
5617   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                  /* BPLHRE */
5618 
5619   /* Vertical */
5620 
5621   tempax = SiS_Pr->SiS_VGAVDE;
5622   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5623      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5624         tempax = SiS_Pr->PanelYRes;
5625      }
5626   }
5627 
5628   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5629   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5630 
5631   push2 = tempbx;
5632 
5633   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5634   if(SiS_Pr->ChipType < SIS_315H) {
5635      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5636         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5637            tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5638         }
5639      }
5640   }
5641   if(islvds) tempcx >>= 1;
5642   else       tempcx >>= 2;
5643 
5644   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5645       (!(SiS_Pr->SiS_LCDInfo & LCDPass11))                  &&
5646       (SiS_Pr->PanelVRS != 999) ) {
5647      tempcx = SiS_Pr->PanelVRS;
5648      tempbx += tempcx;
5649      if(issis) tempbx++;
5650   } else {
5651      tempbx += tempcx;
5652      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5653      else if(issis)                   tempbx++;
5654   }
5655 
5656   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5657 
5658   temp = tempbx & 0x00FF;
5659   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5660      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5661         if(ModeNo == 0x10) temp = 0xa9;
5662      }
5663   }
5664   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                  /* BPLVRS */
5665 
5666   tempcx >>= 3;
5667   tempcx++;
5668 
5669   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5670      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5671         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5672      }
5673   }
5674 
5675   tempcx += tempbx;
5676   temp = tempcx & 0x000F;
5677   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);        /* BPLVRE  */
5678 
5679   temp = ((tempbx >> 8) & 0x07) << 3;
5680   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5681      if(SiS_Pr->SiS_HDE != 640) {
5682         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5683      }
5684   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5685   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5686   tempbx = 0x87;
5687   if((SiS_Pr->ChipType >= SIS_315H) ||
5688      (SiS_Pr->ChipRevision >= 0x30)) {
5689      tempbx = 0x07;
5690      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5691         if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5692      }
5693      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5694      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5695         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5696            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5697         } else {
5698            if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5699         }
5700      }
5701   }
5702   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5703 
5704   tempbx = push2;                                               /* BPLVDEE */
5705 
5706   tempcx = SiS_Pr->SiS_LCDVDES;                                 /* BPLVDES */
5707 
5708   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5709      switch(SiS_Pr->SiS_LCDResInfo) {
5710      case Panel_640x480:
5711         tempbx = SiS_Pr->SiS_VGAVDE - 1;
5712         tempcx = SiS_Pr->SiS_VGAVDE;
5713         break;
5714      case Panel_800x600:
5715         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5716            if(resinfo == SIS_RI_800x600) tempcx++;
5717         }
5718         break;
5719      case Panel_1024x600:
5720         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5721            if(resinfo == SIS_RI_1024x600) tempcx++;
5722            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5723               if(resinfo == SIS_RI_800x600) tempcx++;
5724            }
5725         }
5726         break;
5727      case Panel_1024x768:
5728         if(SiS_Pr->ChipType < SIS_315H) {
5729            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5730               if(resinfo == SIS_RI_1024x768) tempcx++;
5731            }
5732         }
5733         break;
5734      }
5735   }
5736 
5737   temp = ((tempbx >> 8) & 0x07) << 3;
5738   temp |= ((tempcx >> 8) & 0x07);
5739   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5740   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5741   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5742 
5743   /* Vertical scaling */
5744 
5745   if(SiS_Pr->ChipType < SIS_315H) {
5746 
5747 #ifdef SIS300      /* 300 series */
5748      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5749      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5750      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5751      if(temp) tempeax++;
5752 
5753      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5754 
5755      temp = (unsigned short)(tempeax & 0x00FF);
5756      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);       /* BPLVCFACT */
5757      tempvcfact = temp;
5758 #endif /* SIS300 */
5759 
5760   } else {
5761 
5762 #ifdef SIS315H  /* 315 series */
5763      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5764      tempebx = SiS_Pr->SiS_VDE;
5765      temp = (tempeax % tempebx);
5766      tempeax = tempeax / tempebx;
5767      if(temp) tempeax++;
5768      tempvcfact = tempeax;
5769 
5770      temp = (unsigned short)(tempeax & 0x00FF);
5771      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5772      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5773      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5774      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5775      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5776      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5777 
5778      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5779         temp = (unsigned short)(tempeax & 0x00FF);
5780         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5781         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5782         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5783         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5784         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5785         temp = 0;
5786         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5787         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5788      }
5789 #endif
5790 
5791   }
5792 
5793   /* Horizontal scaling */
5794 
5795   tempeax = SiS_Pr->SiS_VGAHDE;         /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5796   if(chkdclkfirst) {
5797      if(modeflag & HalfDCLK) tempeax >>= 1;
5798   }
5799   tempebx = tempeax << 16;
5800   if(SiS_Pr->SiS_HDE == tempeax) {
5801      tempecx = 0xFFFF;
5802   } else {
5803      tempecx = tempebx / SiS_Pr->SiS_HDE;
5804      if(SiS_Pr->ChipType >= SIS_315H) {
5805         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5806      }
5807   }
5808 
5809   if(SiS_Pr->ChipType >= SIS_315H) {
5810      tempeax = (tempebx / tempecx) - 1;
5811   } else {
5812      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5813   }
5814   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5815   temp = (unsigned short)(tempecx & 0x00FF);
5816   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5817 
5818   if(SiS_Pr->ChipType >= SIS_315H) {
5819      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5820      tempbx = (unsigned short)(tempeax & 0xFFFF);
5821   } else {
5822      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5823      tempbx = tempvcfact & 0x3f;
5824      if(tempbx == 0) tempbx = 64;
5825      tempeax /= tempbx;
5826      tempbx = (unsigned short)(tempeax & 0xFFFF);
5827   }
5828   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5829   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5830      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5831      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
5832   }
5833 
5834   temp = ((tempbx >> 8) & 0x07) << 3;
5835   temp = temp | ((tempecx >> 8) & 0x07);
5836   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5837   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5838 
5839   tempecx >>= 16;                                               /* BPLHCFACT  */
5840   if(!chkdclkfirst) {
5841      if(modeflag & HalfDCLK) tempecx >>= 1;
5842   }
5843   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5844   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5845   temp = (unsigned short)(tempecx & 0x00FF);
5846   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5847 
5848 #ifdef SIS315H
5849   if(SiS_Pr->ChipType >= SIS_315H) {
5850      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5851         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5852            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5853         }
5854      } else {
5855         if(islvds) {
5856            if(SiS_Pr->ChipType == SIS_740) {
5857               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5858            } else {
5859               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5860            }
5861         }
5862      }
5863   }
5864 #endif
5865 
5866 #ifdef SIS300
5867   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5868      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5869      unsigned char *trumpdata;
5870      int   i, j = crt2crtc;
5871      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
5872      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5873      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5874 
5875      if(SiS_Pr->SiS_UseROM) {
5876         trumpdata = &ROMAddr[0x8001 + (j * 80)];
5877      } else {
5878         if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5879         trumpdata = &SiS300_TrumpionData[j][0];
5880      }
5881 
5882      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5883      for(i=0; i<5; i++) {
5884         SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5885      }
5886      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5887         if(ModeNo == 0x13) {
5888            for(i=0; i<4; i++) {
5889               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5890            }
5891         } else if(ModeNo == 0x10) {
5892            for(i=0; i<4; i++) {
5893               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5894               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5895            }
5896         }
5897      }
5898      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5899   }
5900 #endif
5901 
5902 #ifdef SIS315H
5903   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5904      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5905      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5906      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5907      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5908      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5909      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5910      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5911      tempax = SiS_Pr->SiS_HDE;                                  /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5912      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5913         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5914         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5915      tempax += 64;
5916      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5917      temp = (tempax >> 8) << 3;
5918      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5919      tempax += 32;                                              /* Blpe = lBlps+32 */
5920      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5921      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);               /* Bflml = 0 */
5922      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5923 
5924      tempax = SiS_Pr->SiS_VDE;
5925      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5926         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5927         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5928      tempax >>= 1;
5929      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5930      temp = (tempax >> 8) << 3;
5931      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5932 
5933      tempeax = SiS_Pr->SiS_HDE;
5934      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5935         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5936         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5937      tempeax <<= 2;                                             /* BDxFIFOSTOP = (HDE*4)/128 */
5938      temp = tempeax & 0x7f;
5939      tempeax >>= 7;
5940      if(temp) tempeax++;
5941      temp = tempeax & 0x3f;
5942      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5943      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);               /* BDxWadrst0 */
5944      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5945      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5946      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5947 
5948      tempax = SiS_Pr->SiS_HDE;
5949      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5950         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5951         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5952      tempax >>= 4;                                              /* BDxWadroff = HDE*4/8/8 */
5953      pushcx = tempax;
5954      temp = tempax & 0x00FF;
5955      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5956      temp = ((tempax & 0xFF00) >> 8) << 3;
5957      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5958 
5959      tempax = SiS_Pr->SiS_VDE;                                  /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5960      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5961         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5962         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5963      tempeax = tempax * pushcx;
5964      temp = tempeax & 0xFF;
5965      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5966      temp = (tempeax & 0xFF00) >> 8;
5967      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5968      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5969      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5970      temp = ((tempeax & 0x01000000) >> 24) << 7;
5971      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5972 
5973      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5974      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5975      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5976      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5977      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5978 
5979      if(SiS_Pr->SiS_IF_DEF_FSTN) {
5980         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5981         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5982         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5983         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5984         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5985         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5986         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5987         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5988         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5989         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5990         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5991         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5992         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5993         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5994         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5995         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5996         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5997         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5998         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5999         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6000      }
6001   }
6002 #endif  /* SIS315H */
6003 }
6004 
6005 /* Set Part 1 */
6006 static void
6007 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6008                 unsigned short RefreshRateTableIndex)
6009 {
6010 #if defined(SIS300) || defined(SIS315H)
6011   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6012 #endif
6013   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6014   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6015 #ifdef SIS315H
6016   unsigned short  tempbl=0;
6017 #endif
6018 
6019   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6020      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6021      return;
6022   }
6023 
6024   if(ModeNo <= 0x13) {
6025      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6026   } else if(SiS_Pr->UseCustomMode) {
6027      modeflag = SiS_Pr->CModeFlag;
6028   } else {
6029      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6030      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6031      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6032   }
6033 
6034   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6035 
6036   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6037          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6038          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6039 
6040      if(SiS_Pr->ChipType < SIS_315H ) {
6041 #ifdef SIS300
6042         SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6043 #endif
6044      } else {
6045 #ifdef SIS315H
6046         SiS_SetCRT2FIFO_310(SiS_Pr);
6047 #endif
6048      }
6049 
6050      /* 1. Horizontal setup */
6051 
6052      if(SiS_Pr->ChipType < SIS_315H ) {
6053 
6054 #ifdef SIS300   /* ------------- 300 series --------------*/
6055 
6056         temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
6057         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6058 
6059         temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6060         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6061 
6062         temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6063         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6064 
6065         pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6066         tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6067         tempbx = pushbx + tempcx;
6068         tempcx <<= 1;
6069         tempcx += tempbx;
6070 
6071         bridgeadd = 12;
6072 
6073 #endif /* SIS300 */
6074 
6075      } else {
6076 
6077 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
6078 
6079         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HT 0x08,0x09 */
6080         if(modeflag & HalfDCLK) {
6081            if(SiS_Pr->SiS_VBType & VB_SISVB) {
6082               tempcx >>= 1;
6083            } else {
6084               tempax = SiS_Pr->SiS_VGAHDE >> 1;
6085               tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6086               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6087                  tempcx = SiS_Pr->SiS_HT - tempax;
6088               }
6089            }
6090         }
6091         tempcx--;
6092         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6093         temp = (tempcx >> 4) & 0xF0;
6094         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6095 
6096         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HDEE 0x0A,0x0C */
6097         tempbx = SiS_Pr->SiS_VGAHDE;
6098         tempcx -= tempbx;
6099         tempcx >>= 2;
6100         if(modeflag & HalfDCLK) {
6101            tempbx >>= 1;
6102            tempcx >>= 1;
6103         }
6104         tempbx += 16;
6105 
6106         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6107 
6108         pushbx = tempbx;
6109         tempcx >>= 1;
6110         tempbx += tempcx;
6111         tempcx += tempbx;
6112 
6113         bridgeadd = 16;
6114 
6115         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6116            if(SiS_Pr->ChipType >= SIS_661) {
6117               if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6118                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6119                  if(resinfo == SIS_RI_1280x1024) {
6120                     tempcx = (tempcx & 0xff00) | 0x30;
6121                  } else if(resinfo == SIS_RI_1600x1200) {
6122                     tempcx = (tempcx & 0xff00) | 0xff;
6123                  }
6124               }
6125            }
6126         }
6127 
6128 #endif  /* SIS315H */
6129 
6130      }  /* 315/330 series */
6131 
6132      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6133 
6134         if(SiS_Pr->UseCustomMode) {
6135            tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6136            tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6137            tempax = SiS_Pr->SiS_VGAHT;
6138            if(modeflag & HalfDCLK) tempax >>= 1;
6139            tempax--;
6140            if(tempcx > tempax) tempcx = tempax;
6141         }
6142 
6143         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6144            unsigned char cr4, cr14, cr5, cr15;
6145            if(SiS_Pr->UseCustomMode) {
6146               cr4  = SiS_Pr->CCRT1CRTC[4];
6147               cr14 = SiS_Pr->CCRT1CRTC[14];
6148               cr5  = SiS_Pr->CCRT1CRTC[5];
6149               cr15 = SiS_Pr->CCRT1CRTC[15];
6150            } else {
6151               cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6152               cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6153               cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6154               cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6155            }
6156            tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                /* (VGAHRS-3)*8 */
6157            tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6158            tempcx &= 0x00FF;
6159            tempcx |= (tempbx & 0xFF00);
6160            tempbx += bridgeadd;
6161            tempcx += bridgeadd;
6162            tempax = SiS_Pr->SiS_VGAHT;
6163            if(modeflag & HalfDCLK) tempax >>= 1;
6164            tempax--;
6165            if(tempcx > tempax) tempcx = tempax;
6166         }
6167 
6168         if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6169            tempbx = 1040;
6170            tempcx = 1044;   /* HWCursor bug! */
6171         }
6172 
6173      }
6174 
6175      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);               /* CRT2 Horizontal Retrace Start */
6176 
6177      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6178 
6179      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6180      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                 /* Overflow */
6181 
6182      /* 2. Vertical setup */
6183 
6184      tempcx = SiS_Pr->SiS_VGAVT - 1;
6185      temp = tempcx & 0x00FF;
6186 
6187      if(SiS_Pr->ChipType < SIS_661) {
6188         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6189            if(SiS_Pr->ChipType < SIS_315H) {
6190               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6191                  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6192                     temp--;
6193                  }
6194               }
6195            } else {
6196               temp--;
6197            }
6198         } else if(SiS_Pr->ChipType >= SIS_315H) {
6199            temp--;
6200         }
6201      }
6202      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6203 
6204      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6205      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6206 
6207      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6208      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6209 
6210      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6211         tempbx++;
6212         tempax = tempbx;
6213         tempcx++;
6214         tempcx -= tempax;
6215         tempcx >>= 2;
6216         tempbx += tempcx;
6217         if(tempcx < 4) tempcx = 4;
6218         tempcx >>= 2;
6219         tempcx += tempbx;
6220         tempcx++;
6221      } else {
6222         tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6223         tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6224      }
6225 
6226      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6227         if(SiS_Pr->UseCustomMode) {
6228            tempbx = SiS_Pr->CVSyncStart;
6229            tempcx = SiS_Pr->CVSyncEnd;
6230         }
6231         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6232            unsigned char cr8, cr7, cr13;
6233            if(SiS_Pr->UseCustomMode) {
6234               cr8    = SiS_Pr->CCRT1CRTC[8];
6235               cr7    = SiS_Pr->CCRT1CRTC[7];
6236               cr13   = SiS_Pr->CCRT1CRTC[13];
6237               tempcx = SiS_Pr->CCRT1CRTC[9];
6238            } else {
6239               cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6240               cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6241               cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6242               tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6243            }
6244            tempbx = cr8;
6245            if(cr7  & 0x04) tempbx |= 0x0100;
6246            if(cr7  & 0x80) tempbx |= 0x0200;
6247            if(cr13 & 0x08) tempbx |= 0x0400;
6248         }
6249      }
6250      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6251 
6252      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6253      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6254 
6255      /* 3. Panel delay compensation */
6256 
6257      if(SiS_Pr->ChipType < SIS_315H) {
6258 
6259 #ifdef SIS300  /* ---------- 300 series -------------- */
6260 
6261         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6262            temp = 0x20;
6263            if(SiS_Pr->ChipType == SIS_300) {
6264               temp = 0x10;
6265               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6266               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6267            }
6268            if(SiS_Pr->SiS_VBType & VB_SIS301) {
6269               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6270            }
6271            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6272            if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6273            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)             temp = 0x08;
6274            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6275               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
6276               else                                          temp = 0x20;
6277            }
6278            if(SiS_Pr->SiS_UseROM) {
6279               if(ROMAddr[0x220] & 0x80) {
6280                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6281                     temp = ROMAddr[0x221];
6282                  else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6283                     temp = ROMAddr[0x222];
6284                  else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6285                     temp = ROMAddr[0x223];
6286                  else
6287                     temp = ROMAddr[0x224];
6288               }
6289            }
6290            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6291               if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6292            }
6293 
6294         } else {
6295            temp = 0x20;
6296            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6297               if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6298            }
6299            if(SiS_Pr->SiS_UseROM) {
6300               if(ROMAddr[0x220] & 0x80) {
6301                  temp = ROMAddr[0x220];
6302               }
6303            }
6304            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6305               if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6306            }
6307         }
6308 
6309         temp &= 0x3c;
6310 
6311         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6312 
6313 #endif  /* SIS300 */
6314 
6315      } else {
6316 
6317 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
6318 
6319         if(SiS_Pr->ChipType < SIS_661) {
6320 
6321            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6322 
6323               if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6324               else                            temp = 0x00;
6325 
6326               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6327               tempbl = 0xF0;
6328               if(SiS_Pr->ChipType == SIS_650) {
6329                  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6330                     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6331                  }
6332               }
6333 
6334               if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6335                  temp = 0x08;
6336                  tempbl = 0;
6337                  if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6338                     if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6339                  }
6340               }
6341 
6342               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);      /* Panel Link Delay Compensation */
6343            }
6344 
6345         } /* < 661 */
6346 
6347         tempax = 0;
6348         if(modeflag & DoubleScanMode) tempax |= 0x80;
6349         if(modeflag & HalfDCLK)       tempax |= 0x40;
6350         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6351 
6352 #endif  /* SIS315H */
6353 
6354      }
6355 
6356   }  /* Slavemode */
6357 
6358   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6359      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6360         /* For 301BDH with LCD, we set up the Panel Link */
6361         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6362      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6363         SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6364      }
6365   } else {
6366      if(SiS_Pr->ChipType < SIS_315H) {
6367         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6368      } else {
6369         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6370            if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6371               SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6372            }
6373         } else {
6374            SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6375         }
6376      }
6377   }
6378 }
6379 
6380 /*********************************************/
6381 /*         SET PART 2 REGISTER GROUP         */
6382 /*********************************************/
6383 
6384 #ifdef SIS315H
6385 static unsigned char *
6386 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6387 {
6388    const unsigned char *tableptr = NULL;
6389    unsigned short      a, b, p = 0;
6390 
6391    a = SiS_Pr->SiS_VGAHDE;
6392    b = SiS_Pr->SiS_HDE;
6393    if(tabletype) {
6394       a = SiS_Pr->SiS_VGAVDE;
6395       b = SiS_Pr->SiS_VDE;
6396    }
6397 
6398    if(a < b) {
6399       tableptr = SiS_Part2CLVX_1;
6400    } else if(a == b) {
6401       tableptr = SiS_Part2CLVX_2;
6402    } else {
6403       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6404          tableptr = SiS_Part2CLVX_4;
6405       } else {
6406          tableptr = SiS_Part2CLVX_3;
6407       }
6408       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6409          if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)        tableptr = SiS_Part2CLVX_3;
6410          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   tableptr = SiS_Part2CLVX_3;
6411          else                                           tableptr = SiS_Part2CLVX_5;
6412       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6413          tableptr = SiS_Part2CLVX_6;
6414       }
6415       do {
6416          if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6417          p += 0x42;
6418       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6419       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6420    }
6421    p += 2;
6422    return ((unsigned char *)&tableptr[p]);
6423 }
6424 
6425 static void
6426 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6427                     unsigned short RefreshRateTableIndex)
6428 {
6429    unsigned char *tableptr;
6430    unsigned char temp;
6431    int i, j;
6432 
6433    if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6434 
6435    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6436    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6437       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6438    }
6439    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6440       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6441       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6442          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6443       }
6444    }
6445    temp = 0x10;
6446    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6447    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6448 }
6449 
6450 static bool
6451 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6452                     unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6453                     unsigned short *ResIndex)
6454 {
6455 
6456   if(SiS_Pr->ChipType < SIS_315H) return false;
6457 
6458   if(ModeNo <= 0x13)
6459      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6460   else
6461      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6462 
6463   (*ResIndex) &= 0x3f;
6464   (*CRT2Index) = 0;
6465 
6466   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6467      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6468         (*CRT2Index) = 200;
6469      }
6470   }
6471 
6472   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6473      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6474         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6475      }
6476   }
6477   return (((*CRT2Index) != 0));
6478 }
6479 #endif
6480 
6481 #ifdef SIS300
6482 static void
6483 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6484 {
6485    unsigned short tempcx;
6486    static const unsigned char atable[] = {
6487        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6488        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6489    };
6490 
6491    if(!SiS_Pr->UseCustomMode) {
6492       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6493               (SiS_Pr->ChipType == SIS_730) ) &&
6494             (SiS_Pr->ChipRevision > 2) )  &&
6495           (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6496           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6497           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6498          if(ModeNo == 0x13) {
6499             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6500             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6501             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6502          } else if((crt2crtc & 0x3F) == 4) {
6503             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6504             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6505             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6506             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6507             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6508          }
6509       }
6510 
6511       if(SiS_Pr->ChipType < SIS_315H) {
6512          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6513             crt2crtc &= 0x1f;
6514             tempcx = 0;
6515             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6516                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6517                   tempcx += 7;
6518                }
6519             }
6520             tempcx += crt2crtc;
6521             if(crt2crtc >= 4) {
6522                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6523             }
6524 
6525             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6526                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6527                   if(crt2crtc == 4) {
6528                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6529                   }
6530                }
6531             }
6532             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6533             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6534          }
6535       }
6536    }
6537 }
6538 
6539 /* For ECS A907. Highly preliminary. */
6540 static void
6541 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6542                     unsigned short ModeNo)
6543 {
6544   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6545   unsigned short crt2crtc, resindex;
6546   int i, j;
6547 
6548   if(SiS_Pr->ChipType != SIS_300) return;
6549   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6550   if(SiS_Pr->UseCustomMode) return;
6551 
6552   if(ModeNo <= 0x13) {
6553      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6554   } else {
6555      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6556   }
6557 
6558   resindex = crt2crtc & 0x3F;
6559   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6560   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6561 
6562   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6563   if(ModeNo > 0x13) {
6564      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6565      resindex = 4;
6566   }
6567 
6568   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6569   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6570   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6571      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6572   }
6573   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6574      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6575   }
6576   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6577      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6578   }
6579   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6580   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6581 }
6582 #endif
6583 
6584 static void
6585 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6586 {
6587   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6588   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6589   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6590 
6591   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6592      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6593         const unsigned char specialtv[] = {
6594                 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6595                 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6596                 0x58,0xe4,0x73,0xda,0x13
6597         };
6598         int i, j;
6599         for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6600            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6601         }
6602         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6603         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6604            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6605               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6606               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6607            } else {
6608               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6609               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6610            }
6611         }
6612      }
6613   } else {
6614      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6615         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6616         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6617         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6618      } else {
6619         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6620         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6621      }
6622   }
6623 }
6624 
6625 static void
6626 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6627 {
6628   unsigned short temp;
6629 
6630   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6631      if(SiS_Pr->SiS_VGAVDE == 525) {
6632         temp = 0xc3;
6633         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6634            temp++;
6635            if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6636         }
6637         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6638         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6639      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6640         temp = 0x4d;
6641         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6642            temp++;
6643            if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6644         }
6645         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6646      }
6647   }
6648 
6649   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6650      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6651         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6652            SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6653            /* Not always for LV, see SetGrp2 */
6654         }
6655         temp = 1;
6656         if(ModeNo <= 0x13) temp = 3;
6657         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6658      }
6659 #if 0
6660      /* 651+301C, for 1280x768 - do I really need that? */
6661      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6662         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6663            if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6664               ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6665               SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6666               SiS_SetReg(SiS_Part2Port,0x02,0x13);
6667               SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6668               SiS_SetReg(SiS_Part2Port,0x05,0x08);
6669               SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6670               SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6671               SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6672               SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6673               SiS_SetReg(SiS_Part2Port,0x20,0x00);
6674               SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6675               SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6676               SiS_SetReg(SiS_Part2Port,0x25,0x04);
6677            }
6678         }
6679      }
6680 #endif
6681   }
6682 }
6683 
6684 static void
6685 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6686                 unsigned short RefreshRateTableIndex)
6687 {
6688   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6689   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6690   unsigned int   longtemp, PhaseIndex;
6691   bool           newtvphase;
6692   const unsigned char *TimingPoint;
6693 #ifdef SIS315H
6694   unsigned short resindex, CRT2Index;
6695   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6696 
6697   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6698 #endif
6699 
6700   if(ModeNo <= 0x13) {
6701      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6702      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6703   } else if(SiS_Pr->UseCustomMode) {
6704      modeflag = SiS_Pr->CModeFlag;
6705      crt2crtc = 0;
6706   } else {
6707      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6708      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6709   }
6710 
6711   temp = 0;
6712   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6713   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6714   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6715   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6716 
6717   if(!(SiS_Pr->SiS_TVMode & TVSetPAL))        temp |= 0x10;
6718 
6719   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6720 
6721   PhaseIndex  = 0x01; /* SiS_PALPhase */
6722   TimingPoint = SiS_Pr->SiS_PALTiming;
6723 
6724   newtvphase = false;
6725   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6726       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6727         (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6728      newtvphase = true;
6729   }
6730 
6731   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6732 
6733      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6734      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6735         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6736         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6737            TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6738         }
6739      }
6740 
6741   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6742 
6743      i = 0;
6744      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6745      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6746 
6747      TimingPoint = &SiS_YPbPrTable[i][0];
6748 
6749      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6750 
6751   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6752 
6753      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6754 
6755   } else {
6756 
6757      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6758      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;     /* SiS_PALPhase : SiS_NTSCPhase */
6759      if(newtvphase) PhaseIndex += 8;                                    /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6760 
6761   }
6762 
6763   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6764      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;       /* SiS_PALMPhase : SiS_PALNPhase */
6765      if(newtvphase) PhaseIndex += 8;                                    /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6766   }
6767 
6768   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6769      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6770         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6771      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6772         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6773      } else {
6774         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6775      }
6776   }
6777 
6778   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6779      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6780   }
6781 
6782   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6783      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6784   }
6785   for(i = 0x39; i <= 0x45; i++, j++) {
6786      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6787   }
6788 
6789   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6790      if(SiS_Pr->SiS_ModeType != ModeText) {
6791         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6792      }
6793   }
6794 
6795   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6796 
6797   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6798   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6799   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6800   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6801 
6802   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)    tempax = 950;
6803   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
6804   else if(SiS_Pr->SiS_TVMode & TVSetPAL)        tempax = 520;
6805   else                                          tempax = 440; /* NTSC, YPbPr 525 */
6806 
6807   if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6808       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6809         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6810 
6811      tempax -= SiS_Pr->SiS_VDE;
6812      tempax >>= 1;
6813      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6814         tempax >>= 1;
6815      }
6816      tempax &= 0x00ff;
6817 
6818      temp = tempax + (unsigned short)TimingPoint[0];
6819      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6820 
6821      temp = tempax + (unsigned short)TimingPoint[1];
6822      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6823 
6824      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6825         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6826            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6827            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6828         } else {
6829            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6830            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6831         }
6832      }
6833 
6834   }
6835 
6836   tempcx = SiS_Pr->SiS_HT;
6837   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6838   tempcx--;
6839   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6840   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6841   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6842 
6843   tempcx = SiS_Pr->SiS_HT >> 1;
6844   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6845   tempcx += 7;
6846   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6847   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6848 
6849   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6850   tempbx += tempcx;
6851   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6852   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6853 
6854   tempbx += 8;
6855   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6856      tempbx -= 4;
6857      tempcx = tempbx;
6858   }
6859   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6860 
6861   j += 2;
6862   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6863   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6864   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6865 
6866   tempcx += 8;
6867   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6868   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6869 
6870   tempcx = SiS_Pr->SiS_HT >> 1;
6871   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6872   j += 2;
6873   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6874   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6875 
6876   tempcx -= 11;
6877   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6878      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6879   }
6880   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6881 
6882   tempbx = SiS_Pr->SiS_VDE;
6883   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6884      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6885      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6886      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6887   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6888              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6889      tempbx >>= 1;
6890      if(SiS_Pr->ChipType >= SIS_315H) {
6891         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6892            if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6893         } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6894            if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6895               if(crt2crtc == 4) tempbx++;
6896            }
6897         }
6898      }
6899      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6900         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6901            if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6902         }
6903         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6904            if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6905         }
6906      }
6907   }
6908   tempbx -= 2;
6909   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6910 
6911   temp = (tempcx >> 8) & 0x0F;
6912   temp |= ((tempbx >> 2) & 0xC0);
6913   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6914      temp |= 0x10;
6915      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6916   }
6917   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6918 
6919   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6920      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6921   }
6922 
6923   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6924      tempbx = SiS_Pr->SiS_VDE;
6925      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6926          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6927         tempbx >>= 1;
6928      }
6929      tempbx -= 3;
6930      temp = ((tempbx >> 3) & 0x60) | 0x18;
6931      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6932      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6933 
6934      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6935         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6936      }
6937   }
6938 
6939   tempbx = 0;
6940   if(!(modeflag & HalfDCLK)) {
6941      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6942         tempax = 0;
6943         tempbx |= 0x20;
6944      }
6945   }
6946 
6947   tempch = tempcl = 0x01;
6948   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6949      if(SiS_Pr->SiS_VGAHDE >= 960) {
6950         if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6951            tempcl = 0x20;
6952            if(SiS_Pr->SiS_VGAHDE >= 1280) {
6953               tempch = 20;
6954               tempbx &= ~0x20;
6955            } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6956               tempch = 25;
6957            } else {
6958               tempch = 25; /* OK */
6959            }
6960         }
6961      }
6962   }
6963 
6964   if(!(tempbx & 0x20)) {
6965      if(modeflag & HalfDCLK) tempcl <<= 1;
6966      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6967      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6968      tempax = longtemp / SiS_Pr->SiS_HDE;
6969      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6970      tempbx |= ((tempax >> 8) & 0x1F);
6971      tempcx = tempax >> 13;
6972   }
6973 
6974   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6975   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6976 
6977   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6978 
6979      tempcx &= 0x07;
6980      if(tempbx & 0x20) tempcx = 0;
6981      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6982 
6983      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6984         tempbx = 0x0382;
6985         tempcx = 0x007e;
6986      } else {
6987         tempbx = 0x0369;
6988         tempcx = 0x0061;
6989      }
6990      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6991      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6992      temp = (tempcx & 0x0300) >> 6;
6993      temp |= ((tempbx >> 8) & 0x03);
6994      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6995         temp |= 0x10;
6996         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
6997         else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6998      }
6999      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7000 
7001      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7002      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7003 
7004      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7005 
7006      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7007         temp = 0;
7008         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7009         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7010      }
7011 
7012   }
7013 
7014   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7015      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7016         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7017         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7018      }
7019      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7020   }
7021 
7022   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7023      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7024         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7025      }
7026   }
7027 
7028   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7029 
7030   /* From here: Part2 LCD setup */
7031 
7032   tempbx = SiS_Pr->SiS_HDE;
7033   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7034   tempbx--;                                     /* RHACTE = HDE - 1 */
7035   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7036   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7037 
7038   temp = 0x01;
7039   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7040      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7041         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7042            temp = 0x02;
7043            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7044               temp = 0x01;
7045            }
7046         }
7047      }
7048   }
7049   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7050 
7051   tempbx = SiS_Pr->SiS_VDE - 1;
7052   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7053   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7054 
7055   tempcx = SiS_Pr->SiS_VT - 1;
7056   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7057   temp = (tempcx >> 3) & 0xE0;
7058   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7059      /* Enable dithering; only do this for 32bpp mode */
7060      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7061         temp |= 0x10;
7062      }
7063   }
7064   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7065 
7066   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7067   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7068 
7069   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7070   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7071 
7072 #ifdef SIS315H
7073   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7074                                                 &CRT2Index, &resindex)) {
7075       switch(CRT2Index) {
7076         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7077         default:
7078         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7079       }
7080 
7081       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7082       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7083       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7084         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7085       }
7086       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7087         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7088       }
7089       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7090         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7091       }
7092       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7093       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7094 
7095       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7096 
7097   } else {
7098 #endif
7099 
7100     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7101     /*             Clevo dual-link 1024x768 */
7102     /*             Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7103     /*             Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7104 
7105     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7106        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7107           tempbx = SiS_Pr->SiS_VDE - 1;
7108           tempcx = SiS_Pr->SiS_VT - 1;
7109        } else {
7110           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7111           tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7112        }
7113     } else {
7114        tempbx = SiS_Pr->PanelYRes;
7115        tempcx = SiS_Pr->SiS_VT;
7116        tempax = 1;
7117        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7118           tempax = SiS_Pr->PanelYRes;
7119           /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7120           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7121              tempax = tempcx = 0;
7122           } else {
7123              tempax -= SiS_Pr->SiS_VDE;
7124           }
7125           tempax >>= 1;
7126        }
7127        tempcx -= tempax; /* lcdvdes */
7128        tempbx -= tempax; /* lcdvdee */
7129     }
7130 
7131     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7132 
7133 #ifdef SIS_XORG_XF86
7134 #ifdef TWDEBUG
7135     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7136 #endif
7137 #endif
7138 
7139     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);      /* lcdvdes  */
7140     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);      /* lcdvdee  */
7141 
7142     temp = (tempbx >> 5) & 0x38;
7143     temp |= ((tempcx >> 8) & 0x07);
7144     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7145 
7146     tempax = SiS_Pr->SiS_VDE;
7147     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7148        tempax = SiS_Pr->PanelYRes;
7149     }
7150     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7151     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7152        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7153           tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7154        }
7155     }
7156 
7157     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7158     if(SiS_Pr->SiS_LCDInfo &am