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