ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / video / sis / init301.c
1 /* $XFree86$ */
2 /*
3  * Mode initializing code (CRT2 section)
4  * for SiS 300/305/540/630/730 and
5  *     SiS 315/550/650/M650/651/661FX/M661xX/740/741/M741/330/660/M660/760/M760
6  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
7  *
8  * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
9  *
10  * If distributed as part of the Linux kernel, the following license terms
11  * apply:
12  *
13  * * This program is free software; you can redistribute it and/or modify
14  * * it under the terms of the GNU General Public License as published by
15  * * the Free Software Foundation; either version 2 of the named License,
16  * * or any later version.
17  * *
18  * * This program is distributed in the hope that it will be useful,
19  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * * GNU General Public License for more details.
22  * *
23  * * You should have received a copy of the GNU General Public License
24  * * along with this program; if not, write to the Free Software
25  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
26  *
27  * Otherwise, the following license terms apply:
28  *
29  * * Redistribution and use in source and binary forms, with or without
30  * * modification, are permitted provided that the following conditions
31  * * are met:
32  * * 1) Redistributions of source code must retain the above copyright
33  * *    notice, this list of conditions and the following disclaimer.
34  * * 2) Redistributions in binary form must reproduce the above copyright
35  * *    notice, this list of conditions and the following disclaimer in the
36  * *    documentation and/or other materials provided with the distribution.
37  * * 3) All advertising materials mentioning features or use of this software
38  * *    must display the following acknowledgement: "This product includes
39  * *    software developed by Thomas Winischhofer, Vienna, Austria."
40  * * 4) The name of the author may not be used to endorse or promote products
41  * *    derived from this software without specific prior written permission.
42  * *
43  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
44  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
47  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
52  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  * Author:      Thomas Winischhofer <thomas@winischhofer.net>
55  *
56  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
57  * Used by permission.
58  *
59  * TW says: This code looks awful, I know. But please don't do anything about
60  * this otherwise debugging will be hell.
61  * The code is extremely fragile as regards the different chipsets, different
62  * video bridges and combinations thereof. If anything is changed, extreme
63  * care has to be taken that that change doesn't break it for other chipsets,
64  * bridges or combinations thereof.
65  * All comments in this file are by me, regardless if marked TW or not.
66  *
67  */
68
69 #if 1
70 #define SET_EMI         /* 302LV/ELV: Set EMI values */
71 #endif
72
73 #define COMPAL_HACK     /* Needed for Compal 1400x1050 (EMI) */
74 #define COMPAQ_HACK     /* Needed for Inventec/Compaq 1280x1024 (EMI) */
75 #define ASUS_HACK       /* Needed for Asus A2H 1024x768 (EMI) */
76
77 #include "init301.h"
78
79 #if 0
80 #define TWNEWPANEL
81 #endif
82
83 #ifdef SIS300
84 #include "oem300.h"
85 #endif
86
87 #ifdef SIS315H
88 #include "oem310.h"
89 #endif
90
91 #define SiS_I2CDELAY      1000
92 #define SiS_I2CDELAYSHORT  150
93
94 /*********************************************/
95 /*         HELPER: Lock/Unlock CRT2          */
96 /*********************************************/
97
98 void
99 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
100 {
101   if(HwInfo->jChipType >= SIS_315H)
102      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
103   else
104      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
105 }
106
107 void
108 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
109 {
110   if(HwInfo->jChipType >= SIS_315H)
111      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
112   else
113      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
114 }
115
116 /*********************************************/
117 /*            HELPER: Enable CRT2            */
118 /*********************************************/
119
120 void
121 SiS_EnableCRT2(SiS_Private *SiS_Pr)
122 {
123   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
124 }
125
126 /*********************************************/
127 /*            HELPER: Write SR11             */
128 /*********************************************/
129
130 static void
131 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
132 {
133    if(HwInfo->jChipType >= SIS_661) DataAND &= 0x0f;
134    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
135 }
136
137 /*********************************************/
138 /*    HELPER: Get Pointer to LCD structure   */
139 /*********************************************/
140
141 /* For 661 series only */
142 #ifdef SIS315H
143 #if 0   /* Need to wait until hardware using this really exists */
144 static UCHAR *
145 GetLCDPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int tabletype,
146              USHORT ModeNo, USHORT ModeIdIndex, USHORT RRTI)
147 {
148   UCHAR *ROMAddr =  HwInfo->pjVirtualRomBase;
149   UCHAR *tableptr = NULL;
150   UCHAR tablelengths[] = { 8, 7, 6, 6, 8, 6, 0, 0, 0 };
151   USHORT modeflag, CRT2Index, tablelength, lcdid, myid, tableptri;
152
153   if(ModeNo <= 0x13) {
154      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
155      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
156   } else {
157      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
158      CRT2Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT2CRTC;
159      /* This is total bullshit: */
160      if(SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO == SIS_RI_720x576) CRT2Index = 10;
161   }
162
163   if(tabletype <= 1) {
164 #if 0   /* Not yet implemented */
165      if(ModeNo <= 0x13) {
166         CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex]. + 5;
167      } else {
168         CRT2Index = SiS_Pr->SiS_RefIndex[RRTI]. + 5;
169      }
170      if(tabletype & 1) CRT2Index >>= 4;
171 #endif
172   }
173
174   CRT2Index &= 0x0f;
175
176   tablelength = tablelengths[tabletype];
177   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
178      if((tabletype == 5) || (tabletype == 7)) tablelength = 8;
179      if((tabletype == 3) || (tabletype == 8)) tablelength = 8;
180   }
181
182   if(!tablelength) return NULL;
183
184   tableptri = ROMAddr[0x222] | (ROMAddr[0x223] << 8);
185   tableptri += (tabletype << 1);
186   if(!tableptri) return NULL;
187   tableptr = &ROMAddr[tableptri];
188
189   do {
190      lcdid = tableptr[0];
191      if(lcdid == 0xff) break;
192      myid = SiS_Pr->SiS_LCDResInfo;
193      if((lcdid & 0x80) && (lcdid != 0x80)) {
194         lcdid &= 0x7f;
195         myid = SiS_Pr->SiS_LCDTypeInfo;
196      }
197      if(SiS_Pr->SiS_LCDInfo & LCDPass11) myid &= ~0x1f;
198
199      if(myid == lcdid) {
200         lcdid = tableptr[1] | (tableptr[2] << 8);
201         myid = SiS_Pr->SiS_LCDInfo661;
202         if(modeflag & HalfDCLK) myid |= 0x200;
203         if(ModeNo <= 0x13)      myid |= 0x400;
204         lcdid &= myid;
205         myid = tableptr[3] | (tableptr[4] << 8);
206         if(lcdid == myid) break;
207      }
208      tableptr += 7;
209   } while (1);
210
211   if(lcdid == myid) {
212      lcdid = tableptr[5] | (tableptr[6] << 8);
213      lcdid += (tablelength * CRT2Index);
214      return((UCHAR *)&ROMAddr[lcdid]);
215   }
216
217   return NULL;
218 }
219 #endif
220
221 static UCHAR *
222 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
223 {
224    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
225    USHORT lcdres = SiS_Pr->SiS_LCDResInfo;
226    USHORT lcdtype = SiS_Pr->SiS_LCDTypeInfo;
227    USHORT romindex=0;
228    UCHAR  *myptr = NULL;
229    UCHAR  lcdid;
230
231    if((ROMAddr) && SiS_Pr->SiS_UseROM) {
232       romindex = ROMAddr[0x256] | (ROMAddr[0x257] << 8);
233    }
234    if(romindex) {
235       myptr = &ROMAddr[romindex];
236    } else {
237       myptr = (UCHAR *)SiS_LCDStruct661;
238    }
239
240    while(myptr[0] != 0xff) {
241       lcdid = myptr[0];
242       if((lcdid & 0x80) && (lcdid != 0x80)) {
243          lcdres = lcdtype;
244          lcdid &= 0x7f;
245       }
246       if(lcdid == lcdres) break;
247       myptr += 26;
248    }
249    if(myptr[0] == 0xff) return NULL;
250
251    return myptr;
252 }
253 #endif
254
255 /*********************************************/
256 /*           Adjust Rate for CRT2            */
257 /*********************************************/
258
259 static BOOLEAN
260 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
261                    USHORT RefreshRateTableIndex, USHORT *i,
262                    PSIS_HW_INFO HwInfo)
263 {
264   USHORT tempax,tempbx,infoflag;
265
266   tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
267
268   tempax = 0;
269
270   if(SiS_Pr->SiS_VBType & VB_SISVB) {
271
272      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
273
274         tempax |= SupportRAMDAC2;
275         if(HwInfo->jChipType >= SIS_315H) {
276            tempax |= SupportRAMDAC2_135;
277            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
278               tempax |= SupportRAMDAC2_162;
279               if(SiS_Pr->SiS_VBType & VB_SIS301C) {
280                  tempax |= SupportRAMDAC2_202;
281               }
282            }
283         }
284
285      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
286
287         tempax |= SupportLCD;
288         if(HwInfo->jChipType >= SIS_315H) {
289            if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
290               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
291                  if(tempbx == 0x2e) {  /* 640x480 */
292                     tempax |= Support64048060Hz;
293                  }
294               }
295            }
296         }
297
298      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
299
300         tempax |= SupportHiVision;
301
302      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
303
304         tempax |= SupportTV;
305         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
306            tempax |= SupportTV1024;
307         }
308
309      }
310
311   } else {      /* for LVDS  */
312
313      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
314         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
315            tempax |= SupportCHTV;
316         }
317      }
318
319      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
320         tempax |= SupportLCD;
321      }
322
323   }
324
325   /* Look backwards in table for matching CRT2 mode */
326   for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
327      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
328      if(infoflag & tempax) return(1);
329      if((*i) == 0) break;
330   }
331
332   /* Look through the whole mode-section of the table from the beginning
333    * for a matching CRT2 mode if no mode was found yet.
334    */
335   for((*i) = 0; ; (*i)++) {
336      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
337         return(0);
338      }
339      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
340      if(infoflag & tempax) return(1);
341   }
342   return(1);
343 }
344
345 /*********************************************/
346 /*              Get rate pointer             */
347 /*********************************************/
348
349 USHORT
350 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
351                PSIS_HW_INFO HwInfo)
352 {
353   SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
354                                0x01, 0x01, 0x01, 0x01,
355                                0x01, 0x01, 0x01, 0x01,
356                                0x01, 0x01, 0x01, 0x01,
357                                0x00, 0x00, 0x00, 0x00 };
358   USHORT RefreshRateTableIndex,i,backup_i;
359   USHORT modeflag,index,temp,backupindex;
360
361   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
362   if(ModeNo == 0xfe) return 0;
363
364   if(ModeNo <= 0x13)
365      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
366   else
367      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
368
369   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
370      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
371         if(modeflag & HalfDCLK) return(0);
372      }
373   }
374
375   if(ModeNo < 0x14) return(0xFFFF);
376
377   /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4]. */
378
379   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
380   backupindex = index;
381
382   if(index > 0) index--;
383
384   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
385      if(SiS_Pr->SiS_VBType & VB_SISVB) {
386         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
387            if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
388            else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
389         }
390         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
391            if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
392               temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
393               if(index > temp) index = temp;
394            }
395         }
396      } else {
397         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
398         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
399            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
400         }
401      }
402   }
403
404   RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
405   ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
406
407   if(HwInfo->jChipType >= SIS_315H) {
408      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
409         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
410             (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
411            if(backupindex <= 1) RefreshRateTableIndex++;
412         }
413      }
414   }
415
416   i = 0;
417   do {
418      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
419      temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
420      temp &= ModeInfoFlag;
421      if(temp < SiS_Pr->SiS_ModeType) break;
422      i++;
423      index--;
424   } while(index != 0xFFFF);
425
426   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
427      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
428         temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
429         if(temp & InterlaceMode) i++;
430      }
431   }
432
433   i--;
434
435   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
436      backup_i = i;
437      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
438         i = backup_i;
439      }
440   }
441
442   return(RefreshRateTableIndex + i);
443 }
444
445 /*********************************************/
446 /*            STORE CRT2 INFO in CR34        */
447 /*********************************************/
448
449 static void
450 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
451 {
452   USHORT temp1,temp2;
453
454   /* Store CRT1 ModeNo in CR34 */
455   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
456   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
457   temp2 = ~(SetInSlaveMode >> 8);
458   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
459 }
460
461 /*********************************************/
462 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
463 /*********************************************/
464
465 static BOOLEAN
466 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
467 {
468   USHORT temp,temp1;
469   UCHAR *ROMAddr;
470
471   if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
472      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
473         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
474         temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
475         if(temp1 & temp) return(1);
476      }
477   }
478   return(0);
479 }
480
481 static BOOLEAN
482 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
483 {
484   USHORT temp,temp1;
485   UCHAR *ROMAddr;
486
487   if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
488      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
489         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
490         temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
491         if(temp1 & temp) return(1);
492      }
493   }
494   return(0);
495 }
496
497 /*********************************************/
498 /*          HELPER: DELAY FUNCTIONS          */
499 /*********************************************/
500
501 void
502 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
503 {
504   USHORT i, j;
505
506   for(i=0; i<delaytime; i++) {
507      j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
508   }
509 }
510
511 static void
512 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
513 {
514   USHORT temp,flag;
515
516   flag = SiS_GetRegByte(0x61) & 0x10;
517
518   while(delay) {
519      temp = SiS_GetRegByte(0x61) & 0x10;
520      if(temp == flag) continue;
521      flag = temp;
522      delay--;
523   }
524 }
525
526 #ifdef SIS315H
527 static void
528 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
529 {
530   while(delay--) {
531      SiS_GenericDelay(SiS_Pr,0x19df);
532   }
533 }
534 #endif
535
536 static void
537 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
538 {
539   while(delay--) {
540      SiS_GenericDelay(SiS_Pr,0x42);
541   }
542 }
543
544 static void
545 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
546 {
547   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
548   USHORT PanelID, DelayIndex, Delay=0;
549
550   if(HwInfo->jChipType < SIS_315H) {
551
552 #ifdef SIS300
553
554       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
555       if(SiS_Pr->SiS_VBType & VB_SISVB) {
556          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
557       }
558       DelayIndex = PanelID >> 4;
559       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
560          Delay = 3;
561       } else {
562          if(DelayTime >= 2) DelayTime -= 2;
563
564          if(!(DelayTime & 0x01)) {
565             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
566          } else {
567             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
568          }
569          if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
570             if(ROMAddr[0x220] & 0x40) {
571                if(!(DelayTime & 0x01)) {
572                   Delay = (USHORT)ROMAddr[0x225];
573                } else {
574                   Delay = (USHORT)ROMAddr[0x226];
575                }
576             }
577          }
578       }
579       SiS_ShortDelay(SiS_Pr,Delay);
580
581 #endif  /* SIS300 */
582
583    } else {
584
585 #ifdef SIS315H
586
587       if(HwInfo->jChipType >= SIS_330) return;
588
589       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
590          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
591          (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {                      /* 315 series, LVDS; Special */
592
593          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
594             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
595             if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
596                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
597             }
598             if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
599                DelayIndex = PanelID & 0x0f;
600             } else {
601                DelayIndex = PanelID >> 4;
602             }
603             if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
604                Delay = 3;
605             } else {
606                if(DelayTime >= 2) DelayTime -= 2;
607                if(!(DelayTime & 0x01)) {
608                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
609                } else {
610                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
611                }
612                if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
613                   if(ROMAddr[0x13c] & 0x40) {
614                      if(!(DelayTime & 0x01)) {
615                         Delay = (USHORT)ROMAddr[0x17e];
616                      } else {
617                         Delay = (USHORT)ROMAddr[0x17f];
618                      }
619                   }
620                }
621             }
622             SiS_ShortDelay(SiS_Pr,Delay);
623          }
624
625       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                        /* 315 series, all bridges */
626
627          DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
628          if(!(DelayTime & 0x01)) {
629             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
630          } else {
631             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
632          }
633          Delay <<= 8;
634          SiS_DDC2Delay(SiS_Pr, Delay);
635
636       }
637
638 #endif /* SIS315H */
639
640    }
641 }
642
643 #ifdef SIS315H
644 static void
645 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
646                       USHORT DelayTime, USHORT DelayLoop)
647 {
648    int i;
649    for(i=0; i<DelayLoop; i++) {
650       SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
651    }
652 }
653 #endif
654
655 /*********************************************/
656 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
657 /*********************************************/
658
659 void
660 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
661 {
662   USHORT watchdog;
663
664   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
665
666   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
667
668   watchdog = 65535;
669   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
670   watchdog = 65535;
671   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
672 }
673
674 static void
675 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
676 {
677   USHORT watchdog;
678
679   watchdog = 65535;
680   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
681   watchdog = 65535;
682   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
683 }
684
685 static void
686 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
687 {
688   if(HwInfo->jChipType < SIS_315H) {
689 #ifdef SIS300
690      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
691         if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
692      }
693      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
694         SiS_WaitRetrace1(SiS_Pr);
695      } else {
696         SiS_WaitRetrace2(SiS_Pr, 0x25);
697      }
698 #endif
699   } else {
700 #ifdef SIS315H
701      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
702         SiS_WaitRetrace1(SiS_Pr);
703      } else {
704         SiS_WaitRetrace2(SiS_Pr, 0x30);
705      }
706 #endif
707   }
708 }
709
710 static void
711 SiS_VBWait(SiS_Private *SiS_Pr)
712 {
713   USHORT tempal,temp,i,j;
714
715   temp = 0;
716   for(i=0; i<3; i++) {
717     for(j=0; j<100; j++) {
718        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
719        if(temp & 0x01) {
720           if((tempal & 0x08))  continue;
721           if(!(tempal & 0x08)) break;
722        } else {
723           if(!(tempal & 0x08)) continue;
724           if((tempal & 0x08))  break;
725        }
726     }
727     temp ^= 0x01;
728   }
729 }
730
731 static void
732 SiS_VBLongWait(SiS_Private *SiS_Pr)
733 {
734   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
735      SiS_VBWait(SiS_Pr);
736   } else {
737      SiS_WaitRetrace1(SiS_Pr);
738   }
739 }
740
741 /*********************************************/
742 /*               HELPER: MISC                */
743 /*********************************************/
744
745 static BOOLEAN
746 SiS_Is301B(SiS_Private *SiS_Pr)
747 {
748   USHORT flag;
749
750   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
751   if(flag >= 0xb0) return TRUE;
752   return FALSE;
753 }
754
755 static BOOLEAN
756 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
757 {
758   USHORT flag;
759
760   if(HwInfo->jChipType == SIS_730) {
761      flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
762      if(flag & 0x20) return TRUE;
763   }
764   flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
765   if(flag & 0x20) return TRUE;
766   return FALSE;
767 }
768
769 BOOLEAN
770 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
771 {
772 #ifdef SIS315H
773   USHORT flag;
774
775   if(HwInfo->jChipType >= SIS_315H) {
776      if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
777         flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
778         if(flag & EnableDualEdge) return TRUE;
779      }
780   }
781 #endif
782   return FALSE;
783 }
784
785 BOOLEAN
786 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
787 {
788 #ifdef SIS315H
789   USHORT flag;
790
791   if(HwInfo->jChipType >= SIS_315H) {
792      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
793      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
794   }
795 #endif
796   return FALSE;
797 }
798
799 static BOOLEAN
800 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
801 {
802 #ifdef SIS315H
803   if(HwInfo->jChipType >= SIS_315H) {
804      if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
805         (SiS_IsVAMode(SiS_Pr, HwInfo))) {
806         if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
807      }
808   }
809 #endif
810   return FALSE;
811 }
812
813 #ifdef SIS315H
814 static BOOLEAN
815 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
816 {
817   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
818   if(SiS_Pr->SiS_VBType & (VB_301C | VB_SIS301LV302LV)) {
819      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
820   }
821   return FALSE;
822 }
823 #endif
824
825 #ifdef SIS315H
826 static BOOLEAN
827 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
828 {
829   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
830   return FALSE;
831 }
832 #endif
833
834 #ifdef SIS315H
835 static BOOLEAN
836 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
837 {
838   USHORT flag;
839
840   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
841      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
842      if(flag & 0x10) return TRUE;
843   }
844   return FALSE;
845 }
846 #endif
847
848 #ifdef SIS315H
849 static BOOLEAN
850 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
851 {
852   USHORT flag;
853
854   if(HwInfo->jChipType == SIS_650) {
855      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
856      flag &= 0xF0;
857      /* Check for revision != A0 only */
858      if((flag == 0xe0) || (flag == 0xc0) ||
859         (flag == 0xb0) || (flag == 0x90)) return FALSE;
860   } else if(HwInfo->jChipType >= SIS_661) return FALSE;
861   return TRUE;
862 }
863 #endif
864
865 #ifdef SIS315H
866 static BOOLEAN
867 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
868 {
869   USHORT flag;
870
871   if(HwInfo->jChipType >= SIS_315H) {
872      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
873      if(flag & EnableCHYPbPr) return TRUE;  /* = YPrPb = 0x08 */
874   }
875   return FALSE;
876 }
877 #endif
878
879 #ifdef SIS315H
880 static BOOLEAN
881 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
882 {
883   USHORT flag;
884
885   if(HwInfo->jChipType >= SIS_315H) {
886      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
887      if(flag & EnableCHScart) return TRUE;  /* = Scart = 0x04 */
888   }
889   return FALSE;
890 }
891 #endif
892
893 #ifdef SIS315H
894 static BOOLEAN
895 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
896 {
897   USHORT flag;
898
899   if(HwInfo->jChipType >= SIS_315H) {
900      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
901      if(flag & SetCRT2ToTV)        return TRUE;
902      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
903      if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
904      if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
905   } else {
906      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
907      if(flag & SetCRT2ToTV)        return TRUE;
908   }
909   return FALSE;
910 }
911 #endif
912
913 #ifdef SIS315H
914 static BOOLEAN
915 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
916 {
917   USHORT flag;
918
919   if(HwInfo->jChipType >= SIS_315H) {
920      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
921      if(flag & SetCRT2ToLCD) return TRUE;
922      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
923      if(flag & SetToLCDA)    return TRUE;
924   } else {
925      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
926      if(flag & SetCRT2ToLCD) return TRUE;
927   }
928   return FALSE;
929 }
930 #endif
931
932 static BOOLEAN
933 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
934 {
935   USHORT flag;
936
937   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
938      return FALSE;
939   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
940      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
941      if((flag == 1) || (flag == 2)) return FALSE;
942   }
943   return TRUE;
944 }
945
946 static BOOLEAN
947 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
948 {
949   USHORT flag;
950
951   if(!(SiS_BridgeIsOn(SiS_Pr))) {
952      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
953      if(HwInfo->jChipType < SIS_315H) {
954        flag &= 0xa0;
955        if((flag == 0x80) || (flag == 0x20)) return FALSE;
956      } else {
957        flag &= 0x50;
958        if((flag == 0x40) || (flag == 0x10)) return FALSE;
959      }
960   }
961   return TRUE;
962 }
963
964 static BOOLEAN
965 SiS_BridgeInSlave(SiS_Private *SiS_Pr)
966 {
967   USHORT flag1;
968
969   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
970   if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
971   return FALSE;
972 }
973
974 /*********************************************/
975 /*       GET VIDEO BRIDGE CONFIG INFO        */
976 /*********************************************/
977
978 /* Setup general purpose IO for Chrontel communication */
979 void
980 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
981 {
982    unsigned long  acpibase;
983    unsigned short temp;
984
985    if(!(SiS_Pr->SiS_ChSW)) return;
986
987 #ifndef LINUX_XF86
988    SiS_SetRegLong(0xcf8,0x80000874);               /* get ACPI base */
989    acpibase = SiS_GetRegLong(0xcfc);
990 #else
991    acpibase = pciReadLong(0x00000800, 0x74);
992 #endif
993    acpibase &= 0xFFFF;
994    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
995    temp &= 0xFEFF;
996    SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
997    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
998    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
999    temp &= 0xFEFF;
1000    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1001    SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
1002    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
1003 }
1004
1005 void
1006 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
1007               USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
1008               int checkcrt2mode)
1009 {
1010   USHORT tempax,tempbx,temp;
1011   USHORT modeflag, resinfo=0;
1012
1013   if(ModeNo <= 0x13) {
1014      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1015   } else {
1016      if(SiS_Pr->UseCustomMode) {
1017         modeflag = SiS_Pr->CModeFlag;
1018      } else {
1019         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1020         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1021      }
1022   }
1023
1024   SiS_Pr->SiS_SetFlag = 0;
1025
1026   SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
1027
1028   tempbx = 0;
1029   if(SiS_BridgeIsOn(SiS_Pr) == 0) {
1030         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1031 #if 0
1032         if(HwInfo->jChipType < SIS_661) {
1033            /* NO - YPbPr not set yet ! */
1034            if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
1035               temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
1036               temp |= SetCRT2ToHiVision;                                        /* 0x80 */
1037            }
1038            if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
1039               temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
1040               temp |= SetCRT2ToSVIDEO;                                          /* 0x08 */
1041            }
1042         }
1043 #endif
1044         tempbx |= temp;
1045         tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1046         tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1047         tempbx |= tempax;
1048
1049 #ifdef SIS315H
1050         if(HwInfo->jChipType >= SIS_315H) {
1051            if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1052               if(ModeNo == 0x03) {
1053                  /* Mode 0x03 is never in driver mode */
1054                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1055               }
1056               if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1057                  /* Reset LCDA setting */
1058                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1059               }
1060               if(IS_SIS650) {
1061                  if(SiS_Pr->SiS_UseLCDA) {
1062                     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1063                        if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1064                           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1065                        }
1066                     }
1067                  }
1068               }
1069               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1070               if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1071                  tempbx |= SetCRT2ToLCDA;
1072               }
1073            }
1074            if(HwInfo->jChipType >= SIS_661) {
1075               tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1076               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1077               if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1078                  if(temp & 0x04) {
1079                     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1080                     if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1081                     else             tempbx |= SetCRT2ToYPbPr525750;
1082                  }
1083               } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
1084                  if(temp & 0x04) {
1085                     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1086                     if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1087                  }
1088               }
1089            }
1090
1091            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1092               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1093               if(temp & SetToLCDA) {
1094                  tempbx |= SetCRT2ToLCDA;
1095               }
1096               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1097                  if(temp & EnableCHYPbPr) {
1098                     tempbx |= SetCRT2ToCHYPbPr;
1099                  }
1100               }
1101            }
1102         }
1103
1104 #endif  /* SIS315H */
1105
1106         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1107            temp = SetCRT2ToSVIDEO   |
1108                   SetCRT2ToAVIDEO   |
1109                   SetCRT2ToSCART    |
1110                   SetCRT2ToLCDA     |
1111                   SetCRT2ToLCD      |
1112                   SetCRT2ToRAMDAC   |
1113                   SetCRT2ToHiVision |
1114                   SetCRT2ToYPbPr525750;
1115         } else {
1116            if(HwInfo->jChipType >= SIS_315H) {
1117               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1118                  temp = SetCRT2ToAVIDEO |
1119                         SetCRT2ToSVIDEO |
1120                         SetCRT2ToSCART  |
1121                         SetCRT2ToLCDA   |
1122                         SetCRT2ToLCD    |
1123                         SetCRT2ToCHYPbPr;
1124               } else {
1125                  temp = SetCRT2ToLCDA   |
1126                         SetCRT2ToLCD;
1127               }
1128            } else {
1129               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1130                  temp = SetCRT2ToTV | SetCRT2ToLCD;
1131               } else {
1132                  temp = SetCRT2ToLCD;
1133               }
1134            }
1135         }
1136
1137         if(!(tempbx & temp)) {
1138            tempax = DisableCRT2Display;
1139            tempbx = 0;
1140         }
1141
1142         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1143            USHORT clearmask = ( DriverMode         |
1144                                 DisableCRT2Display |
1145                                 LoadDACFlag        |
1146                                 SetNotSimuMode     |
1147                                 SetInSlaveMode     |
1148                                 SetPALTV           |
1149                                 SwitchCRT2         |
1150                                 SetSimuScanMode );
1151            if(tempbx & SetCRT2ToLCDA) {
1152               tempbx &= (clearmask | SetCRT2ToLCDA);
1153            }
1154            if(tempbx & SetCRT2ToRAMDAC) {
1155               tempbx &= (clearmask | SetCRT2ToRAMDAC);
1156            }
1157            if(tempbx & SetCRT2ToLCD) {
1158               tempbx &= (clearmask | SetCRT2ToLCD);
1159            }
1160            if(tempbx & SetCRT2ToSCART) {
1161               tempbx &= (clearmask | SetCRT2ToSCART);
1162            }
1163            if(tempbx & SetCRT2ToHiVision) {
1164               tempbx &= (clearmask | SetCRT2ToHiVision);
1165            }
1166            if(tempbx & SetCRT2ToYPbPr525750) {
1167               tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1168            }
1169         } else {
1170            if(HwInfo->jChipType >= SIS_315H) {
1171               if(tempbx & SetCRT2ToLCDA) {
1172                  tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1173               }
1174            }
1175            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1176               if(tempbx & SetCRT2ToTV) {
1177                  tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1178               }
1179            }
1180            if(tempbx & SetCRT2ToLCD) {
1181               tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1182            }
1183            if(HwInfo->jChipType >= SIS_315H) {
1184               if(tempbx & SetCRT2ToLCDA) {
1185                  tempbx |= SetCRT2ToLCD;
1186               }
1187            }
1188         }
1189
1190         if(tempax & DisableCRT2Display) {
1191            if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1192               tempbx = SetSimuScanMode | DisableCRT2Display;
1193            }
1194         }
1195
1196         if(!(tempbx & DriverMode)){
1197            tempbx |= SetSimuScanMode;
1198         }
1199
1200         /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1201         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1202            if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1203                ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
1204                modeflag &= (~CRT2Mode);
1205            }
1206         }
1207
1208         if(!(tempbx & SetSimuScanMode)) {
1209            if(tempbx & SwitchCRT2) {
1210               if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1211                  if( (HwInfo->jChipType >= SIS_315H) &&
1212                      (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1213                     if(resinfo != SIS_RI_1600x1200) {
1214                        tempbx |= SetSimuScanMode;
1215                     }
1216                  } else {
1217                     tempbx |= SetSimuScanMode;
1218                  }
1219               }
1220            } else {
1221               if(!(SiS_BridgeIsEnabled(SiS_Pr,HwInfo))) {
1222                  if(!(tempbx & DriverMode)) {
1223                     if(SiS_BridgeInSlave(SiS_Pr)) {
1224                        tempbx |= SetSimuScanMode;
1225                     }
1226                  }
1227               }
1228            }
1229         }
1230
1231         if(!(tempbx & DisableCRT2Display)) {
1232            if(tempbx & DriverMode) {
1233               if(tempbx & SetSimuScanMode) {
1234                  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1235                     if( (HwInfo->jChipType >= SIS_315H) &&
1236                         (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1237                        if(resinfo != SIS_RI_1600x1200) {
1238                           tempbx |= SetInSlaveMode;
1239                        }
1240                     } else {
1241                        tempbx |= SetInSlaveMode;
1242                     }
1243                  }
1244               }
1245            } else {
1246               tempbx |= SetInSlaveMode;
1247            }
1248         }
1249
1250   }
1251
1252   SiS_Pr->SiS_VBInfo = tempbx;
1253
1254   if(HwInfo->jChipType == SIS_630) {
1255      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1256   }
1257
1258 #ifdef TWDEBUG
1259 #ifdef LINUX_KERNEL
1260   printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1261       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1262 #endif
1263 #ifdef LINUX_XF86
1264   xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1265       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1266 #endif
1267 #endif
1268 }
1269
1270 /*********************************************/
1271 /*           DETERMINE YPbPr MODE            */
1272 /*********************************************/
1273
1274 void
1275 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1276 {
1277
1278   UCHAR temp;
1279
1280   /* Note: This variable is only used on 30xLV systems.
1281    * CR38 has a different meaning on LVDS/CH7019 systems.
1282    * On 661 and later, these bits moved to CR35.
1283    *
1284    * On 301, 301B, only HiVision 1080i is supported.
1285    * On 30xLV, 301C, only YPbPr 1080i is supported.
1286    */
1287
1288   SiS_Pr->SiS_YPbPr = 0;
1289   if(HwInfo->jChipType >= SIS_661) return;
1290
1291   if(SiS_Pr->SiS_VBType) {
1292      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1293         SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1294      }
1295   }
1296
1297   if(HwInfo->jChipType >= SIS_315H) {
1298      if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1299         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1300         if(temp & 0x08) {
1301            switch((temp >> 4)) {
1302            case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1303            case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1304            case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1305            case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1306            }
1307         }
1308      }
1309   }
1310
1311 }
1312
1313 /*********************************************/
1314 /*           DETERMINE TVMode flag           */
1315 /*********************************************/
1316
1317 void
1318 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1319 {
1320   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1321   USHORT temp, temp1, resinfo = 0, romindex = 0;
1322   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1323
1324   SiS_Pr->SiS_TVMode = 0;
1325
1326   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1327   if(SiS_Pr->UseCustomMode) return;
1328
1329   if(ModeNo > 0x13) {
1330      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1331   }
1332
1333   if(HwInfo->jChipType < SIS_661) {
1334
1335      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1336
1337      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1338         temp = 0;
1339         if((HwInfo->jChipType == SIS_630) ||
1340            (HwInfo->jChipType == SIS_730)) {
1341            temp = 0x35;
1342            romindex = 0xfe;
1343         } else if(HwInfo->jChipType >= SIS_315H) {
1344            temp = 0x38;
1345            romindex = 0xf3;
1346            if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1347         }
1348         if(temp) {
1349            if(romindex && ROMAddr && SiS_Pr->SiS_UseROM) {
1350               OutputSelect = ROMAddr[romindex];
1351               if(!(OutputSelect & EnablePALMN)) {
1352                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1353               }
1354            }
1355            temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1356            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1357               if(temp1 & EnablePALM) {          /* 0x40 */
1358                  SiS_Pr->SiS_TVMode |= TVSetPALM;
1359                  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1360               } else if(temp1 & EnablePALN) {   /* 0x80 */
1361                  SiS_Pr->SiS_TVMode |= TVSetPALN;
1362               }
1363            } else {
1364               if(temp1 & EnableNTSCJ) {         /* 0x40 */
1365                  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1366               }
1367            }
1368         }
1369         /* Translate HiVision/YPbPr to our new flags */
1370         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1371            if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1372            else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1373            else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1374            else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1375            if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1376               SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1377               SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1378            } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1379               SiS_Pr->SiS_TVMode |= TVSetPAL;
1380            }
1381         }
1382      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1383         if(SiS_Pr->SiS_CHOverScan) {
1384            if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1385               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1386               if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1387                  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1388               }
1389            } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1390               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1391               if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1392                  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1393               }
1394            }
1395            if(SiS_Pr->SiS_CHSOverScan) {
1396               SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1397            }
1398         }
1399         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1400            temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1401            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1402               if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1403               else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1404            } else {
1405               if(temp & EnableNTSCJ) {
1406                  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1407               }
1408            }
1409         }
1410      }
1411
1412   } else {  /* 661 and later */
1413
1414      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1415      if(temp1 & 0x01) {
1416         SiS_Pr->SiS_TVMode |= TVSetPAL;
1417         if(temp1 & 0x08) {
1418            SiS_Pr->SiS_TVMode |= TVSetPALN;
1419         } else if(temp1 & 0x04) {
1420            if(SiS_Pr->SiS_VBType & VB_SISVB) {
1421               SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1422            }
1423            SiS_Pr->SiS_TVMode |= TVSetPALM;
1424         }
1425      } else {
1426         if(temp1 & 0x02) {
1427            SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1428         }
1429      }
1430      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1431         if(SiS_Pr->SiS_CHOverScan) {
1432            if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1433               SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1434            }
1435         }
1436      }
1437      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1438         if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1439            temp1 &= 0xe0;
1440            if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1441            else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1442            else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1443         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1444            SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1445         }
1446      }
1447   }
1448
1449   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1450
1451   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1452
1453      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1454         SiS_Pr->SiS_TVMode |= TVSetPAL;
1455         SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1456      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1457         if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1458            SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1459         }
1460      }
1461
1462      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1463         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1464            SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1465         }
1466      }
1467
1468      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1469         /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1470         if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1471            if(resinfo == SIS_RI_1024x768) {
1472               SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1473            }
1474         }
1475      }
1476
1477      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1478      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1479         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1480         SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1481      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1482         SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1483      } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1484         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1485            SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1486         }
1487      }
1488
1489   }
1490
1491   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1492
1493 #ifdef TWDEBUG
1494   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1495 #endif
1496
1497 }
1498
1499 /*********************************************/
1500 /*               GET LCD INFO                */
1501 /*********************************************/
1502
1503 void
1504 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1505                   PSIS_HW_INFO HwInfo)
1506 {
1507 #ifdef SIS300
1508   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1509 #endif
1510 #ifdef SIS315H
1511   UCHAR  *myptr = NULL;
1512 #endif
1513   USHORT temp,modeflag,resinfo=0;
1514   const unsigned char SiS300SeriesLCDRes[] =
1515          { 0,  1,  2,  3,  7,  4,  5,  8,
1516            0,  0, 10,  0,  0,  0,  0, 15 };
1517
1518   SiS_Pr->SiS_LCDResInfo = 0;
1519   SiS_Pr->SiS_LCDTypeInfo = 0;
1520   SiS_Pr->SiS_LCDInfo = 0;
1521
1522   if(SiS_Pr->UseCustomMode) {
1523      modeflag = SiS_Pr->CModeFlag;
1524   } else {
1525      if(ModeNo <= 0x13) {
1526         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1527      } else {
1528         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1529         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1530      }
1531   }
1532
1533   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1534
1535   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1536
1537   if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1538      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1539   } else {
1540      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1541   }
1542   temp &= 0x0f;
1543   if(HwInfo->jChipType < SIS_315H) {
1544       /* Translate 300 series LCDRes to 315 series for unified usage */
1545       temp = SiS300SeriesLCDRes[temp];
1546   }
1547   SiS_Pr->SiS_LCDResInfo = temp;
1548
1549   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1550      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1551         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1552   } else {
1553      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1554         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1555   }
1556
1557   if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
1558      if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
1559         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
1560   }
1561
1562   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1563      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1564         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1565      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1566         SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1567      }
1568   }
1569
1570   switch(SiS_Pr->SiS_LCDResInfo) {
1571      case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
1572      case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
1573      case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
1574      case Panel_640x480_3:
1575      case Panel_640x480_2:
1576      case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
1577      case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
1578      case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
1579      case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
1580      case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
1581      case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
1582      case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
1583      case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
1584      case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
1585      case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1586                            SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1587                            break;
1588      case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
1589      case Panel_848x480:   SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480; break;
1590      default:              SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
1591   }
1592
1593   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1594   if(HwInfo->jChipType < SIS_661) {
1595      temp &= ~0xe;
1596   } else {
1597 #ifdef SIS315H
1598      if(!(temp & 0x10)) {
1599         if(temp & 0x08) temp |= LCDPass11;
1600      }
1601      temp &= ~0xe;
1602      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1603         myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
1604         if(myptr) {
1605            if(myptr[2] & 0x01) temp |= LCDDualLink;
1606         }
1607      }
1608 #endif
1609   }
1610   SiS_Pr->SiS_LCDInfo = temp;
1611
1612   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1613      if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1614         SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24 */
1615      }
1616   }
1617
1618   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1619   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1620
1621   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1622      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
1623         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
1624            /* For non-standard LCD resolution, we let the panel scale */
1625            SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1626         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
1627            if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
1628               /* We do not scale to 1280x960 (B/C bridges only) */
1629               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1630            }
1631            if(((HwInfo->jChipType >= SIS_315H) && (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
1632               ((HwInfo->jChipType < SIS_315H)  && (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
1633               /* We do not scale to 1280x768 (B/C bridges only) */
1634               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1635            }
1636            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1637               /* No non-scaling data available for LV bridges */
1638               SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639            }
1640         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
1641            /* No idea about the timing and zoom factors */
1642            SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1643         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
1644            if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
1645               /* We do not scale to 1280x1024 (all bridges) */
1646               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1647            }
1648         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
1649            if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
1650               /* No idea about the timing and zoom factors (C bridge only) */
1651               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1652            }
1653         }
1654         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1655            if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
1656               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
1657                  SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1658               }
1659            }
1660         }
1661      }
1662   }
1663
1664   if(HwInfo->jChipType >= SIS_315H) {
1665 #ifdef SIS315H
1666      if(HwInfo->jChipType < SIS_661) {
1667         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
1668            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1669            SiS_Pr->SiS_LCDInfo |= LCDPass11;
1670         }
1671      }
1672 #endif
1673   } else {
1674 #ifdef SIS300
1675      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1676         if((ROMAddr) && SiS_Pr->SiS_UseROM) {
1677            if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
1678               if(!(ROMAddr[0x235] & 0x02)) {
1679                  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1680               }
1681            }
1682         }
1683      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1684         if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
1685            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1686         }
1687      }
1688 #endif
1689   }
1690
1691   /* Trumpion: Assume non-expanding */
1692   if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
1693      SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1694   }
1695
1696   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1697      SiS_Pr->SiS_LCDInfo &= (~LCDPass11);
1698   }
1699
1700 #ifdef SIS315H
1701   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
1702      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1703         /* Enable 302LV/302ELV dual link mode.
1704          * For 661, this is done above.
1705          */
1706         if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1707            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)) {
1708            /* (Sets this in SenseLCD; new paneltypes) */
1709            SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1710         }
1711         if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
1712            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
1713            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
1714            SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1715         }
1716      }
1717   }
1718 #endif
1719
1720   if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
1721
1722      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1723         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
1724            if(ModeNo > 0x13) {
1725               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1726                  if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
1727                     SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1728                  }
1729               }
1730            }
1731         }
1732         if(ModeNo == 0x12) {
1733            if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
1734               SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1735            }
1736         }
1737      }
1738
1739      if(modeflag & HalfDCLK) {
1740         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
1741            if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1742               if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwInfo->jChipType < SIS_315H)) &&
1743                                               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
1744                  if(ModeNo > 0x13) {
1745                     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
1746                        if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1747                     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
1748                        if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1749                     }
1750                  }
1751               } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1752            } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1753         } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1754      }
1755
1756   }
1757
1758   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1759      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
1760         SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1761      }
1762   } else {
1763      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1764   }
1765
1766   SiS_Pr->SiS_LCDInfo661 = 0;
1767   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) SiS_Pr->SiS_LCDInfo661 |= 0x0001;
1768   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) SiS_Pr->SiS_LCDInfo661 |= 0x0002;
1769   if(SiS_Pr->SiS_LCDInfo & LCDPass11)     SiS_Pr->SiS_LCDInfo661 |= 0x0008;
1770   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) SiS_Pr->SiS_LCDInfo661 |= 0x0010;
1771   SiS_Pr->SiS_LCDInfo661 |= (SiS_Pr->SiS_LCDInfo & 0xe0);
1772   if(SiS_Pr->SiS_LCDInfo & LCDDualLink)   SiS_Pr->SiS_LCDInfo661 |= 0x0100;
1773
1774 #ifdef LINUX_KERNEL
1775 #ifdef TWDEBUG
1776   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
1777         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
1778 #endif
1779 #endif
1780 #ifdef LINUX_XF86
1781   xf86DrvMsgVerb(0, X_PROBED, 4,
1782         "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
1783         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
1784 #endif
1785 }
1786
1787 /*********************************************/
1788 /*                 GET VCLK                  */
1789 /*********************************************/
1790
1791 USHORT
1792 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1793                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
1794 {
1795   USHORT tempbx;
1796   const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
1797   const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
1798   const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
1799 #ifdef SIS300
1800   const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
1801   const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
1802   const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
1803   const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
1804 #endif
1805 #ifdef SIS315H
1806   const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
1807   const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
1808   const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
1809   const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
1810 #endif
1811   USHORT CRT2Index,VCLKIndex=0;
1812   USHORT modeflag,resinfo;
1813   const UCHAR  *CHTVVCLKPtr = NULL;
1814   const USHORT *LCDXlatVCLK1 = NULL;
1815   const USHORT *LCDXlatVCLK2 = NULL;
1816   const USHORT *LVDSXlatVCLK2 = NULL;
1817   const USHORT *LVDSXlatVCLK3 = NULL;
1818
1819   if(HwInfo->jChipType >= SIS_315H) {
1820 #ifdef SIS315H
1821      LCDXlatVCLK1 = LCDXlat1VCLK310;
1822      LCDXlatVCLK2 = LCDXlat2VCLK310;
1823      LVDSXlatVCLK2 = LVDSXlat2VCLK310;
1824      LVDSXlatVCLK3 = LVDSXlat3VCLK310;
1825 #endif
1826   } else {
1827 #ifdef SIS300
1828      LCDXlatVCLK1 = LCDXlat1VCLK300;
1829      LCDXlatVCLK2 = LCDXlat2VCLK300;
1830      LVDSXlatVCLK2 = LVDSXlat2VCLK300;
1831      LVDSXlatVCLK3 = LVDSXlat3VCLK300;
1832 #endif
1833   }
1834
1835   if(ModeNo <= 0x13) {
1836      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1837      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
1838      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
1839   } else {
1840      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1841      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1842      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1843   }
1844
1845   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
1846
1847      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
1848
1849         CRT2Index >>= 6;
1850         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
1851
1852            if(HwInfo->jChipType < SIS_315H) {
1853               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
1854                  VCLKIndex = LCDXlat0VCLK[CRT2Index];
1855               } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
1856                  VCLKIndex = LCDXlatVCLK1[CRT2Index];
1857               } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
1858                  VCLKIndex = LCDXlatVCLK1[CRT2Index];
1859               } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
1860                  VCLKIndex = LCDXlatVCLK1[CRT2Index];
1861               } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
1862                  VCLKIndex = VCLK81_300;        /* guessed */
1863               } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
1864                  VCLKIndex = VCLK108_3_300;
1865                  if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
1866               } else {
1867                  VCLKIndex = LCDXlatVCLK2[CRT2Index];
1868               }
1869            } else {
1870               if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
1871                   (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
1872                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
1873                     VCLKIndex = VCLK108_2_315;
1874                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
1875                     VCLKIndex = VCLK81_315;     /* guessed */
1876                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
1877                     VCLKIndex = VCLK108_2_315;
1878                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
1879                     VCLKIndex = VCLK162_315;
1880                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
1881                     VCLKIndex = VCLK108_3_315;
1882                     if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
1883                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
1884                     VCLKIndex = LCDXlatVCLK1[CRT2Index];
1885                  } else {
1886                     VCLKIndex = LCDXlatVCLK2[CRT2Index];
1887                  }
1888               } else {
1889                  VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
1890                  VCLKIndex = ((VCLKIndex >> 2) & 0x03);
1891                  if(ModeNo > 0x13) {
1892                     VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1893                  }
1894                  if(ModeNo <= 0x13) {
1895                     if(HwInfo->jChipType <= SIS_315PRO) {
1896                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
1897                     } else {
1898                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
1899                     }
1900                  }
1901                  if(HwInfo->jChipType <= SIS_315PRO) {
1902                     if(VCLKIndex == 0) VCLKIndex = 0x41;
1903                     if(VCLKIndex == 1) VCLKIndex = 0x43;
1904                     if(VCLKIndex == 4) VCLKIndex = 0x44;
1905                  }
1906               }
1907            }
1908
1909         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
1910
1911            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1912               if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
1913               else                                  VCLKIndex = HiTVVCLK;
1914               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1915                  if(modeflag & Charx8Dot)           VCLKIndex = HiTVSimuVCLK;
1916                  else                               VCLKIndex = HiTVTextVCLK;
1917               }
1918            } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK - TVCLKBASE_315;
1919            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   VCLKIndex = TVVCLKDIV2;
1920            else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)     VCLKIndex = TVVCLKDIV2;
1921            else                                           VCLKIndex = TVVCLK;
1922
1923            if(HwInfo->jChipType < SIS_315H) {
1924               VCLKIndex += TVCLKBASE_300;
1925            } else {
1926               VCLKIndex += TVCLKBASE_315;
1927            }
1928
1929         } else {                                                /* VGA2 */
1930
1931            VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
1932            VCLKIndex = ((VCLKIndex >> 2) & 0x03);
1933            if(ModeNo > 0x13) {
1934               VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1935               if(HwInfo->jChipType < SIS_315H) {
1936                  VCLKIndex &= 0x3f;
1937                  if( (HwInfo->jChipType == SIS_630) &&
1938                      (HwInfo->jChipRevision >= 0x30)) {
1939                     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
1940                  }
1941                  /* Better VGA2 clock for 1280x1024@75 */
1942                  if(VCLKIndex == 0x17) VCLKIndex = 0x45;
1943               }
1944            }
1945         }
1946
1947      } else {   /* If not programming CRT2 */
1948
1949         VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
1950         VCLKIndex = ((VCLKIndex >> 2) & 0x03);
1951         if(ModeNo > 0x13) {
1952            VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1953            if(HwInfo->jChipType < SIS_315H) {
1954               VCLKIndex &= 0x3f;
1955               if( (HwInfo->jChipType != SIS_630) &&
1956                   (HwInfo->jChipType != SIS_300) ) {
1957                  if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
1958               }
1959            }
1960         }
1961      }
1962
1963   } else {       /*   LVDS  */
1964
1965      VCLKIndex = CRT2Index;
1966
1967      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
1968
1969         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
1970
1971            VCLKIndex &= 0x1f;
1972            tempbx = 0;
1973            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
1974            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1975               tempbx += 2;
1976               if(SiS_Pr->SiS_ModeType > ModeVGA) {
1977                  if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
1978               }
1979               if(SiS_Pr->SiS_TVMode & TVSetPALM) {
1980                  tempbx = 4;
1981                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
1982               } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
1983                  tempbx = 6;
1984                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
1985               }
1986            }
1987            switch(tempbx) {
1988              case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
1989              case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
1990              case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
1991              case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
1992              case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
1993              case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
1994              case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
1995              case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
1996              case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
1997              default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
1998            }
1999            VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2000
2001         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2002
2003            VCLKIndex >>= 6;
2004            if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
2005               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
2006               VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
2007            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
2008                    SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
2009                    SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
2010               VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
2011            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
2012               VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
2013            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
2014               VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
2015            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
2016               VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
2017            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)
2018               VCLKIndex = VCLK68_315;
2019            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
2020               VCLKIndex = VCLK162_315;
2021            else
2022               VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
2023
2024            if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
2025               /* Special Timing: Barco iQ Pro R series */
2026               VCLKIndex = 0x44;
2027            }
2028
2029            if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2030               if(HwInfo->jChipType < SIS_315H) {
2031                  VCLKIndex = VCLK34_300;
2032                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2033               } else {
2034                  VCLKIndex = VCLK34_315;
2035                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2036               }
2037            }
2038
2039         } else {
2040
2041            VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
2042            VCLKIndex = ((VCLKIndex >> 2) & 0x03);
2043            if(ModeNo > 0x13) {
2044               VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2045               if(HwInfo->jChipType < SIS_315H) {
2046                  VCLKIndex &= 0x3F;
2047               }
2048               if( (HwInfo->jChipType == SIS_630) &&
2049                   (HwInfo->jChipRevision >= 0x30) ) {
2050                  if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2051               }
2052            }
2053         }
2054
2055      } else {  /* if not programming CRT2 */
2056
2057         VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
2058         VCLKIndex = ((VCLKIndex >> 2) & 0x03);
2059         if(ModeNo > 0x13) {
2060            VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2061            if(HwInfo->jChipType < SIS_315H) {
2062               VCLKIndex &= 0x3F;
2063               if( (HwInfo->jChipType != SIS_630) &&
2064                   (HwInfo->jChipType != SIS_300) ) {
2065                  if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2066               }
2067 #if 0
2068               if(HwInfo->jChipType == SIS_730) {
2069                  if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2070                  if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2071               }
2072 #endif
2073            }
2074         }
2075
2076      }
2077
2078   }
2079
2080 #ifdef TWDEBUG
2081   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2082 #endif
2083
2084   return(VCLKIndex);
2085 }
2086
2087 /*********************************************/
2088 /*        SET CRT2 MODE TYPE REGISTERS       */
2089 /*********************************************/
2090
2091 static void
2092 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2093                     PSIS_HW_INFO HwInfo)
2094 {
2095   USHORT i,j,modeflag;
2096   USHORT tempcl,tempah=0;
2097 #ifdef SIS300
2098   USHORT temp;
2099 #endif
2100 #ifdef SIS315H
2101   USHORT tempbl, tempah2, tempbl2;
2102 #endif
2103
2104   if(ModeNo <= 0x13) {
2105      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2106   } else {
2107      if(SiS_Pr->UseCustomMode) {
2108         modeflag = SiS_Pr->CModeFlag;
2109      } else {
2110         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2111      }
2112   }
2113
2114   /* BIOS does not do this (neither 301 nor LVDS) */
2115   /* (But it's harmless; see SetCRT2Offset) */
2116   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
2117
2118   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2119
2120      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2121      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2122
2123   } else {
2124
2125      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2126
2127      tempcl = SiS_Pr->SiS_ModeType;
2128
2129      if(HwInfo->jChipType < SIS_315H) {
2130
2131 #ifdef SIS300    /* ---- 300 series ---- */
2132
2133         /* For 301BDH: (with LCD via LVDS) */
2134         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2135            temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2136            temp &= 0xef;
2137            temp |= 0x02;
2138            if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2139               temp |= 0x10;
2140               temp &= 0xfd;
2141            }
2142            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
2143         }
2144
2145         if(ModeNo > 0x13) {
2146            tempcl -= ModeVGA;
2147            if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
2148               tempah = ((0x10 >> tempcl) | 0x80);
2149            }
2150         } else tempah = 0x80;
2151
2152         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2153
2154 #endif  /* SIS300 */
2155
2156      } else {
2157
2158 #ifdef SIS315H    /* ------- 315/330 series ------ */
2159
2160         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2161            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2162               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2163            }
2164         }
2165
2166         if(ModeNo > 0x13) {
2167            tempcl -= ModeVGA;
2168            if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
2169               tempah = (0x08 >> tempcl);
2170               if (tempah == 0) tempah = 1;
2171               tempah |= 0x40;
2172            }
2173         } else tempah = 0x40;
2174
2175         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2176
2177 #endif  /* SIS315H */
2178
2179      }
2180
2181      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2182
2183      if(HwInfo->jChipType < SIS_315H) {
2184         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2185      } else {
2186         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2187            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2188         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2189            if(IS_SIS740) {
2190               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2191            } else {
2192               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2193            }
2194         }
2195      }
2196
2197      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2198
2199         tempah = 0x01;
2200         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2201            tempah |= 0x02;
2202         }
2203         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2204            tempah ^= 0x05;
2205            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2206               tempah ^= 0x01;
2207            }
2208         }
2209
2210         if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2211
2212         if(HwInfo->jChipType < SIS_315H) {
2213
2214            tempah = (tempah << 5) & 0xFF;
2215            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2216            tempah = (tempah >> 5) & 0xFF;
2217
2218         } else {
2219
2220            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2221
2222         }
2223
2224         if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2225            tempah |= 0x10;
2226         }
2227
2228         if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2229            if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
2230               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
2231               tempah |= 0x80;
2232            }
2233         } else {
2234            tempah |= 0x80;
2235         }
2236
2237         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2238            if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2239               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2240                  tempah |= 0x20;
2241               }
2242            }
2243         }
2244
2245         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2246
2247         tempah = 0;
2248
2249         if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2250
2251         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2252            if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2253               tempah |= 0x40;
2254            }
2255         }
2256
2257         if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
2258            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
2259            ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
2260             (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2261            tempah |= 0x80;
2262         }
2263
2264         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2265
2266      } else {  /* LVDS */
2267
2268         if(HwInfo->jChipType >= SIS_315H) {
2269
2270            /* LVDS can only be slave in 8bpp modes */
2271            tempah = 0x80;
2272            if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2273               if(SiS_Pr->SiS_VBInfo & DriverMode) {
2274                  tempah |= 0x02;
2275               }
2276            }
2277
2278            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2279               tempah |= 0x02;
2280            }
2281
2282            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2283               tempah ^= 0x01;
2284            }
2285
2286            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2287               tempah = 1;
2288            }
2289
2290            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2291
2292         } else {
2293
2294            tempah = 0;
2295            if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2296               tempah |= 0x02;
2297            }
2298            tempah <<= 5;
2299
2300            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2301
2302            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2303
2304         }
2305
2306      }
2307
2308   }  /* LCDA */
2309
2310   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2311
2312      if(HwInfo->jChipType >= SIS_315H) {
2313
2314 #ifdef SIS315H
2315
2316         unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2317
2318         /* The following is nearly unpreditable and varies from machine
2319          * to machine. Especially the 301DH seems to be a real trouble
2320          * maker. Some BIOSes simply set the registers (like in the
2321          * NoLCD-if-statements here), some set them according to the
2322          * LCDA stuff. It is very likely that some machines are not
2323          * treated correctly in the following, very case-orientated
2324          * code. What do I do then...?
2325          */
2326
2327         /* 740 variants match for 30xB, 301B-DH, 30xLV */
2328
2329         if(!(IS_SIS740)) {
2330            tempah = 0x04;                                                  /* For all bridges */
2331            tempbl = 0xfb;
2332            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2333               tempah = 0x00;
2334               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2335                  tempbl = 0xff;
2336               }
2337            }
2338            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2339         }
2340
2341         /* The following two are responsible for eventually wrong colors
2342          * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2343          * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2344          * in a 650 box (Jake). What is the criteria?
2345          */
2346
2347         if((IS_SIS740) || (HwInfo->jChipType >= SIS_661)) {
2348            tempah = 0x30;
2349            tempbl = 0xc0;
2350            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2351               tempah = 0x00;
2352               tempbl = 0x00;
2353            }
2354            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2355            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2356         } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2357            /* Fixes "TV-blue-bug" on 315+301 */
2358            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);     /* For 301   */
2359            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2360         } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2361            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xLV */
2362            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2363         } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2364            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xB-DH rev b0 (or "DH on 651"?) */
2365            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2366         } else {
2367            tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB (and 301BDH rev b1) */
2368            tempbl = 0xcf; tempbl2 = 0x3f;
2369            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2370               tempah = tempah2 = 0x00;
2371               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2372                  tempbl = tempbl2 = 0xff;
2373               }
2374            }
2375            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2376            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2377         }
2378
2379         if(IS_SIS740) {
2380            tempah = 0x80;
2381            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2382               tempah = 0x00;
2383            }
2384            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2385         } else {
2386            tempah = 0x00;
2387            tempbl = 0x7f;
2388            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2389               tempbl = 0xff;
2390               if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
2391                  tempah = 0x80;
2392               }
2393            }
2394            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2395         }
2396
2397         /* 661: Sets p4 27 and 34 here, done in SetGroup4 here */
2398
2399 #endif /* SIS315H */
2400
2401      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2402
2403         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2404
2405         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2406            (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2407                (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2408            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2409         } else {
2410            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2411         }
2412
2413      }
2414
2415   } else {  /* LVDS */
2416
2417 #ifdef SIS315H
2418      if(HwInfo->jChipType >= SIS_315H) {
2419
2420         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2421
2422            tempah = 0x04;
2423            tempbl = 0xfb;
2424            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2425               tempah = 0x00;
2426               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2427                  tempbl = 0xff;
2428               }
2429            }
2430            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2431
2432            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2433               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2434            }
2435
2436            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2437
2438         } else if(HwInfo->jChipType == SIS_550) {
2439
2440            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2441            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2442
2443         }
2444
2445      }
2446 #endif
2447
2448   }
2449
2450 }
2451
2452 /*********************************************/
2453 /*            GET RESOLUTION DATA            */
2454 /*********************************************/
2455
2456 USHORT
2457 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2458 {
2459   USHORT resindex;
2460
2461   if(ModeNo <= 0x13)
2462      resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2463   else
2464      resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2465
2466   return(resindex);
2467 }
2468
2469 static void
2470 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2471                    PSIS_HW_INFO HwInfo)
2472 {
2473   USHORT xres,yres,modeflag=0,resindex;
2474
2475   if(SiS_Pr->UseCustomMode) {
2476      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
2477      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2478      return;
2479   }
2480
2481   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2482
2483   if(ModeNo <= 0x13) {
2484      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2485      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2486   } else {
2487      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2488      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2489      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2490   }
2491
2492   if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
2493
2494      if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2495         if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2496            if(yres == 350) yres = 400;
2497         }
2498         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2499            if(ModeNo == 0x12) yres = 400;
2500         }
2501      }
2502
2503      if(ModeNo > 0x13) {
2504         if(modeflag & HalfDCLK)       xres *= 2;
2505         if(modeflag & DoubleScanMode) yres *= 2;
2506      }
2507
2508   }
2509
2510   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2511         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2512            if(xres == 720) xres = 640;
2513         } else {
2514            if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
2515                 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2516                    if(xres == 720) xres = 640;
2517                 }
2518                 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2519                    yres = 400;
2520                    if(HwInfo->jChipType >= SIS_315H) {
2521                       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2522                    } else {
2523                       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2524                    }
2525                 }
2526            } else {
2527               if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2528                  if(xres == 720) xres = 640;
2529               }
2530               if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2531                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
2532                     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2533                        if(yres == 1024) yres = 1056;
2534                     }
2535                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
2536                     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2537                        /* BIOS bug - does this regardless of scaling */
2538                        if(yres == 400) yres = 405;
2539                     }
2540                     if(yres == 350) yres = 360;
2541                     if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2542                        if(yres == 360) yres = 375;
2543                     }
2544                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
2545                     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2546                        if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2547                           if(yres == 350) yres = 357;
2548                           if(yres == 400) yres = 420;
2549                           if(yres == 480) yres = 525;
2550                        }
2551                     }
2552                  }
2553               }
2554            }
2555         }
2556   } else {
2557         if(xres == 720) xres = 640;
2558         if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2559            yres = 400;
2560            if(HwInfo->jChipType >= SIS_315H) {
2561               if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2562            } else {
2563               if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2564            }
2565            if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
2566               yres = 480;
2567            }
2568         }
2569   }
2570   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2571   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2572 }
2573
2574 /*********************************************/
2575 /*           GET CRT2 TIMING DATA            */
2576 /*********************************************/
2577
2578 static BOOLEAN
2579 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2580                    USHORT RefreshRateTableIndex, USHORT *ResIndex,
2581                    USHORT *DisplayType)
2582  {
2583   USHORT tempbx,modeflag=0;
2584   USHORT Flag,CRT2CRTC;
2585
2586   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2587      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2588         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2589      }
2590   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2591      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2592   } else
2593      return FALSE;
2594
2595   if(ModeNo <= 0x13) {
2596      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2597      CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2598   } else {
2599      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2600      CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2601   }
2602
2603   Flag = 1;
2604   tempbx = 0;
2605   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2606      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2607         Flag = 0;
2608         tempbx = 18;
2609         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2610         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2611            tempbx += 2;
2612            if(SiS_Pr->SiS_ModeType > ModeVGA) {
2613               if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2614            }
2615            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2616               tempbx = 18;  /* PALM uses NTSC data */
2617               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2618            } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2619               tempbx = 20;  /* PALN uses PAL data  */
2620               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2621            }
2622         }
2623      }
2624   }
2625   if(Flag) {
2626      tempbx = SiS_Pr->SiS_LCDResInfo;
2627      tempbx -= SiS_Pr->SiS_PanelMinLVDS;
2628      if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
2629         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
2630         if(modeflag & HalfDCLK) tempbx += 3;
2631      } else {
2632         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2633            tempbx = 14;
2634            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
2635            if(modeflag & HalfDCLK) tempbx++;
2636         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
2637            tempbx = 23;
2638            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
2639            if(modeflag & HalfDCLK) tempbx++;
2640         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
2641            tempbx = 27;
2642            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
2643            if(modeflag & HalfDCLK) tempbx++;
2644         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
2645            tempbx = 36;
2646            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
2647            if(modeflag & HalfDCLK) tempbx++;
2648         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
2649            tempbx = 40;
2650            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
2651            if(modeflag & HalfDCLK) tempbx++;
2652         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
2653            tempbx = 54;
2654            if(modeflag & HalfDCLK) tempbx++;
2655         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
2656            tempbx = 52;
2657            if(modeflag & HalfDCLK) tempbx++;
2658         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
2659            tempbx = 50;
2660            if(modeflag & HalfDCLK) tempbx++;
2661         }
2662
2663      }
2664      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2665         tempbx = 12;
2666         if(modeflag & HalfDCLK) tempbx++;
2667      }
2668   }
2669
2670 #if 0
2671   if(SiS_Pr->SiS_IF_DEF_FSTN) {
2672      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2673         tempbx = 22;
2674      }
2675   }
2676 #endif
2677
2678   *ResIndex = CRT2CRTC & 0x3F;
2679   *DisplayType = tempbx;
2680   return TRUE;
2681 }
2682
2683 static void
2684 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2685                USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2686                PSIS_HW_INFO HwInfo)
2687 {
2688   USHORT tempbx=0,tempal=0;
2689   USHORT Flag,resinfo=0;
2690
2691   if(ModeNo <= 0x13) {
2692      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2693   } else {
2694      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2695      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2696   }
2697
2698   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2699
2700      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2701
2702         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
2703            tempbx = 15;
2704         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2705            tempbx = 20;
2706            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 21;
2707            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
2708         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
2709            tempbx = 23;
2710            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
2711            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
2712 #if 0
2713         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
2714            tempbx = 26;
2715            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 27;
2716            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
2717 #endif
2718         } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2719            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2720               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 13;
2721               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
2722               else {
2723                  tempbx = 29;
2724                  if(ModeNo >= 0x13) {
2725                     /* see below */
2726                     if(resinfo == SIS_RI_1280x960) tempal = 10;
2727                  }
2728               }
2729            } else {
2730               tempbx = 29;
2731               if(ModeNo >= 0x13) {
2732                  /* 1280x768 and 1280x960 have same CRT2CRTC,
2733                   * so we change it here if 1280x960 is chosen
2734                   */
2735                  if(resinfo == SIS_RI_1280x960) tempal = 10;
2736               }
2737            }
2738         } else {
2739            tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
2740            if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2741               tempbx += 10;
2742            }
2743         }
2744
2745 #ifdef SIS315H
2746         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2747            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
2748               tempbx = 50;
2749               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 51;
2750               else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
2751            }
2752         }
2753 #endif
2754
2755      } else {                                                   /* TV */
2756
2757         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2758            /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2759            tempbx = 2;
2760            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2761               tempbx = 13;
2762               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2763            }
2764         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2765            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
2766            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2767            else                                         tempbx = 5;
2768            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2769         } else {
2770            if(SiS_Pr->SiS_TVMode & TVSetPAL)            tempbx = 3;
2771            else                                         tempbx = 4;
2772            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2773         }
2774
2775      }
2776
2777      tempal &= 0x3F;
2778
2779      if(ModeNo > 0x13) {
2780         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2781            if(tempal == 6) tempal = 7;
2782            if((resinfo == SIS_RI_720x480) ||
2783               (resinfo == SIS_RI_720x576) ||
2784               (resinfo == SIS_RI_768x576)) {
2785               tempal = 6;
2786            }
2787            if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2788               if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
2789                  if(resinfo == SIS_RI_1024x768) {
2790                     tempal = 8;
2791                  }
2792               }
2793            }
2794         }
2795      }
2796
2797      *CRT2Index = tempbx;
2798      *ResIndex = tempal;
2799
2800   } else {   /* LVDS, 301B-DH (if running on LCD) */
2801
2802      Flag = 1;
2803      tempbx = 0;
2804      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2805         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2806            Flag = 0;
2807            tempbx = 10;
2808            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2809            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2810               tempbx += 2;
2811               if(SiS_Pr->SiS_ModeType > ModeVGA) {
2812                  if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2813               }
2814               if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2815                  tempbx = 90;
2816                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2817               } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2818                  tempbx = 92;
2819                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2820               }
2821            }
2822         }
2823      }
2824
2825      if(Flag) {
2826
2827         if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
2828            tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
2829            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
2830
2831            if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2832               tempbx = 82;
2833               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2834            }
2835         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
2836            tempbx = 18;
2837            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2838         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
2839            tempbx = 6;
2840         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
2841            tempbx = 30;
2842         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
2843            tempbx = 30;
2844         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
2845            tempbx = 15;
2846            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
2847         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
2848            tempbx = 16;
2849            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
2850         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2851            tempbx = 8;
2852            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2853         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
2854            tempbx = 21;
2855            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2856         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
2857            tempbx = 80;
2858            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2859         }
2860
2861         if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2862            tempbx = 7;
2863         }
2864
2865         if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2866            tempbx = 84;
2867            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2868         }
2869
2870      }
2871
2872      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2873         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
2874         if(HwInfo->jChipType < SIS_315H) {
2875            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2876         }
2877      }
2878
2879      *CRT2Index = tempbx;
2880      *ResIndex = tempal & 0x1F;
2881   }
2882 }
2883
2884 #ifdef SIS315H
2885 static void
2886 SiS_GetCRT2PtrA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2887                 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
2888                 USHORT *ResIndex)
2889 {
2890   USHORT tempbx,tempal;
2891
2892   tempbx = SiS_Pr->SiS_LCDResInfo;
2893
2894   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)      tempbx = 4;
2895   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
2896   else tempbx -= SiS_Pr->SiS_Panel1024x768;
2897
2898   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
2899
2900   if(ModeNo <= 0x13)
2901      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2902   else
2903      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2904
2905   /* No customs required yet (Clevo, Compaq, etc) */
2906
2907   *CRT2Index = tempbx;
2908   *ResIndex = tempal & 0x1F;
2909 }
2910 #endif
2911
2912 static void
2913 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2914                    USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
2915 {
2916   USHORT tempax=0,tempbx=0;
2917   USHORT temp1=0,modeflag=0,tempcx=0;
2918   USHORT index;
2919
2920   SiS_Pr->SiS_RVBHCMAX  = 1;
2921   SiS_Pr->SiS_RVBHCFACT = 1;
2922
2923   if(ModeNo <= 0x13) {
2924
2925      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2926      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
2927
2928      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
2929      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
2930      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
2931
2932   } else {
2933
2934      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2935      index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2936
2937      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
2938      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
2939      tempax &= 0x03FF;
2940      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
2941      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
2942      tempcx &= 0x0100;
2943      tempcx <<= 2;
2944      tempbx |= tempcx;
2945      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
2946
2947   }
2948
2949   if(temp1 & 0x01) tempbx |= 0x0100;
2950   if(temp1 & 0x20) tempbx |= 0x0200;
2951
2952   tempax += 5;
2953
2954   /* Charx8Dot is no more used (and assumed), so we set it */
2955   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2956      modeflag |= Charx8Dot;
2957   }
2958
2959   if(modeflag & Charx8Dot) tempax *= 8;
2960   else                     tempax *= 9;
2961
2962   if(modeflag & HalfDCLK)  tempax <<= 1;
2963
2964   tempbx++;
2965
2966   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
2967   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
2968 }
2969
2970 static void
2971 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2972                     USHORT RefreshRateTableIndex,
2973                     PSIS_HW_INFO HwInfo)
2974 {
2975    USHORT CRT2Index, ResIndex;
2976    const SiS_LVDSDataStruct *LVDSData = NULL;
2977
2978    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
2979
2980    if(SiS_Pr->SiS_VBType & VB_SISVB) {
2981       SiS_Pr->SiS_RVBHCMAX  = 1;
2982       SiS_Pr->SiS_RVBHCFACT = 1;
2983       SiS_Pr->SiS_NewFlickerMode = 0;
2984       SiS_Pr->SiS_RVBHRS = 50;
2985       SiS_Pr->SiS_RY1COE = 0;
2986       SiS_Pr->SiS_RY2COE = 0;
2987       SiS_Pr->SiS_RY3COE = 0;
2988       SiS_Pr->SiS_RY4COE = 0;
2989    }
2990
2991    if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2992
2993 #ifdef SIS315H
2994       SiS_GetCRT2PtrA(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2995                       &CRT2Index,&ResIndex);
2996
2997       switch (CRT2Index) {
2998         case  0:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1;    break;
2999         case  1:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_1;   break;
3000         case  3:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1;   break;
3001         case  4:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1;   break;
3002         case  5:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_2;    break;
3003         case  6:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_2;   break;
3004         case  8:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2;   break;
3005         case  9:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2;   break;
3006         default:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1;    break;
3007       }
3008 #endif
3009
3010    } else {
3011
3012       /* 301BDH needs LVDS Data */
3013       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3014          SiS_Pr->SiS_IF_DEF_LVDS = 1;
3015       }
3016
3017       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3018                      &CRT2Index, &ResIndex, HwInfo);
3019
3020       /* 301BDH needs LVDS Data */
3021       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3022          SiS_Pr->SiS_IF_DEF_LVDS = 0;
3023       }
3024
3025       switch (CRT2Index) {
3026         case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3027         case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3028         case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
3029         case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
3030         case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
3031         case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
3032         case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3033         case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
3034         case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
3035         case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
3036         case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3037         case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3038         case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3039         case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3040         case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
3041         case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3042         case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
3043         case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
3044         case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
3045         case 19:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
3046         case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
3047         case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
3048         case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
3049         case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
3050         case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3051         case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3052         case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3053         case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
3054         case 84:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3055         case 85:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3056         case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3057         case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3058         case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3059         case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3060         case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;  /* Super Overscan */
3061         default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3062       }
3063    }
3064
3065    SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3066    SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3067    SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3068    SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3069
3070    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3071
3072       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3073          SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3074          SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3075       }
3076
3077    } else {
3078
3079       if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
3080          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3081             if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
3082                if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3083                   SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3084                   SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3085
3086                   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3087                      if(ResIndex < 0x08) {
3088                         SiS_Pr->SiS_HDE = 1280;
3089                         SiS_Pr->SiS_VDE = 1024;
3090                      }
3091                   }
3092                }
3093             }
3094          }
3095       }
3096    }
3097 }
3098
3099 static void
3100 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3101                    USHORT RefreshRateTableIndex,
3102                    PSIS_HW_INFO HwInfo)
3103 {
3104   USHORT tempax,tempbx,modeflag;
3105   USHORT resinfo;
3106   USHORT CRT2Index,ResIndex;
3107   const SiS_LCDDataStruct *LCDPtr = NULL;
3108   const SiS_TVDataStruct  *TVPtr  = NULL;
3109
3110   if(ModeNo <= 0x13) {
3111      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3112      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3113   } else {
3114      if(SiS_Pr->UseCustomMode) {
3115         modeflag = SiS_Pr->CModeFlag;
3116         resinfo = 0;
3117      } else {
3118         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3119         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3120      }
3121   }
3122   
3123   SiS_Pr->SiS_NewFlickerMode = 0;
3124   SiS_Pr->SiS_RVBHRS = 50;
3125   SiS_Pr->SiS_RY1COE = 0;
3126   SiS_Pr->SiS_RY2COE = 0;
3127   SiS_Pr->SiS_RY3COE = 0;
3128   SiS_Pr->SiS_RY4COE = 0;
3129
3130   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3131
3132   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3133
3134      if(SiS_Pr->UseCustomMode) {
3135
3136         SiS_Pr->SiS_RVBHCMAX  = 1;
3137         SiS_Pr->SiS_RVBHCFACT = 1;
3138         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3139         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3140         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3141         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3142         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3143         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3144
3145      } else {
3146
3147         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3148      }
3149
3150   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3151
3152      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3153                     &CRT2Index,&ResIndex,HwInfo);
3154
3155      switch(CRT2Index) {
3156        case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3157        case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3158        case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3159        case  5:  TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3160        case  6:  TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3161        case  7:  TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3162        case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
3163        case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3164        case 10:  TVPtr = SiS_Pr->SiS_St525iData;    break;
3165        case 11:  TVPtr = SiS_Pr->SiS_St525pData;    break;
3166        case 12:  TVPtr = SiS_Pr->SiS_St750pData;    break;
3167        case 13:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3168        case 14:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3169        default:  TVPtr = SiS_Pr->SiS_StPALData;     break;
3170      }
3171
3172      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3173      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3174      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3175      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3176      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3177      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3178      SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3179      SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3180      if(modeflag & HalfDCLK) {
3181         SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3182      }
3183
3184      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3185
3186         if((resinfo == SIS_RI_1024x768)  ||
3187            (resinfo == SIS_RI_1280x1024) ||
3188            (resinfo == SIS_RI_1280x720)) {
3189            SiS_Pr->SiS_NewFlickerMode = 0x40;
3190         }
3191
3192         if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3193
3194         SiS_Pr->SiS_HT = ExtHiTVHT;
3195         SiS_Pr->SiS_VT = ExtHiTVVT;
3196         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3197            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3198               SiS_Pr->SiS_HT = StHiTVHT;
3199               SiS_Pr->SiS_VT = StHiTVVT;
3200 #if 0
3201               if(!(modeflag & Charx8Dot)) {
3202                  SiS_Pr->SiS_HT = StHiTextTVHT;
3203                  SiS_Pr->SiS_VT = StHiTextTVVT;
3204               }
3205 #endif
3206            }
3207         }
3208
3209      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3210
3211         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3212            SiS_Pr->SiS_HT = 1650;
3213            SiS_Pr->SiS_VT = 750;
3214         } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3215            SiS_Pr->SiS_HT = NTSCHT;
3216            SiS_Pr->SiS_VT = NTSCVT;
3217         } else {
3218            SiS_Pr->SiS_HT = NTSCHT;
3219            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3220            SiS_Pr->SiS_VT = NTSCVT;
3221         }
3222
3223      } else {
3224
3225         SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3226         SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3227         SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3228         SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3229
3230         if(modeflag & HalfDCLK) {
3231            SiS_Pr->SiS_RY1COE = 0x00;
3232            SiS_Pr->SiS_RY2COE = 0xf4;
3233            SiS_Pr->SiS_RY3COE = 0x10;
3234            SiS_Pr->SiS_RY4COE = 0x38;
3235         }
3236
3237         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3238            SiS_Pr->SiS_HT = NTSCHT;
3239            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3240            SiS_Pr->SiS_VT = NTSCVT;
3241         } else {
3242            SiS_Pr->SiS_HT = PALHT;
3243            SiS_Pr->SiS_VT = PALVT;
3244         }
3245
3246      }
3247
3248   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3249
3250      if(SiS_Pr->UseCustomMode) {
3251
3252         SiS_Pr->SiS_RVBHCMAX  = 1;
3253         SiS_Pr->SiS_RVBHCFACT = 1;
3254         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3255         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3256         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3257         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3258         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3259         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3260
3261      } else {
3262
3263         SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3264                       &CRT2Index,&ResIndex,HwInfo);
3265
3266         switch(CRT2Index) {
3267          case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
3268          case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
3269          case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
3270          case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
3271          case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
3272          case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
3273          case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
3274          case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
3275          case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
3276          case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
3277          case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
3278          case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
3279          case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
3280          case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
3281          case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
3282          case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
3283          case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
3284          case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
3285          case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;               break; /* Generic no-scale data */
3286 #ifdef SIS315H
3287          case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data;  break;
3288          case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;                    break;
3289          case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;                     break;
3290 #endif
3291          default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break;
3292         }
3293
3294         SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3295         SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3296         SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3297         SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3298         SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3299         SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3300
3301 #ifdef TWDEBUG
3302         xf86DrvMsg(0, X_INFO,
3303             "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3304 #endif
3305
3306         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3307            tempax = 1024;
3308            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3309               if(HwInfo->jChipType < SIS_315H) {
3310                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3311                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3312                  else                               tempbx = 768;
3313               } else {
3314                  tempbx = 768;
3315               }
3316            } else {
3317               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3318               else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3319               else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3320               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3321               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3322               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3323               else                               tempbx = 768;
3324            }
3325         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
3326            tempax = 1280;
3327            if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3328            else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3329            else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3330            else                               tempbx = 1024;
3331         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
3332            tempax = 1280;
3333            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3334            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3335            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3336            else                                tempbx = 960;
3337         } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) &&
3338                   (HwInfo->jChipType >= SIS_661)) {
3339            tempax = 1400;
3340            tempbx = 1050;
3341            if(SiS_Pr->SiS_VGAVDE == 1024) {
3342               tempax = 1280;
3343               tempbx = 1024;
3344            }
3345         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
3346            tempax = 1600;
3347            tempbx = 1200;
3348            if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))) {
3349               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3350               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3351            }
3352         } else {
3353            tempax = SiS_Pr->PanelXRes;
3354            tempbx = SiS_Pr->PanelYRes;
3355         }
3356         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3357            tempax = SiS_Pr->SiS_VGAHDE;
3358            tempbx = SiS_Pr->SiS_VGAVDE;
3359         }
3360         SiS_Pr->SiS_HDE = tempax;
3361         SiS_Pr->SiS_VDE = tempbx;
3362      }
3363   }
3364 }
3365
3366 static void
3367 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3368                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3369 {
3370
3371   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3372
3373      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3374
3375         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3376
3377            SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3378
3379         } else {
3380
3381            if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3382
3383               /* Need LVDS Data for LCD on 301B-DH */
3384               SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3385
3386            } else {
3387
3388               SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3389
3390            }
3391
3392         }
3393
3394      } else {
3395
3396         SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3397
3398      }
3399
3400   } else {
3401
3402      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3403
3404   }
3405 }
3406
3407 /*********************************************/
3408 /*            GET LVDS DES DATA              */
3409 /*********************************************/
3410
3411 static void
3412 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3413                   USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3414                   USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3415 {
3416   USHORT tempbx,tempal,modeflag;
3417
3418   if(ModeNo <= 0x13) {
3419      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3420      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3421   } else {
3422      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3423      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3424   }
3425
3426   tempbx = 0;
3427   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3428      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3429         tempbx = 50;
3430         if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) tempbx += 2;
3431         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3432         /* Nothing special needed for SOverscan    */
3433         /*     PALM uses NTSC data, PALN uses PAL data */
3434      }
3435   }
3436
3437   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3438      tempbx = SiS_Pr->SiS_LCDTypeInfo;
3439      if(HwInfo->jChipType >= SIS_661) {
3440         /* As long as we don's use the BIOS tables, we
3441          * need to convert the TypeInfo as for 315 series
3442          */
3443         tempbx = SiS_Pr->SiS_LCDResInfo - 1;
3444      }
3445      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
3446      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3447         tempbx = 32;
3448         if(modeflag & HalfDCLK) tempbx++;
3449      }
3450   }
3451
3452   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3453      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
3454         tempal = 0x07;
3455         if(HwInfo->jChipType < SIS_315H) {
3456            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
3457         }
3458      }
3459   }
3460
3461   *PanelIndex = tempbx;
3462   *ResIndex = tempal & 0x1F;
3463 }
3464
3465 #ifdef SIS315H
3466 static void
3467 SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3468                    USHORT RefreshRateTableIndex, USHORT *PanelIndex, USHORT *ResIndex,
3469                    PSIS_HW_INFO HwInfo)
3470 {
3471   USHORT tempbx=0,tempal;
3472
3473   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      tempbx = 2;
3474   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
3475   else tempbx = SiS_Pr->SiS_LCDResInfo - 2;
3476
3477   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
3478
3479   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
3480      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3481         if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
3482            tempbx = 80;
3483            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3484         }
3485      }
3486   }
3487   if((SiS_Pr->SiS_CustomT == CUT_UNIWILL1024) ||
3488      (SiS_Pr->SiS_CustomT == CUT_UNIWILL10242)) {
3489      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3490         tempbx = 82;
3491         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3492      }
3493   }
3494   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3495      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
3496         tempbx = 84;
3497         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3498      }
3499   }
3500   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
3501      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3502         tempbx = 86;
3503         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3504      }
3505   }
3506
3507   if(ModeNo <= 0x13)
3508      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3509   else
3510      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3511
3512   *PanelIndex = tempbx;
3513   *ResIndex = tempal & 0x1F;
3514 }
3515 #endif
3516
3517 static void
3518 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3519                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3520 {
3521   USHORT modeflag;
3522   USHORT PanelIndex,ResIndex;
3523   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
3524
3525   if((SiS_Pr->UseCustomMode) ||
3526      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
3527      (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
3528      SiS_Pr->SiS_LCDHDES = 0;
3529      SiS_Pr->SiS_LCDVDES = 0;
3530      return;
3531   }
3532
3533   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3534
3535 #ifdef SIS315H
3536      SiS_GetLVDSDesPtrA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3537                         &PanelIndex, &ResIndex, HwInfo);
3538
3539      switch (PanelIndex)
3540      {
3541         case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
3542         case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
3543         case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
3544         case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
3545         case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
3546         case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
3547         case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
3548         case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
3549         case 80: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_1;   break;  /*  custom  */
3550         case 81: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_2;   break;
3551         case 82: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_1; break;
3552         case 83: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_2; break;
3553         case 84: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_1; break;
3554         case 85: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_2; break;
3555         case 86: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_1;    break;  /*  custom  */
3556         case 87: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_2;    break;
3557         default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
3558      }
3559 #endif
3560
3561   } else {
3562
3563      SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3564                        &PanelIndex, &ResIndex, HwInfo);
3565
3566      switch (PanelIndex)
3567      {
3568         case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break;   /* ---  */
3569         case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
3570         case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
3571         case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
3572         case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
3573         case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
3574         case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
3575         case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
3576         case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
3577         case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
3578         case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
3579         case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
3580         case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;
3581         case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
3582         case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;
3583         case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
3584         case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;    /* --- */
3585         case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
3586         case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
3587         case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
3588         case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
3589         case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
3590         case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
3591         case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
3592         case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
3593         case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
3594         case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
3595         case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
3596         case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;
3597         case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
3598         case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
3599         case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
3600         case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;   break;    /* pass 1:1 */
3601         case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;   break;
3602         case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break; /* TV */
3603         case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
3604         case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
3605         case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
3606         default:
3607                  if(HwInfo->jChipType < SIS_315H)
3608                     PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
3609                  else
3610                     PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
3611                  break;
3612      }
3613   }
3614   SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3615   SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3616
3617   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
3618      if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3619         if(ModeNo <= 0x13) {
3620            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3621            if(!(modeflag & HalfDCLK)) {
3622               SiS_Pr->SiS_LCDHDES = 632;
3623            }
3624         }
3625      } else {
3626         if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3627            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
3628               if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768) {
3629                  if(ModeNo <= 0x13) {
3630                     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3631                     if(HwInfo->jChipType < SIS_315H) {
3632                        if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3633                     } else {
3634                        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
3635                           SiS_Pr->SiS_LCDHDES = 480;
3636                        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
3637                           SiS_Pr->SiS_LCDHDES = 804;
3638                        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
3639                           SiS_Pr->SiS_LCDHDES = 704;
3640                        if(!(modeflag & HalfDCLK)) {
3641                           SiS_Pr->SiS_LCDHDES = 320;
3642                           if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
3643                              SiS_Pr->SiS_LCDHDES = 632;
3644                           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
3645                              SiS_Pr->SiS_LCDHDES = 542;
3646                        }
3647                     }
3648                  }
3649               }
3650            }
3651         }
3652      }
3653   }
3654 }
3655
3656 /*********************************************/
3657 /*          SET CRT2 AUTO-THRESHOLD          */
3658 /*********************************************/
3659
3660 #ifdef SIS315H
3661 static void
3662 SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr)
3663 {
3664   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
3665 }
3666 #endif
3667
3668 /*********************************************/
3669 /*           DISABLE VIDEO BRIDGE            */
3670 /*********************************************/
3671
3672 /* NEVER use any variables (VBInfo), this will be called
3673  * from outside the context of modeswitch!
3674  * MUST call getVBType before calling this
3675  */
3676 void
3677 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3678 {
3679 #ifdef SIS315H
3680   USHORT tempah,pushax=0,modenum;
3681 #endif
3682   USHORT temp=0;
3683
3684   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3685
3686       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
3687
3688         if(HwInfo->jChipType < SIS_315H) {
3689
3690 #ifdef SIS300      /* 300 series */
3691
3692            if(HwInfo->jChipType == SIS_300) {  /* For 300+301LV (A907) */
3693
3694               if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3695                  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3696                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3697                     SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3698                  }
3699               }
3700               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3701               SiS_ShortDelay(SiS_Pr,1);
3702               SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3703               SiS_DisplayOff(SiS_Pr);
3704               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3705               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3706               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3707                  if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3708                      (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3709                     SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3710                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3711                  }
3712               }
3713
3714            } else {
3715
3716               if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3717                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3718                  SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3719               }
3720               if(SiS_Is301B(SiS_Pr)) {
3721                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3722                  SiS_ShortDelay(SiS_Pr,1);
3723               }
3724               SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3725               SiS_DisplayOff(SiS_Pr);
3726               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3727               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3728               SiS_UnLockCRT2(SiS_Pr,HwInfo);
3729               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3730               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3731               if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3732                   (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3733                  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3734                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3735               }
3736            }
3737
3738 #endif  /* SIS300 */
3739
3740         } else {
3741
3742 #ifdef SIS315H     /* 315 series */
3743
3744            if(IS_SIS550650740660) {             /* 550, 650, 740, 660 */
3745
3746               modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3747
3748               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                       /* LV */
3749 #ifdef SET_EMI
3750                  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3751                     if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3752                        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3753                     }
3754                  }
3755 #endif
3756                  if( (modenum <= 0x13) ||
3757                      (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3758                      (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
3759                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3760                     if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3761                        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3762                        SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3763                     }
3764                  }
3765
3766                  if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
3767                     (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
3768                     SiS_DDC2Delay(SiS_Pr,0xff00);
3769                     SiS_DDC2Delay(SiS_Pr,0xe000);
3770
3771                     SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3772
3773                     pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3774
3775                     if(IS_SIS740) {
3776                        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3777                     }
3778
3779                     SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3780
3781                     if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3782                        tempah = 0xef;
3783                        if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
3784                           tempah = 0xf7;
3785                        }
3786                        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3787                     }
3788                  }
3789
3790               } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {                        /* B-DH */
3791
3792                  if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3793                     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
3794                  }
3795
3796               }
3797
3798               if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3799                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3800                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
3801               }
3802
3803               if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
3804                  (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3805                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3806                  tempah = 0x3f;
3807                  if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3808                     tempah = 0x7f;
3809                     if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3810                        tempah = 0xbf;
3811                     }
3812                  }
3813                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3814               }
3815
3816               if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3817                  ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3818
3819                  if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
3820                     (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3821                     (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3822                     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3823                     SiS_DisplayOff(SiS_Pr);
3824                     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3825                  } else {
3826                     SiS_DisplayOff(SiS_Pr);
3827                     SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3828                     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3829                     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3830                     if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
3831                        SiS_DisplayOff(SiS_Pr);
3832                        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3833                        SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3834                        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3835                        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3836                        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3837                        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3838                        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3839                     }
3840                  }
3841
3842               } else {
3843
3844                  if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
3845                     (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3846                     (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3847                     if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3848                        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3849                        SiS_DisplayOff(SiS_Pr);
3850                     }
3851                     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3852                  } else {
3853                     SiS_DisplayOff(SiS_Pr);
3854                     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3855                     SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3856                  }
3857
3858                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3859                  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3860                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3861                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3862                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3863
3864               }
3865
3866               if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
3867                  (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
3868                  (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
3869
3870                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);
3871
3872                  tempah = 0x3f;
3873                  if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3874                     tempah = 0x7f;
3875                     if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3876                        tempah = 0xbf;
3877                     }
3878                  }
3879                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3880
3881                  if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3882                     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3883                  }
3884
3885                  if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3886                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3887                     if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3888                        if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3889                           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3890                        }
3891                     }
3892                  }
3893
3894                  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3895
3896                  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3897                     if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
3898                         (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
3899                        SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3900                     }
3901                  }
3902
3903               } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
3904
3905                  /* NIL */
3906
3907               } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
3908                         (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3909                         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3910
3911                  if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3912                     tempah = 0xef;
3913                     if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3914                        if(modenum > 0x13) {
3915                           tempah = 0xf7;
3916                        }
3917                     }
3918                     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3919                  }
3920                  if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3921                     (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
3922                     if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3923                        (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3924                        if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3925                           (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3926                           SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3927                           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3928                           SiS_PanelDelay(SiS_Pr, HwInfo, 4);
3929                        }
3930                     }
3931                  }
3932
3933               }
3934
3935           } else {                      /* 315, 330 - all bridge types */
3936
3937              if(SiS_Is301B(SiS_Pr)) {
3938                 tempah = 0x3f;
3939                 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3940                    tempah = 0x7f;
3941                    if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3942                       tempah = 0xbf;
3943                    }
3944                 }
3945                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3946                 if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
3947                    SiS_DisplayOff(SiS_Pr);
3948                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3949                 }
3950              }
3951              if( (!(SiS_Is301B(SiS_Pr))) ||
3952                  (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
3953
3954                 if( (!(SiS_Is301B(SiS_Pr))) ||
3955                     (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3956
3957                    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3958                    SiS_DisplayOff(SiS_Pr);
3959
3960                 }
3961
3962                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3963
3964                 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3965
3966                 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3967                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3968                 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3969                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3970
3971              }
3972
3973           }    /* 315/330 */
3974
3975 #endif /* SIS315H */
3976
3977         }
3978
3979       } else {     /* ============ For 301 ================ */
3980
3981         if(HwInfo->jChipType < SIS_315H) {
3982            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3983               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3984               SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3985            }
3986         }
3987
3988         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
3989         SiS_DisplayOff(SiS_Pr);
3990
3991         if(HwInfo->jChipType >= SIS_315H) {
3992            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3993         }
3994
3995         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
3996
3997         if(HwInfo->jChipType >= SIS_315H) {
3998             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3999             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4000             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4001             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4002         } else {
4003             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4004             if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4005                 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4006                 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4007                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4008             }
4009         }
4010
4011       }
4012
4013   } else {     /* ============ For LVDS =============*/
4014
4015     if(HwInfo->jChipType < SIS_315H) {
4016
4017 #ifdef SIS300   /* 300 series */
4018
4019         if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4020            SiS_SetCH700x(SiS_Pr,0x090E);
4021         }
4022
4023         if(HwInfo->jChipType == SIS_730) {
4024            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4025               SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4026            }
4027            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4028               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4029               SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4030            }
4031         } else {
4032            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4033               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4034                  if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4035                     SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4036                     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4037                        SiS_DisplayOff(SiS_Pr);
4038                     }
4039                     SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4040                     SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4041                  }
4042               }
4043            }
4044         }
4045
4046         SiS_DisplayOff(SiS_Pr);
4047
4048         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4049
4050         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4051         SiS_UnLockCRT2(SiS_Pr,HwInfo);
4052         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4053         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4054
4055         if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4056             (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4057            SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4058            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4059         }
4060
4061 #endif  /* SIS300 */
4062
4063     } else {
4064
4065 #ifdef SIS315H  /* 315 series */
4066
4067         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4068
4069            if(HwInfo->jChipType == SIS_740) {
4070               temp = SiS_GetCH701x(SiS_Pr,0x61);
4071               if(temp < 1) {
4072                  SiS_SetCH701x(SiS_Pr,0xac76);
4073                  SiS_SetCH701x(SiS_Pr,0x0066);
4074               }
4075
4076               if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4077                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4078                  SiS_SetCH701x(SiS_Pr,0x3e49);
4079               }
4080            }
4081
4082            if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4083                (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
4084               SiS_Chrontel701xBLOff(SiS_Pr);
4085               SiS_Chrontel701xOff(SiS_Pr,HwInfo);
4086            }
4087
4088            if(HwInfo->jChipType != SIS_740) {
4089               if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4090                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4091                  SiS_SetCH701x(SiS_Pr,0x0149);
4092               }
4093            }
4094
4095         }
4096
4097         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4098            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4099            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4100         }
4101
4102         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4103             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4104             (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4105            SiS_DisplayOff(SiS_Pr);
4106         }
4107
4108         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4109             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4110             (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4111            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4112         }
4113
4114         if(HwInfo->jChipType == SIS_740) {
4115            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4116         }
4117
4118         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4119
4120         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4121             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4122             (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4123            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4124         }
4125
4126         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4127            if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4128               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4129               if(HwInfo->jChipType == SIS_550) {
4130                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4131                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4132               }
4133            }
4134         } else {
4135            if(HwInfo->jChipType == SIS_740) {
4136               if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4137                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4138               }
4139            } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4140               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4141            }
4142         }
4143
4144         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4145            if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4146               /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4147            } else {
4148               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4149            }
4150         }
4151
4152         SiS_UnLockCRT2(SiS_Pr,HwInfo);
4153
4154         if(HwInfo->jChipType == SIS_550) {
4155            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4156            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4157         } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4158                    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4159                    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4160            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4161         }
4162
4163         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4164            if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4165               if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4166                  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4167                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4168               }
4169            }
4170         }
4171
4172 #endif  /* SIS315H */
4173
4174     }  /* 315 series */
4175
4176   }  /* LVDS */
4177
4178 }
4179
4180 /*********************************************/
4181 /*            ENABLE VIDEO BRIDGE            */
4182 /*********************************************/
4183
4184 /* NEVER use any variables (VBInfo), this will be called
4185  * from outside the context of a mode switch!
4186  * MUST call getVBType before calling this
4187  */
4188 void
4189 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4190 {
4191   USHORT temp=0,tempah;
4192 #ifdef SIS315H
4193   USHORT temp1,pushax=0;
4194   BOOLEAN delaylong = FALSE;
4195 #endif
4196
4197
4198   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4199
4200     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
4201
4202       if(HwInfo->jChipType < SIS_315H) {
4203
4204 #ifdef SIS300     /* 300 series */
4205
4206          if(HwInfo->jChipType == SIS_300) {
4207
4208             if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4209                if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4210                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4211                   if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4212                      SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4213                   }
4214                }
4215             }
4216             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4217             if(SiS_BridgeInSlave(SiS_Pr)) {
4218                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4219                if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4220             }
4221             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4222             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4223             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4224             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4225             SiS_DisplayOn(SiS_Pr);
4226             if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4227                if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4228                   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4229                      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4230                         SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4231                      }
4232                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4233                   }
4234                }
4235             }
4236
4237          } else {
4238
4239             if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4240                (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4241                /* This is only for LCD output on 301B-DH via LVDS */
4242                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4243                if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4244                   SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4245                }
4246                SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
4247                SiS_DisplayOn(SiS_Pr);
4248                SiS_UnLockCRT2(SiS_Pr,HwInfo);
4249                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4250                if(SiS_BridgeInSlave(SiS_Pr)) {
4251                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4252                } else {
4253                   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4254                }
4255                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4256                    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4257                        if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4258                            SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4259                        }
4260                        SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4261                        SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4262                    }
4263                }
4264             } else {
4265                temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4266                if(SiS_BridgeInSlave(SiS_Pr)) {
4267                   tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4268                   if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4269                }
4270                SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4271                SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4272                SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4273                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4274                SiS_DisplayOn(SiS_Pr);
4275             }
4276
4277          }
4278 #endif /* SIS300 */
4279
4280       } else {
4281
4282 #ifdef SIS315H    /* 315 series */
4283
4284          if(IS_SIS550650740660) {               /* 550, 650, 740, 660 */
4285
4286             UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4287
4288             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4289
4290                if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
4291                   (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
4292                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4293 #ifdef SET_EMI
4294                   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4295                      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4296                   }
4297 #endif
4298                }
4299
4300                if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4301                   tempah = 0x10;
4302                   if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4303                      if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4304                      else                              tempah = 0x08;
4305                   }
4306                   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4307                }
4308
4309                if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
4310                   (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
4311                   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4312                   SiS_DisplayOff(SiS_Pr);
4313                   pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4314                   if(IS_SIS740) {
4315                      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4316                   }
4317                }
4318
4319                if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4320                    (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4321                   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4322                      if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
4323                         (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
4324                         SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4325                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4326                         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4327                            SiS_GenericDelay(SiS_Pr, 0x4500);
4328                         }
4329                         SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4330                      } else {
4331                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4332                         SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4333                      }
4334                   }
4335                }
4336
4337                if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
4338                   (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
4339                   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4340                      SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4341                      delaylong = TRUE;
4342                   }
4343                }
4344
4345             } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4346
4347                if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4348                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
4349                }
4350
4351             } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
4352
4353                if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4354                   tempah = 0x10;
4355                   if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4356                      if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4357                      else                              tempah = 0x08;
4358                   }
4359                   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4360                }
4361
4362             }
4363
4364             if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4365                temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4366                if(SiS_BridgeInSlave(SiS_Pr)) {
4367                   tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4368                   if(!(tempah & SetCRT2ToRAMDAC)) {
4369                      if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4370                   }
4371                }
4372                SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4373
4374                SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4375
4376                if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
4377                   (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4378                   (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
4379                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4380                   temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
4381                   if(!(temp & 0x80)) {
4382                      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4383                   }
4384                } else {
4385                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4386                }
4387             } else {
4388                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4389             }
4390
4391             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4392
4393             if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
4394                (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4395                (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
4396                temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
4397                if(!(temp & 0x80)) {
4398                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4399                }
4400             }
4401
4402             tempah = 0xc0;
4403             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4404                tempah = 0x80;
4405                if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) {
4406                   tempah = 0x40;
4407                }
4408             }
4409             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4410
4411             if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
4412                (((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4413                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400))     &&
4414                 (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))))) {
4415                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4416             }
4417
4418             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4419
4420                if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
4421                   (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
4422                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4423                }
4424 #ifdef COMPAQ_HACK
4425                if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4426                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4427                }
4428 #endif
4429
4430                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4431
4432                if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4433 #ifdef SET_EMI
4434                   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4435                      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4436                   }
4437 #endif
4438                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4439 #ifdef SET_EMI
4440                   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4441
4442                      cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4443
4444                      /*                                              (P4_30|0x40)  */
4445                      /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4446                      /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4447                      /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4448                      /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4449                      /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4450                      /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4451                      /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4452                      /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4453                      /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4454
4455                      if(SiS_Pr->HaveEMI) {
4456                         r30 = SiS_Pr->EMI_30;
4457                         r31 = SiS_Pr->EMI_31;
4458                         r32 = SiS_Pr->EMI_32;
4459                         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                         if((cr36 & 0x0f) == 0x02) {                     /* 1024x768 */
4473                            r30 |= 0x40;
4474                            if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
4475                               r30 &= ~0x40;
4476                            }
4477                         } else if((cr36 & 0x0f) == 0x03) {              /* 1280x1024 */
4478                            r30 |= 0x40;
4479                            if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
4480                               r30 &= ~0x40;
4481                            }
4482                         } else if((cr36 & 0x0f) == 0x09) {              /* 1400x1050 */
4483                            r30 |= 0x40;
4484                         } else if((cr36 & 0x0f) == 0x0b) {              /* 1600x1200 - unknown */
4485                            r30 |= 0x40;
4486                         }
4487                      }
4488
4489                      if(!SiS_Pr->HaveEMI) {
4490                         if((cr36 & 0x0f) == 0x02) {
4491                            if((cr36 & 0xf0) == 0x30) {
4492                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4493                            } else {
4494                               r31 = 0x05; r32 = 0x60; r33 = 0x33;
4495                            }
4496                         } else if((cr36 & 0x0f) == 0x03) {
4497                            if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4498                               r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4499                            } else {
4500                               r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4501                            }
4502                         } else if((cr36 & 0x0f) == 0x09) {
4503                            if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4504                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4505                            } else {
4506                               r31 = 0x05; r32 = 0x60; r33 = 0x00;
4507                            }
4508                         } else {
4509                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4510                         }
4511                      }
4512
4513                      /* BIOS values don't work so well sometimes */
4514                      if(!SiS_Pr->OverruleEMI) {
4515 #ifdef COMPAL_HACK
4516                         if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4517                            if((cr36 & 0x0f) == 0x09) {
4518                               r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4519                            }
4520                         }
4521 #endif
4522 #ifdef COMPAQ_HACK
4523                         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4524                            if((cr36 & 0x0f) == 0x03) {
4525                               r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;     /* rev 1 */
4526                            }
4527                         }
4528 #endif
4529 #ifdef ASUS_HACK
4530                         if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4531                            if((cr36 & 0x0f) == 0x02) {
4532                               /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4533                               /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4534                               /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4535                               /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4536                            }
4537                         }
4538 #endif
4539                      }
4540                      if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4541                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4542                      }
4543                      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4544                      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4545                      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4546                      if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4547                         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4548                      } else {
4549                         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
4550                      }
4551                      if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4552                          (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4553                         if(r30 & 0x40) {
4554                            SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4555                            if(delaylong) {
4556                               SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4557                               delaylong = FALSE;
4558                            }
4559                            SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4560                            if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4561                               SiS_GenericDelay(SiS_Pr, 0x500);
4562                            }
4563                            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4564                         }
4565                      }
4566                   }
4567 #endif
4568                }
4569
4570                if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4571
4572                   if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4573                       (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4574                      SiS_DisplayOn(SiS_Pr);
4575                      SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4576                      SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4577                      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4578                      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4579                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4580                      }
4581                   }
4582
4583                } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
4584
4585                   if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4586                      if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
4587                          (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4588                         SiS_DisplayOn(SiS_Pr);
4589                         SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4590                         SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4591                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4592                      }
4593                   }
4594
4595                } else {
4596
4597                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4598                   if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4599                      if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4600                          ((SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ) {
4601                         SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4602                         if(delaylong) {
4603                            SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4604                         }
4605                         SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4606                         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4607                            SiS_GenericDelay(SiS_Pr, 0x500);
4608                         }
4609                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4610                      }
4611                   }
4612
4613                   SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4614                   SiS_DisplayOn(SiS_Pr);
4615                   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4616
4617                   if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4618                      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4619                   }
4620
4621                }
4622
4623             }
4624
4625          } else {                       /* 315, 330 */
4626
4627             if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4628                temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4629                if(SiS_BridgeInSlave(SiS_Pr)) {
4630                   tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4631                   if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4632                }
4633                SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4634
4635                SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4636
4637                temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4638                if(!(temp & 0x80))
4639                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4640             }
4641
4642             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4643
4644             if(SiS_Is301B(SiS_Pr)) {
4645
4646                temp=SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4647                if(!(temp & 0x80))
4648                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4649
4650                tempah = 0xc0;
4651                if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4652                   tempah = 0x80;
4653                   if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4654                      tempah = 0x40;
4655                   }
4656                }
4657                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4658
4659                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4660
4661             } else {
4662
4663                SiS_VBLongWait(SiS_Pr);
4664                SiS_DisplayOn(SiS_Pr);
4665                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
4666                SiS_VBLongWait(SiS_Pr);
4667
4668             }
4669
4670          }   /* 315, 330 */
4671
4672 #endif /* SIS315H */
4673
4674       }
4675
4676     } else {    /* ============  For 301 ================ */
4677
4678        if(HwInfo->jChipType < SIS_315H) {
4679           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4680              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4681              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4682           }
4683        }
4684
4685        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4686        if(SiS_BridgeInSlave(SiS_Pr)) {
4687           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4688           if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4689        }
4690        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4691
4692        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4693
4694        if(HwInfo->jChipType >= SIS_315H) {
4695           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4696           if(!(temp & 0x80)) {
4697              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4698           }
4699        }
4700
4701        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4702
4703        SiS_VBLongWait(SiS_Pr);
4704        SiS_DisplayOn(SiS_Pr);
4705        if(HwInfo->jChipType >= SIS_315H) {
4706           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4707        }
4708        SiS_VBLongWait(SiS_Pr);
4709
4710        if(HwInfo->jChipType < SIS_315H) {
4711           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4712              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4713              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4714           }
4715        }
4716
4717     }
4718
4719   } else {   /* =================== For LVDS ================== */
4720
4721     if(HwInfo->jChipType < SIS_315H) {
4722
4723 #ifdef SIS300    /* 300 series */
4724
4725        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4726           if(HwInfo->jChipType == SIS_730) {
4727              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4728              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4729              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4730           }
4731           SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4732           if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4733              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4734           }
4735        }
4736
4737        SiS_EnableCRT2(SiS_Pr);
4738        SiS_DisplayOn(SiS_Pr);
4739        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4740        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4741        if(SiS_BridgeInSlave(SiS_Pr)) {
4742           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4743        } else {
4744           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4745        }
4746
4747        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4748           if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4749              SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4750              SiS_SetCH700x(SiS_Pr,0x0B0E);
4751           }
4752        }
4753
4754        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4755           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4756              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4757                 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4758                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4759                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4760                 }
4761                 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4762                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4763              }
4764           }
4765        }
4766
4767 #endif  /* SIS300 */
4768
4769     } else {
4770
4771 #ifdef SIS315H    /* 315 series */
4772
4773        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4774           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4775              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4776              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4777           }
4778        }
4779
4780        SiS_EnableCRT2(SiS_Pr);
4781        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4782
4783        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4784
4785        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4786           temp = SiS_GetCH701x(SiS_Pr,0x66);
4787           temp &= 0x20;
4788           SiS_Chrontel701xBLOff(SiS_Pr);
4789        }
4790
4791        if(HwInfo->jChipType != SIS_550) {
4792           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4793        }
4794
4795        if(HwInfo->jChipType == SIS_740) {
4796           if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4797              if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4798                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4799              }
4800           }
4801        }
4802
4803        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4804        if(!(temp1 & 0x80)) {
4805           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4806        }
4807
4808        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4809           if(temp) {
4810              SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4811           }
4812        }
4813
4814        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4815           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4816              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4817              if(HwInfo->jChipType == SIS_550) {
4818                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4819                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4820              }
4821           }
4822        } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4823           if(HwInfo->jChipType != SIS_740) {
4824              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4825           }
4826        }
4827
4828        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4829           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4830        }
4831
4832        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4833           if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4834              SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4835           }
4836           if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4837               (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4838              SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4839           }
4840        }
4841
4842        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4843           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4844              if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4845                  (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4846                 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4847                 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4848              }
4849           }
4850        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4851           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4852              if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4853                 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4854                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4855              }
4856           }
4857        }
4858
4859 #endif  /* SIS315H */
4860
4861     } /* 310 series */
4862
4863   }  /* LVDS */
4864
4865 }
4866
4867 /*********************************************/
4868 /*         SET PART 1 REGISTER GROUP         */
4869 /*********************************************/
4870
4871 /********** Set CRT2 OFFSET / PITCH **********/
4872 static void
4873 SiS_SetCRT2Offset(SiS_Private *SiS_Pr,USHORT ModeNo,
4874                   USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
4875                   PSIS_HW_INFO HwInfo)
4876 {
4877   USHORT offset;
4878   UCHAR temp;
4879
4880   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4881
4882   offset = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
4883                          HwInfo);
4884
4885   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
4886      SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
4887
4888   temp = (UCHAR)(offset & 0xFF);
4889   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,temp);
4890   temp = (UCHAR)(offset >> 8);
4891   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,temp);
4892   temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4893   if(offset % 8) temp++;
4894   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4895 }
4896
4897 /************* Set CRT2 Sync *************/
4898 static void
4899 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4900                 PSIS_HW_INFO HwInfo)
4901 {
4902   USHORT tempah=0,tempbl,infoflag;
4903
4904   tempbl = 0xC0;
4905
4906   if(SiS_Pr->UseCustomMode) {
4907      infoflag = SiS_Pr->CInfoFlag;
4908   } else {
4909      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4910   }
4911
4912   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                    /* LVDS */
4913
4914      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4915         tempah = 0;
4916      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4917         tempah = SiS_Pr->SiS_LCDInfo;
4918      } else tempah = infoflag >> 8;
4919
4920      tempah &= 0xC0;
4921
4922      tempah |= 0x20;
4923      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4924
4925      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4926         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4927            (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4928            tempah |= 0xc0;
4929         }
4930      }
4931
4932      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4933         if(HwInfo->jChipType >= SIS_315H) {
4934            tempah >>= 3;
4935            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4936         } else {
4937            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4938         }
4939      } else {
4940         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4941      }
4942
4943   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4944
4945      if(HwInfo->jChipType < SIS_315H) {
4946
4947 #ifdef SIS300  /* ---- 300 series --- */
4948
4949         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {                   /* 630 - 301B(-DH) */
4950
4951            tempah = infoflag >> 8;
4952            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4953               if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4954                  tempah = SiS_Pr->SiS_LCDInfo;
4955               }
4956            }
4957            tempah &= 0xC0;
4958
4959            tempah |= 0x20;
4960            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4961
4962            tempah &= 0x3f;
4963            tempah |= tempbl;
4964            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4965
4966         } else {                                                        /* 630 - 301 */
4967
4968            tempah = infoflag >> 8;
4969            tempah &= 0xC0;
4970            tempah |= 0x20;
4971            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4972            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4973
4974         }
4975
4976 #endif /* SIS300 */
4977
4978      } else {
4979
4980 #ifdef SIS315H  /* ------- 315 series ------ */
4981
4982         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                     /* 315 - 30xLV */
4983
4984            if(((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4985                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) ||
4986               ((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
4987                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050))) {
4988               tempah = infoflag >> 8;
4989            } else {
4990               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4991            }
4992            tempah &= 0xC0;
4993
4994            tempah |= 0x20;
4995            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4996            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4997
4998         } else {                                                        /* 315 - 301, 301B */
4999
5000            tempah = infoflag >> 8;
5001            if(!SiS_Pr->UseCustomMode) {
5002               if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5003                  if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5004                     tempah = SiS_Pr->SiS_LCDInfo;
5005                  }
5006               }
5007            }
5008            tempah &= 0xC0;
5009
5010            tempah |= 0x20;
5011            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5012
5013            if(SiS_Pr->SiS_VBType & VB_NoLCD) {                  /* TEST, imitate BIOS bug */
5014               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5015                  tempah |= 0xc0;
5016               }
5017            }
5018            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5019
5020         }
5021 #endif  /* SIS315H */
5022       }
5023    }
5024 }
5025
5026 /******** Set CRT2 FIFO on 300/630/730 *******/
5027 #ifdef SIS300
5028 static void
5029 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
5030                     PSIS_HW_INFO HwInfo)
5031 {
5032   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
5033   USHORT temp,index;
5034   USHORT modeidindex,refreshratetableindex;
5035   USHORT VCLK=0,MCLK,colorth=0,data2=0;
5036   USHORT tempal, tempah, tempbx, tempcl, tempax;
5037   USHORT CRT1ModeNo,CRT2ModeNo;
5038   USHORT SelectRate_backup;
5039   ULONG  data,eax;
5040   const UCHAR  LatencyFactor[] = {
5041         97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
5042         00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
5043         97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
5044         00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
5045         80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
5046         00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
5047         86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
5048         00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
5049   };
5050   const UCHAR  LatencyFactor730[] = {
5051          69, 63, 61,
5052          86, 79, 77,
5053         103, 96, 94,
5054         120,113,111,
5055         137,130,128,    /* <-- last entry, data below */
5056         137,130,128,    /* to avoid using illegal values */
5057         137,130,128,
5058         137,130,128,
5059         137,130,128,
5060         137,130,128,
5061         137,130,128,
5062         137,130,128,
5063         137,130,128,
5064         137,130,128,
5065         137,130,128,
5066         137,130,128,
5067   };
5068   const UCHAR ThLowB[]   = {
5069         81, 4, 72, 6, 88, 8,120,12,
5070         55, 4, 54, 6, 66, 8, 90,12,
5071         42, 4, 45, 6, 55, 8, 75,12
5072   };
5073   const UCHAR ThTiming[] = {
5074         1, 2, 2, 3, 0, 1, 1, 2
5075   };
5076
5077   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5078
5079   if(!SiS_Pr->CRT1UsesCustomMode) {
5080
5081      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                         /* get CRT1 ModeNo */
5082      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5083      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5084      SiS_Pr->SiS_SelectCRT2Rate = 0;
5085      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
5086
5087      if(CRT1ModeNo >= 0x13) {
5088         index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
5089         index &= 0x3F;
5090         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                               /* Get VCLK */
5091
5092         colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex);     /* Get colordepth */
5093         colorth >>= 1;
5094         if(!colorth) colorth++;
5095      }
5096
5097   } else {
5098
5099      CRT1ModeNo = 0xfe;
5100      VCLK = SiS_Pr->CSRClock_CRT1;                                              /* Get VCLK */
5101      data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
5102      switch(data2) {                                                            /* Get color depth */
5103         case 0 : colorth = 1; break;
5104         case 1 : colorth = 1; break;
5105         case 2 : colorth = 2; break;
5106         case 3 : colorth = 2; break;
5107         case 4 : colorth = 3; break;
5108         case 5 : colorth = 4; break;
5109         default: colorth = 2;
5110      }
5111
5112   }
5113
5114   if(CRT1ModeNo >= 0x13) {
5115     if(HwInfo->jChipType == SIS_300) {
5116        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5117     } else {
5118        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5119     }
5120     index &= 0x07;
5121     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;                         /* Get MCLK */
5122
5123     data2 = (colorth * VCLK) / MCLK;
5124
5125     temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5126     temp = ((temp & 0x00FF) >> 6) << 1;
5127     if(temp == 0) temp = 1;
5128     temp <<= 2;
5129     temp &= 0xff;
5130
5131     data2 = temp - data2;
5132
5133     if((28 * 16) % data2) {
5134         data2 = (28 * 16) / data2;
5135         data2++;
5136     } else {
5137         data2 = (28 * 16) / data2;
5138     }
5139
5140     if(HwInfo->jChipType == SIS_300) {
5141
5142         tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
5143         tempah &= 0x62;
5144         tempah >>= 1;
5145         tempal = tempah;
5146         tempah >>= 3;
5147         tempal |= tempah;
5148         tempal &= 0x07;
5149         tempcl = ThTiming[tempal];
5150         tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5151         tempbx >>= 6;
5152         tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5153         tempah >>= 4;
5154         tempah &= 0x0c;
5155         tempbx |= tempah;
5156         tempbx <<= 1;
5157         tempal = ThLowB[tempbx + 1];
5158         tempal *= tempcl;
5159         tempal += ThLowB[tempbx];
5160         data = tempal;
5161
5162     } else if(HwInfo->jChipType == SIS_730) {
5163
5164 #ifndef LINUX_XF86
5165        SiS_SetRegLong(0xcf8,0x80000050);
5166        eax = SiS_GetRegLong(0xcfc);
5167 #else
5168        eax = pciReadLong(0x00000000, 0x50);
5169 #endif
5170        tempal = (USHORT)(eax >> 8);
5171        tempal &= 0x06;
5172        tempal <<= 5;
5173
5174 #ifndef LINUX_XF86
5175        SiS_SetRegLong(0xcf8,0x800000A0);
5176        eax = SiS_GetRegLong(0xcfc);
5177 #else
5178        eax = pciReadLong(0x00000000, 0xA0);
5179 #endif
5180        temp = (USHORT)(eax >> 28);
5181        temp &= 0x0F;
5182        tempal |= temp;
5183
5184        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5185        tempbx = 0;        /* -- do it like the BIOS anyway... */
5186        tempax = tempbx;
5187        tempbx &= 0xc0;
5188        tempbx >>= 6;
5189        tempax &= 0x0f;
5190        tempax *= 3;
5191        tempbx += tempax;
5192
5193        data = LatencyFactor730[tempbx];
5194        data += 15;
5195        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5196        if(!(temp & 0x80)) data += 5;
5197
5198     } else {
5199
5200        index = 0;
5201        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5202        if(temp & 0x0080) index += 12;
5203
5204 #ifndef LINUX_XF86
5205        SiS_SetRegLong(0xcf8,0x800000A0);
5206        eax = SiS_GetRegLong(0xcfc);
5207 #else
5208        /* We use pci functions X offers. We use tag 0, because
5209         * we want to read/write to the host bridge (which is always
5210         * 00:00.0 on 630, 730 and 540), not the VGA device.
5211         */
5212        eax = pciReadLong(0x00000000, 0xA0);
5213 #endif
5214        temp = (USHORT)(eax >> 24);
5215        if(!(temp&0x01)) index += 24;
5216
5217 #ifndef LINUX_XF86
5218        SiS_SetRegLong(0xcf8,0x80000050);
5219        eax = SiS_GetRegLong(0xcfc);
5220 #else
5221        eax = pciReadLong(0x00000000, 0x50);
5222 #endif
5223        temp=(USHORT)(eax >> 24);
5224        if(temp & 0x01) index += 6;
5225
5226        temp = (temp & 0x0F) >> 1;
5227        index += temp;
5228
5229        data = LatencyFactor[index];
5230        data += 15;
5231        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5232        if(!(temp & 0x80)) data += 5;
5233     }
5234
5235     data += data2;                              /* CRT1 Request Period */
5236
5237     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5238     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5239
5240     if(!SiS_Pr->UseCustomMode) {
5241
5242        CRT2ModeNo = ModeNo;
5243        SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5244
5245        refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5246
5247        index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5248                                refreshratetableindex,HwInfo);
5249        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                                /* Get VCLK  */
5250
5251        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5252           if((ROMAddr) && SiS_Pr->SiS_UseROM) {
5253              if(ROMAddr[0x220] & 0x01) {
5254                 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5255              }
5256           }
5257        }
5258
5259     } else {
5260
5261        CRT2ModeNo = 0xfe;
5262        VCLK = SiS_Pr->CSRClock;                                                 /* Get VCLK */
5263
5264     }
5265
5266     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex);         /* Get colordepth */
5267     colorth >>= 1;
5268     if(!colorth) colorth++;
5269
5270     data = data * VCLK * colorth;
5271     if(data % (MCLK << 4)) {
5272         data = data / (MCLK << 4);
5273         data++;
5274     } else {
5275         data = data / (MCLK << 4);
5276     }
5277
5278     if(data <= 6) data = 6;
5279     if(data > 0x14) data = 0x14;
5280
5281     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5282     if(HwInfo->jChipType == SIS_300) {
5283        if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5284        else             temp = (temp & (~0x1F)) | 0x16;
5285        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
5286                 temp = (temp & (~0x1F)) | 0x13;
5287        }
5288     } else {
5289        if( ( (HwInfo->jChipType == SIS_630) ||
5290              (HwInfo->jChipType == SIS_730) )  &&
5291            (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5292       {
5293           temp = (temp & (~0x1F)) | 0x1b;
5294       } else {
5295           temp = (temp & (~0x1F)) | 0x16;
5296       }
5297     }
5298     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5299
5300     if( (HwInfo->jChipType == SIS_630) &&
5301         (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5302     {
5303         if(data > 0x13) data = 0x13;
5304     }
5305     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5306
5307   } else {  /* If mode <= 0x13, we just restore everything */
5308
5309     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5310     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5311
5312   }
5313 }
5314 #endif
5315
5316 /**** Set CRT2 FIFO on 315/330 series ****/
5317 #ifdef SIS315H
5318 static void
5319 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr)
5320 {
5321   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5322   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
5323 }
5324 #endif
5325
5326 /*************** Set LCD-A ***************/
5327 #ifdef SIS315H
5328 static void
5329 SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5330                    PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5331 {
5332   USHORT modeflag,resinfo;
5333   USHORT push2,tempax,tempbx,tempcx,temp;
5334   ULONG tempeax=0,tempebx,tempecx,tempvcfact;
5335
5336   /* This is not supported with LCDA */
5337   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
5338   if(SiS_Pr->UseCustomMode) return;
5339
5340   if(IS_SIS330) {
5341      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);                     /* Xabre 1.01.03 */
5342   } else if(IS_SIS740) {
5343      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                 /* 740/LVDS */
5344         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);          /* 740/LVDS */
5345         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5346      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5347         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);                  /* 740/301LV, 301BDH */
5348      }
5349   } else {
5350      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                 /* 650/LVDS */
5351         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);          /* 650/LVDS */
5352         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);                  /* 650/LVDS 1.10.07 */
5353      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5354         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);                 /* 650/30xLv 1.10.6s */
5355      }
5356   }
5357
5358   if(ModeNo <= 0x13) {
5359      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5360      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5361   } else {
5362      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5363      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5364   }
5365
5366   tempax = SiS_Pr->SiS_LCDHDES;
5367
5368   temp = (tempax & 0x0007);                                     /* BPLHDESKEW[2:0]   */
5369   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
5370   temp = (tempax >> 3) & 0x00FF;                                /* BPLHDESKEW[10:3]  */
5371   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
5372
5373   tempbx = SiS_Pr->SiS_HDE;
5374   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5375      tempbx = SiS_Pr->PanelXRes;
5376   }
5377
5378   tempax += tempbx;                                             /* HDE + HSKEW = lcdhdee  */
5379   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5380
5381   temp = tempax;
5382   if(SiS_Pr->SiS_VBType & VB_SISVB) {
5383      if(temp & 0x07) temp += 8;
5384   }
5385   temp >>= 3;                                                   /* BPLHDEE  */
5386   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                          /* Part1_17h  */
5387
5388   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;                      /* (HT-HDE) / 4  */
5389
5390   /* 650/30xLV 1.10.6s, 740/LVDS */
5391   if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
5392       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
5393      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5394         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
5395         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
5396         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
5397         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
5398         else                                                          tempcx = 0x30;
5399      }
5400   }
5401
5402   tempcx += tempax;                                             /* lcdhrs  */
5403   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5404
5405   temp = (tempcx >> 3) & 0x00FF;                                /* BPLHRS */
5406   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                          /* Part1_14h  */
5407
5408   temp += 10;
5409   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
5410      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5411         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5412            temp += 6;
5413            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
5414               temp++;
5415               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
5416                  temp += 7;
5417                  if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
5418                     temp -= 10;
5419                  }
5420               }
5421            }
5422         }
5423      }
5424   }
5425   temp &= 0x1F;
5426   temp |= ((tempcx & 0x07) << 5);
5427   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
5428
5429   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
5430      tempax = SiS_Pr->PanelYRes;
5431   } else {
5432      tempax = SiS_Pr->SiS_VGAVDE;
5433   }
5434
5435   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5436   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5437   push2 = tempbx;
5438
5439   tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
5440
5441   if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
5442       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
5443      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5444         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
5445         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
5446         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
5447         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
5448         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
5449         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 1;
5450         else                                                           tempcx = 0x0057;
5451      }
5452   }
5453
5454   tempbx += tempcx;
5455   if(SiS_Pr->SiS_VBType & VB_SISVB) {
5456      tempbx++;                                                  /* BPLVRS  */
5457   }
5458   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5459   temp = tempbx & 0x00FF;
5460   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
5461
5462   tempcx >>= 3;
5463   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
5464      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5465         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5466            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 3;
5467            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 5;
5468            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 5;
5469            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 5;
5470            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 2;
5471            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 2;
5472         }
5473      }
5474   }
5475   tempcx += tempbx;
5476   tempcx++;                                                     /* BPLVRE  */
5477   temp = tempcx & 0x000F;
5478   if(SiS_Pr->SiS_VBType & VB_SISVB) {
5479      temp |= 0xC0;
5480      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
5481   } else {
5482      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
5483   }
5484
5485   temp = ((tempbx >> 8) & 0x07) << 3;
5486   if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5487   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)   temp |= 0x40;
5488   if(SiS_Pr->SiS_VBType & VB_SISVB) {
5489      /* Don't check Part1Port,0x00 -> is not being set if LCDA! */
5490      /* We check SR06 instead here: */
5491      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5492         if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5493      }
5494   } else {
5495      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5496         if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5497      }
5498   }
5499   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
5500
5501   tempbx = push2;                                               /* BPLVDEE */
5502
5503   tempcx = SiS_Pr->SiS_LCDVDES;                                 /* NPLVDES */
5504   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5505      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
5506         if(resinfo == SIS_RI_800x600) tempcx++;
5507      }
5508   }
5509   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
5510      tempbx = tempcx = SiS_Pr->SiS_VGAVDE;
5511      tempbx--;
5512   }
5513
5514   temp = ((tempbx >> 8) & 0x07) << 3;
5515   temp = temp | ((tempcx >> 8) & 0x07);
5516   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
5517   temp = tempbx & 0x00FF;
5518   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
5519   temp = tempcx & 0x00FF;
5520   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
5521
5522   tempeax = SiS_Pr->SiS_VGAVDE << 18;
5523   tempebx = SiS_Pr->SiS_VDE;
5524   temp = (USHORT)(tempeax % tempebx);
5525   tempeax = tempeax / tempebx;
5526   if(temp) tempeax++;
5527   tempvcfact = tempeax;
5528
5529   temp = (USHORT)(tempeax & 0x00FF);
5530   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5531
5532   temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5533   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5534
5535   temp = (USHORT)((tempeax & 0x00030000) >> 16);
5536   if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5537   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5538
5539   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5540      temp = (USHORT)(tempeax & 0x00FF);
5541      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5542      temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5543      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5544      temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5545      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5546      temp = 0;
5547      if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5548      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5549   }
5550
5551   tempeax = SiS_Pr->SiS_VGAHDE << 16;
5552   tempebx = SiS_Pr->SiS_HDE;
5553   temp = tempeax % tempebx;
5554   tempeax /= tempebx;
5555   if(temp) tempeax++;
5556   if(tempebx == SiS_Pr->SiS_VGAHDE) tempeax = 0xFFFF;
5557   tempecx = tempeax;
5558   tempeax = ((SiS_Pr->SiS_VGAHDE << 16) / tempecx) - 1;
5559   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5560   temp = (USHORT)(tempecx & 0x00FF);
5561   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
5562
5563   tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5564   tempbx = (USHORT)(tempeax & 0x0FFFF);
5565
5566   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
5567
5568   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
5569
5570   temp = ((tempbx >> 8) & 0x07) << 3;
5571   temp = temp | ((tempecx >> 8) & 0x07);
5572   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
5573
5574   temp = tempbx & 0x00FF;
5575   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
5576
5577   tempecx >>= 16;                                               /* BPLHCFACT  */
5578   if(modeflag & HalfDCLK) tempecx >>= 1;
5579   temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
5580   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
5581
5582   temp = (USHORT)(tempecx & 0x000000FF);
5583   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5584
5585   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
5586      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5587   }
5588 }
5589 #endif  /* SIS 315 */
5590
5591 static USHORT
5592 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5593 {
5594   ULONG tempax,tempbx;
5595
5596   tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
5597   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5598   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5599   return((USHORT) tempax);
5600 }
5601
5602 /******* Set Part 1 / SiS bridge *********/
5603 static void
5604 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5605                   PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5606 {
5607   USHORT  push1,push2;
5608   USHORT  tempax,tempbx,tempcx,temp;
5609   USHORT  resinfo,modeflag;
5610   unsigned char p1_7, p1_8;
5611
5612   if(ModeNo <= 0x13) {
5613      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5614      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5615   } else {
5616      if(SiS_Pr->UseCustomMode) {
5617         modeflag = SiS_Pr->CModeFlag;
5618         resinfo = 0;
5619      } else {
5620         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5621         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5622      }
5623   }
5624
5625   /* The following is only done if bridge is in slave mode: */
5626
5627   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
5628
5629   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
5630
5631   if(modeflag & Charx8Dot) tempcx = 0x08;
5632   else                     tempcx = 0x09;
5633
5634   tempax = SiS_Pr->SiS_VGAHDE;                                  /* 0x04 Horizontal Display End */
5635   if(modeflag & HalfDCLK) tempax >>= 1;
5636   tempax = ((tempax / tempcx) - 1) & 0xff;
5637   tempbx = tempax;
5638
5639   temp = tempax;
5640   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5641
5642   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5643      if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5644         temp += 2;
5645      }
5646   }
5647   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5648      if(resinfo == SIS_RI_800x600) temp -= 2;
5649   }
5650   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
5651
5652   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
5653
5654   tempax = 0xFFFF;
5655   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5656   if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5657   if(modeflag & HalfDCLK)         tempax >>= 1;
5658   tempax = (tempax / tempcx) - 5;
5659   tempcx = tempax;
5660
5661   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5662      temp = tempcx - 1;
5663      if(!(modeflag & HalfDCLK)) {
5664         temp -= 6;
5665         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5666            temp -= 2;
5667            if(ModeNo > 0x13) temp -= 10;
5668         }
5669      }
5670   } else {
5671      tempcx = (tempcx + tempbx) >> 1;
5672      temp = (tempcx & 0x00FF) + 2;
5673      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5674         temp--;
5675         if(!(modeflag & HalfDCLK)) {
5676            if((modeflag & Charx8Dot)) {
5677               temp += 4;
5678               if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5679               if(HwInfo->jChipType >= SIS_315H) {
5680                  if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5681               }
5682            }
5683         }
5684      } else {
5685         if(!(modeflag & HalfDCLK)) {
5686            temp -= 4;
5687            if((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) &&
5688               (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200)) {
5689               if(SiS_Pr->SiS_VGAHDE >= 800) {
5690                  temp -= 7;
5691                  if(HwInfo->jChipType < SIS_315H) {
5692                     /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
5693                     if(SiS_Pr->SiS_ModeType == ModeEGA) {
5694                        if(SiS_Pr->SiS_VGAVDE == 1024) {
5695                           temp += 15;
5696                           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
5697                              temp += 7;
5698                        }
5699                     }
5700                  }
5701                  if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
5702                     if(SiS_Pr->SiS_VGAHDE >= 1280) {
5703                        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5704                     }
5705                  }
5706               }
5707            }
5708         }
5709      }
5710   }
5711
5712   p1_7 = temp;
5713   p1_8 = 0x00;
5714
5715   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5716      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5717         if(ModeNo <= 0x01) {
5718            p1_7 = 0x2a;
5719            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5720            else                                 p1_8 = 0x41;
5721         } else if(SiS_Pr->SiS_ModeType == ModeText) {
5722            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5723            else                                 p1_7 = 0x55;
5724            p1_8 = 0x00;
5725         } else if(ModeNo <= 0x13) {
5726            if(modeflag & HalfDCLK) {
5727               if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5728                  p1_7 = 0x30;
5729                  p1_8 = 0x03;
5730               } else {
5731                  p1_7 = 0x2f;
5732                  p1_8 = 0x02;
5733               }
5734            } else {
5735               p1_7 = 0x5b;
5736               p1_8 = 0x03;
5737            }
5738         } else if( ((HwInfo->jChipType >= SIS_315H) &&
5739                     ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5740                    ((HwInfo->jChipType < SIS_315H) &&
5741                     (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5742            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5743               p1_7 = 0x30,
5744               p1_8 = 0x03;
5745            } else {
5746               p1_7 = 0x2f;
5747               p1_8 = 0x03;
5748            }
5749         }
5750      }
5751   }
5752
5753   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5754      if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5755         p1_7 = 0x63;
5756         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5757      }
5758      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5759         if(!(modeflag & HalfDCLK)) {
5760            p1_7 = 0xb2;
5761            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5762               p1_7 = 0xab;
5763            }
5764         }
5765      }
5766   }
5767
5768   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7);                  /* 0x07 Horizontal Retrace Start */
5769   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8);                  /* 0x08 Horizontal Retrace End   */
5770
5771   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                  /* 0x18 SR08 (FIFO Threshold?)   */
5772
5773   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5774
5775   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                  /* 0x09 Set Max VT    */
5776
5777   tempcx = 0x121;
5778   tempbx = SiS_Pr->SiS_VGAVDE;                                  /* 0x0E Vertical Display End */
5779   if     (tempbx == 357) tempbx = 350;
5780   else if(tempbx == 360) tempbx = 350;
5781   else if(tempbx == 375) tempbx = 350;
5782   else if(tempbx == 405) tempbx = 400;
5783   else if(tempbx == 420) tempbx = 400;
5784   else if(tempbx == 525) tempbx = 480;
5785   push2 = tempbx;
5786   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5787      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
5788         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5789            if     (tempbx == 350) tempbx += 5;
5790            else if(tempbx == 480) tempbx += 5;
5791         }
5792      }
5793   }
5794   tempbx -= 2;
5795   temp = tempbx & 0x00FF;
5796   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);                  /* 0x10 vertical Blank Start */
5797
5798   tempbx = push2;
5799   tempbx--;
5800   temp = tempbx & 0x00FF;
5801 #if 0
5802   /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5803   if(xxx()) {
5804       if(temp == 0xdf) temp = 0xda;
5805   }
5806 #endif
5807   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5808
5809   temp = 0;
5810   if(modeflag & DoubleScanMode) temp |= 0x80;
5811   if(HwInfo->jChipType >= SIS_661) {
5812      if(tempbx & 0x0200)        temp |= 0x20;
5813      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5814      if(tempbx & 0x0100)  tempcx |= 0x000a;
5815      if(tempbx & 0x0400)  tempcx |= 0x1200;
5816   } else {
5817      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5818      if(tempbx & 0x0100)  tempcx |= 0x0002;
5819      if(tempbx & 0x0400)  tempcx |= 0x0600;
5820   }
5821
5822   if(tempbx & 0x0200)  tempcx |= 0x0040;
5823
5824   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                  /* 0x11 Vertical Blank End */
5825
5826   tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5827
5828   if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5829      if(resinfo != SIS_RI_1280x1024) {
5830         tempbx += (tempax << 1);
5831      }
5832   } else if(HwInfo->jChipType >= SIS_315H) {
5833      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
5834         tempbx += (tempax << 1);
5835      }
5836   }
5837
5838   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5839      tempbx -= 10;
5840   } else {
5841      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5842         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5843            tempbx += 40;
5844            if(HwInfo->jChipType >= SIS_315H) {
5845               if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5846            }
5847         }
5848      }
5849   }
5850   tempax >>= 2;
5851   tempax++;
5852   tempax += tempbx;
5853   push1 = tempax;
5854   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5855      if(tempbx <= 513)  {
5856         if(tempax >= 513) tempbx = 513;
5857      }
5858   }
5859   temp = tempbx & 0x00FF;
5860   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                  /* 0x0C Vertical Retrace Start */
5861
5862   tempbx--;
5863   temp = tempbx & 0x00FF;
5864   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5865
5866   if(tempbx & 0x0100) tempcx |= 0x0008;
5867
5868   if(tempbx & 0x0200) {
5869      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5870   }
5871   tempbx++;
5872
5873   if(tempbx & 0x0100) tempcx |= 0x0004;
5874   if(tempbx & 0x0200) tempcx |= 0x0080;
5875   if(tempbx & 0x0400) {
5876      if(HwInfo->jChipType >= SIS_661)        tempcx |= 0x0800;
5877      else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5878      else                                    tempcx |= 0x0C00;
5879   }
5880
5881   tempbx = push1;
5882   temp = tempbx & 0x000F;
5883   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                  /* 0x0D vertical Retrace End */
5884
5885   if(tempbx & 0x0010) tempcx |= 0x2000;
5886
5887   temp = tempcx & 0x00FF;
5888   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* 0x0A CR07 */
5889
5890   temp = (tempcx & 0xFF00) >> 8;
5891   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                  /* 0x17 SR0A */
5892
5893   tempax = modeflag;
5894   temp = (tempax & 0xFF00) >> 8;
5895   temp = (temp >> 1) & 0x09;
5896   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01;           /* Always 8 dotclock */
5897   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* 0x16 SR01 */
5898
5899   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                  /* 0x0F CR14 */
5900
5901   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                  /* 0x12 CR17 */
5902
5903   temp = 0x00;
5904   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5905      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5906         temp = 0x80;
5907      }
5908   }
5909   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* 0x1A SR0E */
5910 }
5911
5912 /*********** Set Part 1 / LVDS ***********/
5913 static void
5914 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5915                    PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5916 {
5917   USHORT modeflag, resinfo;
5918   USHORT push1, push2, tempax, tempbx, tempcx, temp;
5919 #ifdef SIS315H
5920   USHORT pushcx;
5921 #endif
5922   ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
5923
5924   /* This is not supported on LVDS */
5925   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
5926   if(SiS_Pr->UseCustomMode) return;
5927
5928   if(ModeNo <= 0x13) {
5929      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5930      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5931   } else {
5932      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5933      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5934   }
5935
5936   /* Set up Panel Link */
5937
5938   /* 1. Horizontal setup */
5939
5940   tempax = SiS_Pr->SiS_LCDHDES;
5941
5942   if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5943      if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
5944          (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5945            tempax -= 8;
5946      }
5947   }
5948
5949   tempcx = SiS_Pr->SiS_HT;                                /* Horiz. Total */
5950
5951   tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
5952
5953   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
5954      SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
5955      tempbx >>= 1;
5956   }
5957
5958   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5959      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5960         if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5961            tempbx = SiS_Pr->PanelXRes;
5962         } else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5963            tempbx = SiS_Pr->PanelXRes;
5964            if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
5965               tempbx = 800;
5966               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
5967                  tempbx = 1024;
5968               }
5969            }
5970         }
5971      }
5972   }
5973   tempcx = (tempcx - tempbx) >> 2;               /* HT-HDE / 4 */
5974
5975   push1 = tempax;
5976
5977   tempax += tempbx;
5978
5979   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5980
5981   push2 = tempax;
5982
5983   if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
5984      (!SiS_Pr->SiS_IF_DEF_DSTN) &&
5985      (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
5986      (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
5987      (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
5988      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5989         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5990            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
5991               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
5992               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
5993               else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
5994                     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
5995                    if(HwInfo->jChipType < SIS_315H) {
5996                       if(SiS_Pr->SiS_VBType & VB_SISVB) {
5997                          tempcx = 0x0017;  /* A901; sometimes 0x0018; */
5998                       } else {
5999                          tempcx = 0x0017;
6000 #ifdef TWNEWPANEL
6001                          tempcx = 0x0018;
6002 #endif
6003                       }
6004                    } else {
6005                       tempcx = 0x0018;
6006                    }
6007               }
6008               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
6009               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
6010               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
6011               else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
6012            }
6013         }
6014      }
6015   }
6016
6017   tempcx += tempax;                              /* lcdhrs  */
6018   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
6019
6020   tempax = tempcx >> 3;                          /* BPLHRS */
6021   temp = tempax & 0x00FF;
6022   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);           /* Part1_14h; Panel Link Horizontal Retrace Start  */
6023
6024   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
6025      temp = (tempax & 0x00FF) + 2;
6026   } else {
6027      temp = (tempax & 0x00FF) + 10;
6028      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6029         if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
6030            (!SiS_Pr->SiS_IF_DEF_FSTN) &&
6031            (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
6032            (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
6033            (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
6034            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
6035               temp += 6;
6036               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
6037                  temp++;
6038                  if(HwInfo->jChipType >= SIS_315H) {
6039                     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
6040                        temp += 7;
6041                        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
6042                           temp -= 0x14;
6043                           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
6044                              temp -= 10;
6045                           }
6046                        }
6047                     }
6048                  }
6049               }
6050            }
6051         }
6052      }
6053   }
6054
6055   temp &= 0x1F;
6056   temp |= ((tempcx & 0x0007) << 5);
6057 #if 0
6058   if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
6059 #endif
6060   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);           /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
6061
6062   tempbx = push2;
6063   tempcx = push1;                                /* lcdhdes  */
6064
6065   temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
6066   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);           /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
6067
6068   tempcx >>= 3;                                  /* BPLHDES */
6069   temp = (tempcx & 0x00FF);
6070 #if 0 /* Not 550 FSTN */
6071   if(HwInfo->jChipType >= SIS_315H) {
6072      if(ModeNo == 0x5b) temp--; */
6073   }
6074 #endif
6075   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);           /* Part1_16h; Panel Link Horizontal Display Enable Start  */
6076
6077   if((HwInfo->jChipType < SIS_315H) ||
6078      (SiS_Pr->SiS_IF_DEF_FSTN) ||
6079      (SiS_Pr->SiS_IF_DEF_DSTN)) {
6080      if(tempbx & 0x07) tempbx += 8;
6081   }
6082   tempbx >>= 3;                                  /* BPLHDEE  */
6083   temp = tempbx & 0x00FF;
6084 #if 0 /* Not 550 FSTN */
6085   if(HwInfo->jChipType >= SIS_315H) {
6086      if(ModeNo == 0x5b) temp--;
6087   }
6088 #endif
6089   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);           /* Part1_17h; Panel Link Horizontal Display Enable End  */
6090
6091   /* 2. Vertical setup */
6092
6093   if(HwInfo->jChipType < SIS_315H) {
6094      tempcx = SiS_Pr->SiS_VGAVT;
6095      tempbx = SiS_Pr->SiS_VGAVDE;
6096      if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
6097         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6098            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
6099               tempbx = SiS_Pr->PanelYRes;
6100            }
6101         }
6102      }
6103      tempcx -= tempbx;
6104
6105   } else {
6106
6107      tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
6108
6109   }
6110
6111   tempbx = SiS_Pr->SiS_LCDVDES;                                 /* VGAVDES  */
6112   push1 = tempbx;
6113
6114   tempax = SiS_Pr->SiS_VGAVDE;
6115
6116   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6117      if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
6118         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
6119            tempax = 600;
6120            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
6121               tempax = 768;
6122            }
6123         }
6124      } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
6125                 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
6126                 ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
6127                  (SiS_Pr->SiS_IF_DEF_FSTN) ||
6128                  (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
6129         tempax = SiS_Pr->PanelYRes;
6130      }
6131   }
6132
6133   tempbx += tempax;
6134   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
6135
6136   push2 = tempbx;
6137
6138   tempcx >>= 1;
6139
6140   if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
6141      (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
6142      (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
6143      (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
6144      (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
6145      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6146         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
6147         tempcx = 0x0017;
6148      } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
6149         if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6150            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
6151            else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
6152                    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
6153            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
6154            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
6155            else                                                           tempcx = 0x0057;
6156         } else  {
6157            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
6158            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
6159            else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
6160                    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
6161                    if(HwInfo->jChipType < SIS_315H) {
6162                       if(SiS_Pr->SiS_VBType & VB_SISVB) {
6163                          tempcx = 0x0002;   /* A901; sometimes 0x0003; */
6164                       } else {
6165                          tempcx = 0x0002;
6166 #ifdef TWNEWPANEL
6167                          tempcx = 0x0003;
6168 #endif
6169                       }
6170                    } else tempcx = 0x0003;
6171            }
6172            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
6173            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
6174            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
6175            else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
6176            else                                                          tempcx = 0x0057;
6177         }
6178      }
6179   }
6180
6181   tempbx += tempcx;                             /* BPLVRS  */
6182
6183   if((HwInfo->jChipType < SIS_315H) ||
6184      (SiS_Pr->SiS_IF_DEF_FSTN) ||
6185      (SiS_Pr->SiS_IF_DEF_DSTN)) {
6186      tempbx++;
6187   }
6188
6189   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
6190
6191   temp = tempbx & 0x00FF;
6192   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);           /* Part1_18h; Panel Link Vertical Retrace Start  */
6193
6194   tempcx >>= 3;
6195
6196   if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
6197      (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
6198      (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
6199      (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
6200      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6201         if( (HwInfo->jChipType < SIS_315H) &&
6202             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
6203         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
6204         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
6205         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
6206         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
6207         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
6208         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
6209         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
6210         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
6211         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
6212         else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
6213                 if(HwInfo->jChipType < SIS_315H) {
6214                    if(SiS_Pr->SiS_VBType & VB_SISVB) {
6215                       tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
6216                    } else {
6217                       tempcx = 0x0004;
6218 #ifdef TWNEWPANEL
6219                       tempcx = 0x0005;
6220 #endif
6221                    }
6222                 } else {
6223                    tempcx = 0x0005;
6224                 }
6225         }
6226      }
6227   }
6228
6229   tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
6230   temp = tempcx & 0x000F;
6231   if(SiS_Pr->SiS_IF_DEF_FSTN ||
6232      SiS_Pr->SiS_IF_DEF_DSTN ||
6233      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
6234      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
6235      (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
6236      temp |= 0x30;
6237   }
6238   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
6239
6240   temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
6241   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6242      if(SiS_Pr->SiS_HDE != 640) {
6243         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
6244      }
6245   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
6246   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
6247   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6248      if(HwInfo->jChipType >= SIS_315H) {
6249         if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6250            temp |= 0x80;
6251         }
6252      } else {
6253         if( (HwInfo->jChipType == SIS_630) ||
6254             (HwInfo->jChipType == SIS_730) ) {
6255            if(HwInfo->jChipRevision >= 0x30) {
6256               temp |= 0x80;
6257            }
6258         }
6259      }
6260   }
6261   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
6262
6263   if (HwInfo->jChipType < SIS_315H) {
6264
6265 #ifdef SIS300      /* 300 series */
6266
6267         tempeax = SiS_Pr->SiS_VGAVDE << 6;
6268         temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
6269         tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
6270         if(temp != 0) tempeax++;
6271         tempebx = tempeax;                         /* BPLVCFACT  */
6272
6273         if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6274            tempebx = 0x003F;
6275         }
6276
6277         temp = (USHORT)(tempebx & 0x00FF);
6278         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
6279
6280 #endif /* SIS300 */
6281
6282   } else {
6283
6284 #ifdef SIS315H  /* 315 series */
6285
6286         if(HwInfo->jChipType == SIS_740) {
6287            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
6288         } else {
6289            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,0x23);
6290         }
6291
6292         tempeax = SiS_Pr->SiS_VGAVDE << 18;
6293         temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
6294         tempeax = tempeax / SiS_Pr->SiS_VDE;
6295         if(temp != 0) tempeax++;
6296         tempebx = tempeax;                         /* BPLVCFACT  */
6297         tempvcfact = tempeax;
6298         temp = (USHORT)(tempebx & 0x00FF);
6299         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
6300         temp = (USHORT)((tempebx & 0x00FF00) >> 8);
6301         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
6302         temp = (USHORT)((tempebx & 0x00030000) >> 16);
6303         temp &= 0x03;
6304         if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
6305         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
6306
6307 #endif /* SIS315H */
6308
6309   }
6310
6311   tempbx = push2;                                  /* BPLVDEE  */
6312   tempcx = push1;
6313
6314   push1 = temp;
6315
6316   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6317         if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
6318                 if(HwInfo->jChipType < SIS_315H) {
6319                         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
6320                                 if(resinfo == SIS_RI_1024x600) tempcx++;
6321                                 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6322                                         if(resinfo == SIS_RI_800x600) tempcx++;
6323                                 }
6324                         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
6325                                 if(resinfo == SIS_RI_800x600)  tempcx++;
6326                                 if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
6327                         } else  if(resinfo == SIS_RI_1024x768) tempcx++;
6328                 } else {
6329                         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
6330                                 if(resinfo == SIS_RI_800x600)  tempcx++;
6331                         }
6332                 }
6333         }
6334   }
6335
6336   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
6337      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
6338         tempcx = SiS_Pr->SiS_VGAVDE;
6339         tempbx = SiS_Pr->SiS_VGAVDE - 1;
6340      }
6341   }
6342
6343   temp = ((tempbx & 0x0700) >> 8) << 3;
6344   temp |= ((tempcx & 0x0700) >> 8);
6345   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);          /* Part1_1Dh; Vertical Display Overflow; Control Signal */
6346
6347   temp = tempbx & 0x00FF;
6348   /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
6349   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);          /* Part1_1Ch; Panel Link Vertical Display Enable End  */
6350
6351   temp = tempcx & 0x00FF;
6352   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);          /* Part1_1Bh; Panel Link Vertical Display Enable Start  */
6353
6354   /* 3. Additional horizontal setup (scaling, etc) */
6355
6356   tempecx = SiS_Pr->SiS_VGAHDE;
6357   if(HwInfo->jChipType >= SIS_315H) {
6358      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
6359         if(modeflag & HalfDCLK) tempecx >>= 1;
6360      }
6361   }
6362   tempebx = SiS_Pr->SiS_HDE;
6363   if(tempecx == tempebx) tempeax = 0xFFFF;
6364   else {
6365      tempeax = tempecx;
6366      tempeax <<= 16;
6367      temp = (USHORT)(tempeax % tempebx);
6368      tempeax = tempeax / tempebx;
6369      if(HwInfo->jChipType >= SIS_315H) {
6370         if(temp) tempeax++;
6371      }
6372   }
6373   tempecx = tempeax;
6374
6375   if(HwInfo->jChipType >= SIS_315H) {
6376      tempeax = SiS_Pr->SiS_VGAHDE;
6377      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
6378         if(modeflag & HalfDCLK) tempeax >>= 1;
6379      }
6380      tempeax <<= 16;
6381      tempeax = (tempeax / tempecx) - 1;
6382   } else {
6383      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6384   }
6385   tempecx <<= 16;
6386   tempecx |= (tempeax & 0xFFFF);
6387   temp = (USHORT)(tempecx & 0x00FF);
6388   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);           /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
6389
6390   tempbx = SiS_Pr->SiS_VDE;
6391   if(HwInfo->jChipType >= SIS_315H) {
6392      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6393      tempbx = (USHORT)(tempeax & 0x0FFFF);
6394   } else {
6395      tempeax = SiS_Pr->SiS_VGAVDE << 6;
6396      tempbx = push1 & 0x3f;
6397      if(tempbx == 0) tempbx = 64;
6398      tempeax /= tempbx;
6399      tempbx = (USHORT)(tempeax & 0x0FFFF);
6400   }
6401   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
6402   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6403      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6404      else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
6405   }
6406
6407   temp = ((tempbx & 0xFF00) >> 8) << 3;
6408   temp |= (USHORT)((tempecx & 0x0700) >> 8);
6409   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);          /* Part1_20h; Overflow register */
6410
6411   temp = tempbx & 0x00FF;
6412   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);          /* Part1_21h; Panel Link Vertical Accumulator Register */
6413
6414   tempecx >>= 16;                               /* BPLHCFACT  */
6415   if((HwInfo->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
6416      if(modeflag & HalfDCLK) tempecx >>= 1;
6417   }
6418   temp = (USHORT)((tempecx & 0xFF00) >> 8);
6419   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);          /* Part1_22h; Panel Link Horizontal Scaling Factor High */
6420
6421   temp = (USHORT)(tempecx & 0x00FF);
6422   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
6423
6424   /* 630/301B and 630/LVDS do something for 640x480 panels here */
6425
6426 #ifdef SIS315H
6427   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6428      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6429      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6430      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6431      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6432      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6433      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6434      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
6435      tempax = SiS_Pr->SiS_HDE;                                  /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6436      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6437         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
6438      tempax += 64;
6439      temp = tempax & 0x00FF;
6440      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
6441      temp = ((tempax & 0xFF00) >> 8) << 3;
6442      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6443      tempax += 32;                                              /* Blpe=lBlps+32 */
6444      temp = tempax & 0x00FF;
6445      if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
6446      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
6447      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);               /* Bflml=0 */
6448      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6449
6450      tempax = SiS_Pr->SiS_VDE;
6451      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6452         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
6453      tempax >>= 1;
6454      temp = tempax & 0x00FF;
6455      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
6456      temp = ((tempax & 0xFF00) >> 8) << 3;
6457      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6458
6459      tempeax = SiS_Pr->SiS_HDE;
6460      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6461         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
6462      tempeax <<= 2;                                             /* BDxFIFOSTOP = (HDE*4)/128 */
6463      tempebx = 128;
6464      temp = (USHORT)(tempeax % tempebx);
6465      tempeax = tempeax / tempebx;
6466      if(temp) tempeax++;
6467      temp = (USHORT)(tempeax & 0x003F);
6468      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
6469      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);               /* BDxWadrst0 */
6470      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6471      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6472      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
6473
6474      tempax = SiS_Pr->SiS_HDE;
6475      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6476         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
6477      tempax >>= 4;                                              /* BDxWadroff = HDE*4/8/8 */
6478      pushcx = tempax;
6479      temp = tempax & 0x00FF;
6480      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6481      temp = ((tempax & 0xFF00) >> 8) << 3;
6482      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6483
6484      tempax = SiS_Pr->SiS_VDE;                                  /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6485      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
6486         SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
6487      tempeax = (tempax * pushcx);
6488      tempebx = 0x00100000 + tempeax;
6489      temp = (USHORT)tempebx & 0x000000FF;
6490      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6491      temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6492      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6493      temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
6494      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6495      temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6496      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6497
6498      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6499      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6500      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6501      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6502      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6503
6504      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6505         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6506         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6507         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6508         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6509         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6510         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6511         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6512         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6513         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6514         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6515         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6516         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6517         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6518         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6519         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6520         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6521         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6522         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6523         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6524         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6525      }
6526   }
6527 #endif  /* SIS315H */
6528
6529 }
6530
6531 /************** Set Part 1 ***************/
6532 static void
6533 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6534               PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6535 {
6536   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
6537   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
6538   USHORT  pushbx=0, CRT1Index=0;
6539 #ifdef SIS315H
6540   USHORT  tempbl=0;
6541 #endif
6542   USHORT  modeflag, resinfo=0;
6543
6544   if(ModeNo <= 0x13) {
6545      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6546   } else {
6547      if(SiS_Pr->UseCustomMode) {
6548         modeflag = SiS_Pr->CModeFlag;
6549      } else {
6550         CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6551         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6552         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6553      }
6554   }
6555
6556   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6557
6558 #ifdef SIS315H
6559      SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
6560      SiS_SetGroup1_LCDA(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6561 #endif
6562
6563   } else {
6564
6565      if( (HwInfo->jChipType >= SIS_315H) &&
6566          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6567          (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
6568
6569         SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
6570
6571      } else {
6572
6573         SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex,
6574                           RefreshRateTableIndex, HwInfo);
6575
6576         if (HwInfo->jChipType < SIS_315H ) {
6577 #ifdef SIS300
6578               SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6579 #endif
6580         } else {
6581 #ifdef SIS315H
6582               SiS_SetCRT2FIFO_310(SiS_Pr);
6583 #endif
6584         }
6585
6586         SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
6587
6588         /* 1. Horizontal setup */
6589
6590         if(HwInfo->jChipType < SIS_315H ) {
6591
6592 #ifdef SIS300   /* ------------- 300 series --------------*/
6593
6594                 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                         /* BTVGA2HT 0x08,0x09 */
6595                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
6596
6597                 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6598                 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
6599
6600                 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
6601                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
6602
6603                 pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
6604                 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6605                 tempbx = pushbx + tempcx;
6606                 tempcx <<= 1;
6607                 tempcx += tempbx;
6608
6609                 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6610
6611                    if(SiS_Pr->UseCustomMode) {
6612                       tempbx = SiS_Pr->CHSyncStart + 12;
6613                       tempcx = SiS_Pr->CHSyncEnd + 12;
6614                    }
6615
6616                    if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6617                       unsigned char cr4, cr14, cr5, cr15;
6618                       if(SiS_Pr->UseCustomMode) {
6619                          cr4  = SiS_Pr->CCRT1CRTC[4];
6620                          cr14 = SiS_Pr->CCRT1CRTC[14];
6621                          cr5  = SiS_Pr->CCRT1CRTC[5];
6622                          cr15 = SiS_Pr->CCRT1CRTC[15];
6623                       } else {
6624                          cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6625                          cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6626                          cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6627                          cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6628                       }
6629                       tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
6630                       tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
6631                    }
6632
6633                    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
6634                       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)){
6635                          tempbx = 1040;
6636                          tempcx = 1042;
6637                       }
6638                    }
6639                 }
6640
6641                 temp = tempbx & 0x00FF;
6642                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
6643 #endif /* SIS300 */
6644
6645         } else {
6646
6647 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
6648
6649                 tempcx = SiS_Pr->SiS_VGAHT;                                    /* BTVGA2HT 0x08,0x09 */
6650                 if(modeflag & HalfDCLK) {
6651                     if(SiS_Pr->SiS_VBType & VB_SISVB) {
6652                        tempcx >>= 1;
6653                     } else {
6654                        tempax = SiS_Pr->SiS_VGAHDE >> 1;
6655                        tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6656                        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6657                           tempcx = SiS_Pr->SiS_HT - tempax;
6658                        }
6659                     }
6660                 }
6661                 tempcx--;
6662
6663                 temp = tempcx & 0xff;
6664                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
6665
6666                 temp = ((tempcx & 0xff00) >> 8) << 4;
6667                 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
6668
6669                 tempcx = SiS_Pr->SiS_VGAHT;                                    /* BTVGA2HDEE 0x0A,0x0C */
6670                 tempbx = SiS_Pr->SiS_VGAHDE;
6671                 tempcx -= tempbx;
6672                 tempcx >>= 2;
6673                 if(modeflag & HalfDCLK) {
6674                    tempbx >>= 1;
6675                    tempcx >>= 1;
6676                 }
6677                 tempbx += 16;
6678
6679                 temp = tempbx & 0xff;
6680                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
6681
6682                 pushbx = tempbx;
6683                 tempcx >>= 1;
6684                 tempbx += tempcx;
6685                 tempcx += tempbx;
6686
6687                 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6688
6689                    if(HwInfo->jChipType >= SIS_661) {
6690                       if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ||
6691                          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
6692                          if(resinfo == SIS_RI_1280x1024) {
6693                             tempcx = 0x30;
6694                          } else if(resinfo == SIS_RI_1600x1200) {
6695                             tempcx = 0xff;
6696                          }
6697                       }
6698                    }
6699
6700                    if(SiS_Pr->UseCustomMode) {
6701                       tempbx = SiS_Pr->CHSyncStart + 16;
6702                       tempcx = SiS_Pr->CHSyncEnd + 16;
6703                       tempax = SiS_Pr->SiS_VGAHT;
6704                       if(modeflag & HalfDCLK) tempax >>= 1;
6705                       tempax--;
6706                       if(tempcx > tempax)  tempcx = tempax;
6707                    }
6708
6709                    if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6710                       unsigned char cr4, cr14, cr5, cr15;
6711                       if(SiS_Pr->UseCustomMode) {
6712                          cr4  = SiS_Pr->CCRT1CRTC[4];
6713                          cr14 = SiS_Pr->CCRT1CRTC[14];
6714                          cr5  = SiS_Pr->CCRT1CRTC[5];
6715                          cr15 = SiS_Pr->CCRT1CRTC[15];
6716                       } else {
6717                          cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6718                          cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6719                          cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6720                          cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6721                       }
6722                       tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                 /* (VGAHRS-3)*8 */
6723                       tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;    /* (VGAHRE-3)*8 */
6724                       tempcx &= 0x00FF;
6725                       tempcx |= (tempbx & 0xFF00);
6726                       tempbx += 16;
6727                       tempcx += 16;
6728                       tempax = SiS_Pr->SiS_VGAHT;
6729                       if(modeflag & HalfDCLK) tempax >>= 1;
6730                       tempax--;
6731                       if(tempcx > tempax)  tempcx = tempax;
6732                    }
6733
6734                    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6735                       tempbx = 1040;
6736                       tempcx = 1042;
6737                    }
6738
6739                 }
6740
6741                 temp = tempbx & 0xff;
6742                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
6743 #endif  /* SIS315H */
6744
6745         }  /* 315/330 series */
6746
6747         /* The following is done for all bridge/chip types/series */
6748
6749         tempax = tempbx & 0xFF00;
6750         tempbx = pushbx;
6751         tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
6752         tempax |= (tempbx & 0xFF00);
6753         temp = (tempax & 0xFF00) >> 8;
6754         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
6755
6756         temp = tempcx & 0x00FF;
6757         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
6758
6759         /* 2. Vertical setup */
6760
6761         tempcx = SiS_Pr->SiS_VGAVT - 1;
6762         temp = tempcx & 0x00FF;
6763
6764         if(HwInfo->jChipType < SIS_661) {
6765            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6766               if(HwInfo->jChipType < SIS_315H) {
6767                  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6768                     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6769                        temp--;
6770                     }
6771                  }
6772               } else {
6773                  temp--;
6774               }
6775            } else if(HwInfo->jChipType >= SIS_315H) {
6776               temp--;
6777            }
6778         }
6779         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
6780
6781         tempbx = SiS_Pr->SiS_VGAVDE - 1;
6782         temp = tempbx & 0x00FF;
6783         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
6784
6785         temp = ((tempbx & 0xFF00) << 3) >> 8;
6786         temp |= ((tempcx & 0xFF00) >> 8);
6787         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
6788
6789         if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6790            tempbx++;
6791            tempax = tempbx;
6792            tempcx++;
6793            tempcx -= tempax;
6794            tempcx >>= 2;
6795            tempbx += tempcx;
6796            if(tempcx < 4) tempcx = 4;
6797            tempcx >>= 2;
6798            tempcx += tempbx;
6799            tempcx++;
6800         } else {
6801            tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6802            tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6803         }
6804
6805         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6806
6807            if(SiS_Pr->UseCustomMode) {
6808               tempbx = SiS_Pr->CVSyncStart;
6809               tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
6810            }
6811
6812            if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6813               unsigned char cr8, cr7, cr13, cr9;
6814               if(SiS_Pr->UseCustomMode) {
6815                  cr8  = SiS_Pr->CCRT1CRTC[8];
6816                  cr7  = SiS_Pr->CCRT1CRTC[7];
6817                  cr13 = SiS_Pr->CCRT1CRTC[13];
6818                  cr9  = SiS_Pr->CCRT1CRTC[9];
6819               } else {
6820                  cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6821                  cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6822                  cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6823                  cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6824               }
6825               tempbx = cr8;
6826               if(cr7 & 0x04)  tempbx |= 0x0100;
6827               if(cr7 & 0x80)  tempbx |= 0x0200;
6828               if(cr13 & 0x08) tempbx |= 0x0400;
6829               tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
6830            }
6831         }
6832         temp = tempbx & 0x00FF;
6833         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
6834
6835         temp = ((tempbx & 0xFF00) >> 8) << 4;
6836         temp |= (tempcx & 0x000F);
6837         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
6838
6839         /* 3. Panel compensation delay */
6840
6841         if(HwInfo->jChipType < SIS_315H) {
6842
6843 #ifdef SIS300  /* ---------- 300 series -------------- */
6844
6845            if(SiS_Pr->SiS_VBType & VB_SISVB) {
6846                 temp = 0x20;
6847
6848                 if(HwInfo->jChipType == SIS_300) {
6849                    temp = 0x10;
6850                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
6851                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
6852                 }
6853                 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6854                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
6855                 }
6856                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
6857                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
6858                 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)            temp = 0x08;
6859                 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6860                    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)      temp = 0x2c;
6861                    else                                         temp = 0x20;
6862                 }
6863                 if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
6864                     if(ROMAddr[0x220] & 0x80) {
6865                         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6866                                 temp = ROMAddr[0x221];
6867                         else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6868                                 temp = ROMAddr[0x222];
6869                         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
6870                                 temp = ROMAddr[0x223];
6871                         else
6872                                 temp = ROMAddr[0x224];
6873                         temp &= 0x3c;
6874                     }
6875                 }
6876                 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6877                    if(SiS_Pr->PDC) {
6878                         temp = SiS_Pr->PDC & 0x3c;
6879                    }
6880                 }
6881            } else {
6882                 temp = 0x20;
6883                 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6884                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
6885                 }
6886                 if((ROMAddr) && SiS_Pr->SiS_UseROM) {
6887                     if(ROMAddr[0x220] & 0x80) {
6888                         temp = ROMAddr[0x220] & 0x3c;
6889                     }
6890                 }
6891                 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6892                    if(SiS_Pr->PDC) {
6893                       temp = SiS_Pr->PDC & 0x3c;
6894                    }
6895                 }
6896            }
6897
6898            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6899
6900 #endif  /* SIS300 */
6901
6902         } else {
6903
6904 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
6905
6906            if(HwInfo->jChipType < SIS_661) {
6907
6908               if(SiS_Pr->SiS_VBType & VB_SISVB) {
6909
6910                  temp = 0x10;
6911                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
6912                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
6913                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
6914                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
6915                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6916                     temp = 0x08;
6917                     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6918                        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  temp = 0x2c;
6919                        else                                     temp = 0x20;
6920                     }
6921                  }
6922                  if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
6923                     tempbl = 0x00;
6924                     if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
6925                        if(HwInfo->jChipType < SIS_330) {
6926                           if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6927                        } else {
6928                           if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
6929                        }
6930                     }
6931                  } else {  /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
6932                     tempbl = 0xF0;
6933                  }
6934                  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {
6935                     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
6936                        if(SiS_Pr->PDC) {
6937                           temp = SiS_Pr->PDC;
6938                           tempbl = 0;
6939                        }
6940                     }
6941                  }
6942
6943               } else {  /* LVDS */
6944
6945                  if(HwInfo->jChipType == SIS_740) {
6946                     temp = 0x03;
6947                  } else {
6948                     temp = 0x00;
6949                  }
6950                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6951                  tempbl = 0xF0;
6952                  if(HwInfo->jChipType == SIS_650) {
6953                     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6954                        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6955                     }
6956                  }
6957
6958                  if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6959                     temp = 0x08;
6960                     tempbl = 0;
6961                     if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
6962                        if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6963                     }
6964                  }
6965               }
6966
6967               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);      /* Panel Link Delay Compensation */
6968
6969            } /* < 661 */
6970
6971            tempax = 0;
6972            if (modeflag & DoubleScanMode) tempax |= 0x80;
6973            if (modeflag & HalfDCLK)       tempax |= 0x40;
6974            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6975
6976 #endif  /* SIS315H */
6977
6978         }
6979
6980      }  /* Slavemode */
6981
6982      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6983
6984         /* For 301BDH with LCD, we set up the Panel Link */
6985         if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
6986
6987             SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
6988                                HwInfo, RefreshRateTableIndex);
6989
6990         } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6991
6992             SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex,
6993                               HwInfo, RefreshRateTableIndex);
6994         }
6995
6996      } else {
6997
6998         if(HwInfo->jChipType < SIS_315H) {
6999
7000            SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
7001                                 HwInfo, RefreshRateTableIndex);
7002         } else {
7003
7004            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
7005               if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7006                   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
7007                                       HwInfo,RefreshRateTableIndex);
7008               }
7009            } else {
7010               SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
7011                                  HwInfo,RefreshRateTableIndex);
7012            }
7013
7014         }
7015
7016      }
7017   } /* LCDA */
7018 }
7019
7020 /*********************************************/
7021 /*         SET PART 2 REGISTER GROUP         */
7022 /*********************************************/
7023
7024 #ifdef SIS315H
7025 static UCHAR *
7026 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
7027 {
7028    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
7029    const UCHAR  *tableptr = NULL;
7030    USHORT a, b, p = 0;
7031
7032    a = SiS_Pr->SiS_VGAHDE;
7033    b = SiS_Pr->SiS_HDE;
7034    if(tabletype) {
7035       a = SiS_Pr->SiS_VGAVDE;
7036       b = SiS_Pr->SiS_VDE;
7037    }
7038
7039    if((HwInfo->jChipType >= SIS_661) && (ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
7040
7041       if(a < b) {
7042          p = ROMAddr[0x278] | (ROMAddr[0x279] << 8);
7043       } else if(a == b) {
7044          p = ROMAddr[0x27a] | (ROMAddr[0x27b] << 8);
7045       } else {
7046          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7047             p = ROMAddr[0x27e] | (ROMAddr[0x27f] << 8);
7048          } else {
7049             p = ROMAddr[0x27c] | (ROMAddr[0x27d] << 8);
7050          }
7051          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7052             if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)      p = ROMAddr[0x280] | (ROMAddr[0x281] << 8);
7053             else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) p = ROMAddr[0x282] | (ROMAddr[0x283] << 8);
7054             else                                         p = ROMAddr[0x284] | (ROMAddr[0x285] << 8);
7055          } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7056             p = ROMAddr[0x286] | (ROMAddr[0x287] << 8);
7057          }
7058          do {
7059             if((ROMAddr[p] | ROMAddr[p+1] << 8) == a) break;
7060             p += 0x42;
7061          } while((ROMAddr[p] | ROMAddr[p+1] << 8) != 0xffff);
7062          if((ROMAddr[p] | ROMAddr[p+1] << 8) == 0xffff) p -= 0x42;
7063       }
7064       p += 2;
7065       return(&ROMAddr[p]);
7066
7067    } else {
7068
7069       if(a < b) {
7070          tableptr = SiS_Part2CLVX_1;
7071       } else if(a == b) {
7072          tableptr = SiS_Part2CLVX_2;
7073       } else {
7074          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7075             tableptr = SiS_Part2CLVX_4;
7076          } else {
7077             tableptr = SiS_Part2CLVX_3;
7078          }
7079          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7080             if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)      tableptr = SiS_Part2CLVX_3;
7081             else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
7082             else                                         tableptr = SiS_Part2CLVX_5;
7083
7084          } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7085             tableptr = SiS_Part2CLVX_6;
7086          }
7087          do {
7088             if((tableptr[p] | tableptr[p+1] << 8) == a) break;
7089             p += 0x42;
7090          } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
7091          if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
7092       }
7093       p += 2;
7094       return((UCHAR *)&tableptr[p]);
7095    }
7096 }
7097
7098
7099 static void
7100 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7101                     USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7102 {
7103    UCHAR *tableptr;
7104    int i, j;
7105    UCHAR temp;
7106
7107    if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
7108
7109    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
7110    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
7111       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
7112    }
7113    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7114       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
7115       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
7116          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
7117       }
7118    }
7119    temp = 0x10;
7120    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
7121    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
7122 }
7123
7124 static void
7125 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
7126                     USHORT RefreshRateTableIndex,USHORT *CRT2Index,
7127                     USHORT *ResIndex,PSIS_HW_INFO HwInfo)
7128 {
7129   USHORT tempbx,tempal;
7130
7131   if(ModeNo <= 0x13)
7132         tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7133   else
7134         tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7135
7136   tempbx = SiS_Pr->SiS_LCDResInfo;
7137
7138   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
7139   else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
7140
7141   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
7142      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
7143         tempbx = 100;
7144         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 101;
7145         else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
7146      }
7147   } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
7148      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
7149         if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7150            tempbx = 103;
7151            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 104;
7152            else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105;
7153         }
7154      }
7155   } else if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
7156      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
7157         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 106;
7158      }
7159   }
7160
7161   *CRT2Index = tempbx;
7162   *ResIndex = tempal & 0x3F;
7163 }
7164 #endif
7165
7166 #ifdef SIS300
7167 /* For ECS A907. Highly preliminary. */
7168 static void
7169 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7170                     USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
7171                     USHORT ModeNo)
7172 {
7173   USHORT crt2crtc, resindex;
7174   int    i,j;
7175   const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
7176
7177   if(HwInfo->jChipType != SIS_300) return;
7178   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
7179   if(SiS_Pr->UseCustomMode) return;
7180
7181   if(ModeNo <= 0x13) {
7182      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7183   } else {
7184      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7185   }
7186
7187   resindex = crt2crtc & 0x3F;
7188   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
7189   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
7190
7191   /* The BIOS code (1.16.51,56) is obviously a fragment! */
7192   if(ModeNo > 0x13) {
7193      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
7194      resindex = 4;
7195   }
7196
7197   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7198   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7199   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7200         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7201   }
7202   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7203         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7204   }
7205   for(j = 0x1f; j <= 0x21; i++, j++ ) {
7206         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7207   }
7208   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7209   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7210 }
7211 #endif
7212
7213 static void
7214 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
7215 {
7216   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
7217   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
7218   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
7219
7220   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7221      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7222         const UCHAR specialtv[] = {
7223                 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
7224                 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
7225                 0x58,0xe4,0x73,0xda,0x13
7226         };
7227         int i, j;
7228         for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
7229            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
7230         }
7231         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
7232         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
7233            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7234               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
7235            } else {
7236               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x15);
7237            }
7238            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
7239         }
7240      }
7241   } else {
7242      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x21);
7243      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x5a);
7244   }
7245 }
7246
7247 static void
7248 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
7249               PSIS_HW_INFO HwInfo)
7250 {
7251   USHORT      i, j, tempax, tempbx, tempcx, temp;
7252   USHORT      push1, push2, modeflag, crt2crtc;
7253   ULONG       longtemp, tempeax;
7254   const       UCHAR *PhasePoint;
7255   const       UCHAR *TimingPoint;
7256 #ifdef SIS315H
7257   USHORT      resindex, CRT2Index;
7258   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
7259 #endif
7260 #ifdef SIS300
7261   const UCHAR atable[] = {
7262        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
7263        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
7264   };
7265 #endif
7266
7267 #ifdef SIS315H   
7268   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7269 #endif
7270
7271   if(ModeNo <= 0x13) {
7272      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7273      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7274   } else {
7275      if(SiS_Pr->UseCustomMode) {
7276         modeflag = SiS_Pr->CModeFlag;
7277         crt2crtc = 0;
7278      } else {
7279         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7280         crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7281      }
7282   }
7283
7284   temp = 0;
7285   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
7286   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
7287   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
7288   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
7289
7290   if(!(SiS_Pr->SiS_TVMode & TVSetPAL))        temp |= 0x10;
7291
7292   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
7293
7294   PhasePoint  = SiS_Pr->SiS_PALPhase;
7295   TimingPoint = SiS_Pr->SiS_PALTiming;
7296
7297   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7298
7299      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
7300      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7301         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
7302         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7303            TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
7304 #if 0
7305            if(!(modeflag & Charx8Dot))  TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
7306 #endif
7307         }
7308      }
7309
7310   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7311
7312      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      TimingPoint = &SiS_YPbPrTable[2][0];
7313      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
7314      else                                         TimingPoint = &SiS_YPbPrTable[0][0];
7315
7316      PhasePoint = SiS_Pr->SiS_NTSCPhase;
7317
7318   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7319
7320      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
7321          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
7322            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
7323         PhasePoint = SiS_Pr->SiS_PALPhase2;
7324      }
7325
7326   } else {
7327
7328      TimingPoint = SiS_Pr->SiS_NTSCTiming;
7329      PhasePoint  = SiS_Pr->SiS_NTSCPhase;
7330      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
7331         PhasePoint = SiS_Pr->SiS_PALPhase;
7332      }
7333
7334      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
7335          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
7336            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
7337         PhasePoint = SiS_Pr->SiS_NTSCPhase2;
7338         if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
7339            PhasePoint = SiS_Pr->SiS_PALPhase2;
7340         }
7341      }
7342
7343   }
7344
7345   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7346      PhasePoint = SiS_Pr->SiS_PALMPhase;
7347      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
7348          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
7349            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
7350         PhasePoint = SiS_Pr->SiS_PALMPhase2;
7351      }
7352   }
7353
7354   if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7355      PhasePoint = SiS_Pr->SiS_PALNPhase;
7356      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
7357          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
7358            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
7359         PhasePoint = SiS_Pr->SiS_PALNPhase2;
7360      }
7361   }
7362
7363   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7364      PhasePoint = SiS_Pr->SiS_SpecialPhase;
7365      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7366         PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
7367      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
7368         PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
7369      }
7370   }
7371
7372   for(i=0x31, j=0; i<=0x34; i++, j++) {
7373      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
7374   }
7375
7376   for(i=0x01, j=0; i<=0x2D; i++, j++) {
7377      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7378   }
7379   for(i=0x39; i<=0x45; i++, j++) {
7380      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7381   }
7382
7383   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7384      if(SiS_Pr->SiS_ModeType != ModeText) {
7385         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7386      }
7387   }
7388
7389   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7390
7391   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7392   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7393   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7394   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7395
7396   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)    tempax = 950;
7397   else if(SiS_Pr->SiS_TVMode & TVSetPAL)        tempax = 520;
7398   else                                          tempax = 440;
7399
7400   if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
7401       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7402         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7403
7404      tempax -= SiS_Pr->SiS_VDE;
7405      tempax >>= 2;
7406      tempax &= 0x00ff;
7407
7408      temp = tempax + (USHORT)TimingPoint[0];
7409      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7410
7411      temp = tempax + (USHORT)TimingPoint[1];
7412      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7413
7414      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7415         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7416            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
7417            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x52);
7418         } else {
7419            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7420            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7421         }
7422      }
7423
7424   }
7425
7426   tempcx = SiS_Pr->SiS_HT;
7427   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7428   tempcx--;
7429   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
7430   temp = tempcx & 0x00FF;
7431   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,temp);
7432   temp = (tempcx & 0xFF00) >> 8;
7433   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
7434
7435   tempcx++;
7436   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx++;
7437   tempcx >>= 1;
7438
7439   push1 = tempcx;
7440
7441   tempcx += 7;
7442   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7443   temp = (tempcx & 0x00FF) << 4;
7444   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
7445
7446   tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
7447   tempbx += tempcx;
7448
7449   temp = tempbx & 0x00FF;
7450   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,temp);
7451   temp = ((tempbx & 0xFF00) >> 8) << 4;
7452   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
7453
7454   tempbx += 8;
7455   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7456      tempbx -= 4;
7457      tempcx = tempbx;
7458   }
7459   temp = (tempbx & 0x00FF) << 4;
7460   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
7461
7462   j += 2;
7463   tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
7464   temp = tempcx & 0x00FF;
7465   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,temp);
7466   temp = ((tempcx & 0xFF00) >> 8) << 4;
7467   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
7468
7469   tempcx += 8;
7470   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7471   temp = (tempcx & 0x00FF) << 4;
7472   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
7473
7474   tempcx = push1;
7475
7476   j += 2;
7477   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7478   temp = (tempcx & 0x00FF) << 4;
7479   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
7480
7481   tempcx -= 11;
7482   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7483      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7484   }
7485   temp = tempcx & 0x00FF;
7486   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,temp);
7487
7488   tempbx = SiS_Pr->SiS_VDE;
7489   if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7490   if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7491   if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7492   if(HwInfo->jChipType < SIS_315H) {
7493      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
7494   } else {
7495      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7496          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7497         tempbx >>= 1;
7498         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7499            if(ModeNo <= 0x13) {
7500               if(crt2crtc == 1) tempbx++;
7501            }
7502         } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7503            if(crt2crtc == 4) {
7504               if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
7505            }
7506         }
7507      }
7508   }
7509   tempbx -= 2;
7510   temp = tempbx & 0x00FF;
7511   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7512      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7513         if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
7514      }
7515   }
7516
7517   if(HwInfo->jChipType < SIS_661) {
7518      /* From 1.10.7w - doesn't make sense */
7519      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7520         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7521            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7522               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
7523                  if(ModeNo == 0x03) temp++;
7524               }
7525            }
7526         }
7527      }
7528   }
7529   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,temp);
7530
7531   temp = (tempcx >> 8) & 0x0F;
7532   temp |= (((tempbx >> 8) << 6) & 0xC0);
7533   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750 | SetCRT2ToSCART))) {
7534      temp |= 0x10;
7535      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x20;
7536   }
7537   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7538
7539   if((HwInfo->jChipType > SIS_315H) && (HwInfo->jChipType < SIS_661)) {
7540      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7541         if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7542            if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
7543                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
7544               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
7545            }
7546         }
7547      }
7548   }
7549
7550   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7551      tempbx = SiS_Pr->SiS_VDE;
7552      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7553         if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7554            tempbx >>= 1;
7555         }
7556      }
7557      tempbx -= 3;
7558      if(HwInfo->jChipType >= SIS_661) {
7559         if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {  /* Why not 301B/LV? */
7560            temp = 0;
7561            if(tempcx & 0x0400) temp |= 0x20;
7562            if(tempbx & 0x0400) temp |= 0x40;
7563            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x10,temp);
7564         }
7565      }
7566      tempbx &= 0x03ff;
7567      temp = ((tempbx & 0xFF00) >> 8) << 5;
7568      temp |= 0x18;
7569      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7570      temp = tempbx & 0x00FF;
7571      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,temp);
7572
7573   }
7574
7575   tempbx = 0;
7576   if(!(modeflag & HalfDCLK)) {
7577      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7578         tempax = 0;
7579         tempbx |= 0x2000;
7580      }
7581   }
7582
7583   tempcx = 0x0101;
7584   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7585      if(SiS_Pr->SiS_VGAHDE >= 1024) {
7586         if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7587            tempcx = 0x1920;
7588            if(SiS_Pr->SiS_VGAHDE >= 1280) {
7589               tempcx = 0x1420;
7590               tempbx &= ~0x2000;
7591            }
7592         }
7593      }
7594   }
7595
7596   if(!(tempbx & 0x2000)) {
7597      if(modeflag & HalfDCLK) {
7598         tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
7599      }
7600      longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
7601      longtemp <<= 13;
7602      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7603         longtemp <<= 3;
7604      }
7605      tempeax = longtemp / SiS_Pr->SiS_HDE;
7606      if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
7607      tempax = (USHORT)tempeax;
7608      tempbx |= (tempax & 0x1F00);
7609      tempcx = (tempax & 0xFF00) >> (8 + 5);
7610   }
7611
7612   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7613   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,(tempbx >> 8));
7614
7615   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7616
7617      temp = tempcx & 0x0007;
7618      if(tempbx & 0x2000) temp = 0;
7619      if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
7620         temp |= 0x18;
7621      }
7622      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
7623
7624      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7625         tempbx = 0x0382;
7626         tempcx = 0x007e;
7627      } else {
7628         tempbx = 0x0369;
7629         tempcx = 0x0061;
7630      }
7631      temp = (tempbx & 0x00FF) ;
7632      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,temp);
7633      temp = (tempcx & 0x00FF) ;
7634      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,temp);
7635      temp = (tempcx & 0x0300) >> (8 - 2);
7636      temp |= ((tempbx >> 8) & 0x03);
7637      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7638         temp |= 0x10;
7639         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7640         else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7641      }
7642      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7643
7644      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7645      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
7646
7647      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7648
7649      if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7650         temp = 0;
7651         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7652         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7653      }
7654
7655   }
7656
7657   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7658      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7659         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7660         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
7661      }
7662      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7663   }
7664
7665   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7666      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7667         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7668      }
7669   }
7670
7671   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7672
7673   /* From here: Part2 LCD setup */
7674
7675   tempbx = SiS_Pr->SiS_HDE;
7676   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7677   tempbx--;                                     /* RHACTE = HDE - 1 */
7678   temp = tempbx & 0x00FF;
7679   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,temp);
7680   temp = (tempbx & 0xFF00) >> 4;
7681   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
7682
7683   temp = 0x01;
7684   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
7685      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7686         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7687            temp = 0x02;
7688            if(HwInfo->jChipType >= SIS_315H) {
7689               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7690                  temp = 0x01;
7691               }
7692            }
7693         }
7694      }
7695   }
7696   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7697
7698   tempbx = SiS_Pr->SiS_VDE - 1;
7699   temp = tempbx & 0x00FF;
7700   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,temp);
7701   temp = ((tempbx & 0xFF00) >> 8) & 0x07;
7702   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
7703
7704   tempcx = SiS_Pr->SiS_VT - 1;
7705   temp = tempcx & 0x00FF;
7706   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,temp);
7707
7708   temp = ((tempcx & 0xFF00) >> 8) << 5;
7709
7710   /* Enable dithering; only do this for 32bpp mode */
7711   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7712      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7713         temp |= 0x10;
7714      }
7715   }
7716
7717   /* Must do special for Compaq1280; Acer1280 OK, Clevo1400 OK, COMPAL1400 OK */
7718   /* Compaq1280 panel loses sync if using CR37 sync info. */
7719   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
7720      if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7721         if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
7722            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
7723            if(SiS_Pr->SiS_LCDInfo & LCDSync) {
7724               temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
7725            }
7726         } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
7727                   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) {
7728            temp |= 0x03;
7729         } else {
7730            temp |= (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) >> 6);
7731            temp |= 0x08;
7732            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04;
7733         }
7734      } else {
7735         if(SiS_Pr->SiS_LCDInfo & LCDSync) {
7736            temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
7737         }
7738      }
7739   }
7740
7741   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1A,temp);
7742
7743   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7744   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7745
7746   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7747   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7748
7749 #if 0  /* Use the 315/330 series code for now */
7750   if((HwInfo->jChipType >= SIS_661)          &&
7751      (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
7752      (ROMAddr && SiS_Pr->SiS_UseROM)) {
7753
7754       /* This is done for the LVDS bridges only, since
7755        * the TMDS panels already work correctly with
7756        * the old code. Besides, we only do that if
7757        * we can get the data from the ROM, I am tired
7758        * of carrying a lot of tables around.
7759        */
7760
7761 #ifdef SIS315H                                                  /* ------------ 661/741/760 series --------- */
7762       UCHAR *myptr = NULL, myptr1 = NULL;
7763
7764       myptr = (UCHAR *)GetLCDPtr661(SiS_Pr, HwInfo, 6, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7765       myptr1 = (UCHAR *)GetLCDStructPtr661(SiS_Pr, HwInfo);
7766
7767       tempbx = (myptr[3] | (myptr[4] << 8)) & 0x0fff;
7768       tempcx = SiS_Pr->PanelYRes;
7769       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7770          tempcx = SiS_Pr->SiS_VDE;
7771       }
7772
7773       tempcx += tempbx;
7774       if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
7775
7776       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempbx);
7777       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempcx);
7778
7779       tempcx &= 0x07ff;
7780       tempbx &= 0x07ff;
7781       temp = (tempcx >> 8) << 3;
7782       temp |= (tempbx >> 8);
7783       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7784
7785       tempbx = (myptr[4] | (myptr[5] << 8)) >> 4;
7786       tempcx = myptr1[6];
7787       if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = myptr[7];
7788
7789       tempcx += tempbx;
7790       if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
7791
7792       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);
7793       temp = tempcx & 0x000f;
7794       temp |= ((tempbx & 0x0f00) >> 4);
7795       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7796
7797       tempax = SiS_Pr->SiS_HT;
7798       tempbx = (myptr[0] | (myptr[1] << 8)) & 0x0fff;
7799       tempcx = SiS_Pr->PanelXRes;
7800       if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = SiS_Pr->SiS_HDE;
7801
7802       if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7803          tempax >>= 1;
7804          tempbx >>= 1;
7805          tempcx >>= 1;
7806       }
7807       if(SiS_Pr->SiS_VBType & VB_SIS302LV)                 tempbx++;
7808       if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) tempbx++;
7809
7810       tempcx += tempbx;
7811       if(tempcx >= tempax) tempcx -= tempax;
7812
7813       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,tempbx);
7814       temp = ((tempbx & 0xff00) >> 8) << 4;
7815       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,temp);
7816       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempcx);
7817       temp = tempcx >> 8;
7818       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x25,temp);
7819
7820       tempax = SiS_Pr->SiS_HT;
7821       tempbx = (myptr[1] | (myptr[2] << 8)) >> 4;
7822       tempcx = myptr1[5];
7823       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7824          tempcx = myptr[6];
7825       }
7826       if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7827          tempax >>= 1;
7828          tempbx >>= 1;
7829          tempcx >>= 1;
7830       }
7831       if(SiS_Pr->SiS_VBType & VB_SIS302LV) tempbx++;
7832
7833       tempcx += tempbx;
7834       if(tempcx >= tempax) tempcx -= tempax;
7835
7836       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,tempbx);
7837       temp = (tempbx & 0x0f00) >> 4;
7838       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1d,0x0f,temp);
7839       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempcx);
7840
7841       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
7842          if(SiS_Pr->SiS_VGAVDE == 525) {
7843             temp = 0xc3;
7844             if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7845                temp++;
7846                if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
7847             }
7848             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
7849             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
7850          } else if(SiS_Pr->SiS_VGAVDE == 420) {
7851             temp = 0x4d;
7852             if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7853                temp++;
7854                if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
7855             }
7856             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
7857          }
7858       }
7859
7860 #endif
7861
7862   } else
7863 #endif
7864          if((HwInfo->jChipType >= SIS_315H)                    &&
7865             (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
7866             ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
7867              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
7868              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
7869              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
7870
7871 #ifdef SIS315H                                                  /* ------------- 315/330 series ------------ */
7872
7873       SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7874                           &CRT2Index, &resindex, HwInfo);
7875
7876       switch(CRT2Index) {
7877         case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
7878         case Panel_1280x1024     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
7879         case Panel_1400x1050     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
7880         case Panel_1600x1200     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
7881         case Panel_1024x768  + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
7882         case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
7883         case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
7884         case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
7885         case Panel_1024x768  + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
7886         case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
7887         case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
7888         case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
7889         case 100:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break;  /* Custom */
7890         case 101:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
7891         case 102:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
7892         case 103:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_1; break;    /* Custom */
7893         case 104:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_2; break;
7894         case 105:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_3; break;
7895         case 106:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Asus1024x768_3; break;
7896         default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
7897       }
7898
7899       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7900       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7901       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7902         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7903       }
7904       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7905         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7906       }
7907       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7908         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7909       }
7910       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7911       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7912
7913       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
7914         if(SiS_Pr->SiS_VGAVDE == 525) {
7915           temp = 0xc3;
7916           if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7917              temp++;
7918              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
7919           }
7920           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
7921           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
7922         } else if(SiS_Pr->SiS_VGAVDE == 420) {
7923           temp = 0x4d;
7924           if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7925              temp++;
7926              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
7927           }
7928           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
7929         }
7930      }
7931
7932      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7933         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
7934            /* See Sync above, 0x1a */
7935            temp = 1;
7936            if(ModeNo <= 0x13) temp = 3;
7937            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
7938         }
7939      }
7940 #endif
7941
7942   } else {   /* ------ 300 series and other bridges, other LCD resolutions ------ */
7943
7944       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes
7945        * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding,
7946        * the bridge scales all modes to 1024.
7947        * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
7948        */
7949
7950     tempcx = SiS_Pr->SiS_VT;
7951     tempbx = SiS_Pr->PanelYRes;
7952
7953     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7954        tempbx = SiS_Pr->SiS_VDE - 1;
7955        tempcx--;
7956     }
7957
7958     tempax = 1;
7959     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
7960        if(tempbx != SiS_Pr->SiS_VDE) {
7961           tempax = tempbx;
7962           if(tempax < SiS_Pr->SiS_VDE) {
7963              tempax = 0;
7964              tempcx = 0;
7965           } else {
7966              tempax -= SiS_Pr->SiS_VDE;
7967           }
7968           tempax >>= 1;
7969        }
7970        tempcx -= tempax; /* lcdvdes */
7971        tempbx -= tempax; /* lcdvdee */
7972     }
7973
7974     /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7975
7976 #ifdef TWDEBUG
7977     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7978 #endif
7979
7980     temp = tempcx & 0x00FF;                             /* RVEQ1EQ=lcdvdes */
7981     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,temp);
7982     temp = tempbx & 0x00FF;                             /* RVEQ2EQ=lcdvdee */
7983     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,temp);
7984
7985     temp = ((tempbx & 0xFF00) >> 8) << 3;
7986     temp |= ((tempcx & 0xFF00) >> 8);
7987     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7988
7989     tempbx = SiS_Pr->SiS_VT;    /* push2; */
7990     tempax = SiS_Pr->SiS_VDE;   /* push1; */
7991     tempcx = (tempbx - tempax) >> 4;
7992     tempbx += tempax;
7993     tempbx >>= 1;
7994     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10;
7995
7996     /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
7997
7998     if(SiS_Pr->UseCustomMode) {
7999        tempbx = SiS_Pr->CVSyncStart;
8000     }
8001
8002 #ifdef TWDEBUG
8003     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
8004 #endif
8005
8006     temp = tempbx & 0x00FF;                             /* RTVACTEE = lcdvrs */
8007     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
8008
8009     temp = ((tempbx & 0xFF00) >> 8) << 4;
8010     tempbx += (tempcx + 1);
8011     temp |= (tempbx & 0x000F);
8012
8013     if(SiS_Pr->UseCustomMode) {
8014        temp &= 0xf0;
8015        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
8016     }
8017
8018 #ifdef TWDEBUG
8019     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
8020 #endif
8021
8022     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
8023
8024     /* Code from 630/301B (I+II) BIOS */
8025
8026 #ifdef SIS300
8027     if(!SiS_Pr->UseCustomMode) {
8028        if( ( ( (HwInfo->jChipType == SIS_630) ||
8029                (HwInfo->jChipType == SIS_730) ) &&
8030              (HwInfo->jChipRevision > 2) )  &&
8031            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
8032            (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
8033            (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
8034           if(ModeNo == 0x13) {
8035              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
8036              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
8037              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
8038           } else {
8039              if((crt2crtc & 0x3F) == 4) {
8040                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
8041                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
8042                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
8043                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
8044                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
8045              }
8046           }
8047        }
8048
8049        if(HwInfo->jChipType < SIS_315H) {
8050           if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
8051              crt2crtc &= 0x1f;
8052              tempcx = 0;
8053              if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
8054                 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8055                    tempcx += 7;
8056                 }
8057              }
8058              tempcx += crt2crtc;
8059              if(crt2crtc >= 4) {
8060                 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
8061              }
8062
8063              if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
8064                 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8065                    if(crt2crtc == 4) {
8066                       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
8067                    }
8068                 }
8069              }
8070              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
8071              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
8072           }
8073        }
8074     }
8075 #endif
8076
8077     tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
8078     tempbx = SiS_Pr->SiS_HDE + 7;                         /* lcdhdee         */
8079     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8080        tempbx += 2;
8081     }
8082     push1 = tempbx;
8083
8084 #ifdef TWDEBUG
8085     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
8086 #endif
8087
8088     temp = tempbx & 0x00FF;                               /* RHEQPLE = lcdhdee */
8089     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,temp);
8090     temp = (tempbx & 0xFF00) >> 8;
8091     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
8092
8093     temp = 7;
8094     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8095        temp += 2;
8096     }
8097     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);          /* RHBLKE = lcdhdes[7:0] */
8098     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);       /* lcdhdes [11:8] */
8099
8100     tempbx += tempcx;
8101     push2 = tempbx;
8102
8103     if(SiS_Pr->UseCustomMode) {
8104        tempbx = SiS_Pr->CHSyncStart + 7;
8105        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8106           tempbx += 2;
8107        }
8108     }
8109
8110 #ifdef TWDEBUG
8111     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
8112 #endif
8113
8114     temp = tempbx & 0x00FF;                               /* RHBURSTS = lcdhrs */
8115     if(!SiS_Pr->UseCustomMode) {
8116        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
8117           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
8118              if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
8119           }
8120        }
8121     }
8122     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,temp);
8123     temp = (tempbx & 0x0F00) >> 4;
8124     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
8125
8126     tempbx = push2;
8127     tempcx <<= 1;
8128     tempbx += tempcx;
8129
8130     if(SiS_Pr->UseCustomMode) {
8131        tempbx = SiS_Pr->CHSyncEnd + 7;
8132        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8133           tempbx += 2;
8134        }
8135     }
8136
8137 #ifdef TWDEBUG
8138     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
8139 #endif
8140
8141     temp = tempbx & 0x00FF;                               /* RHSYEXP2S = lcdhre */
8142     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,temp);
8143
8144     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
8145        if(SiS_Pr->SiS_VGAVDE == 525) {
8146           if(SiS_Pr->SiS_ModeType <= ModeVGA)
8147              temp=0xC6;
8148           else
8149              temp=0xC3;
8150           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
8151           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xB3);
8152        } else if(SiS_Pr->SiS_VGAVDE == 420) {
8153           if(SiS_Pr->SiS_ModeType <= ModeVGA)
8154              temp=0x4F;
8155           else
8156              temp=0x4D;
8157           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
8158        }
8159     }
8160
8161 #ifdef SIS300
8162     SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
8163                         RefreshRateTableIndex, ModeNo);
8164 #endif
8165
8166   } /* HwInfo */
8167 }
8168
8169 /*********************************************/
8170 /*         SET PART 3 REGISTER GROUP         */
8171 /*********************************************/
8172
8173 static void
8174 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8175               PSIS_HW_INFO HwInfo)
8176 {
8177   USHORT modeflag, i;
8178   const UCHAR  *tempdi;
8179
8180   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
8181
8182   if(ModeNo<=0x13) {
8183      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8184   } else {
8185      if(SiS_Pr->UseCustomMode) {
8186         modeflag = SiS_Pr->CModeFlag;
8187      } else {
8188         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8189      }
8190   }
8191
8192 #ifndef SIS_CP
8193   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
8194 #endif
8195
8196 #ifdef SIS_CP
8197   SIS_CP_INIT301_CP
8198 #endif
8199
8200   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8201      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
8202      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
8203   } else {
8204      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
8205      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
8206   }
8207
8208   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8209      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
8210      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
8211      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
8212   }
8213
8214   tempdi = NULL;
8215   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
8216      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
8217      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
8218         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
8219 #if 0
8220         if(!(modeflag & Charx8Dot)) {
8221            tempdi = SiS_Pr->SiS_HiTVGroup3Text;
8222         }
8223 #endif
8224      }
8225   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
8226      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
8227         tempdi = SiS_HiTVGroup3_1;
8228         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
8229      }
8230   }
8231   if(tempdi) {
8232      for(i=0; i<=0x3E; i++){
8233         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
8234      }
8235      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
8236         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
8237            SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
8238         }
8239      }
8240   }
8241
8242   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) {
8243 #ifdef SIS_CP
8244      SIS_CP_INIT301_CP2
8245 #endif
8246   }
8247 }
8248
8249 /*********************************************/
8250 /*         SET PART 4 REGISTER GROUP         */
8251 /*********************************************/
8252
8253 #ifdef SIS315H
8254 static void
8255 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8256 {
8257    USHORT temp, temp1;
8258
8259    if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
8260
8261    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
8262    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
8263    if(!(temp & 0x01)) {
8264       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
8265       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
8266       if(HwInfo->jChipType < SIS_661) {
8267          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
8268       }
8269       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
8270       temp = 0;
8271       if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)) {
8272          temp |= 0x0002;
8273          if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)) {
8274             temp ^= 0x0402;
8275             if(!(SiS_Pr->SiS_TVMode & TVSetHiVision)) {
8276                temp ^= 0x0002;
8277             }
8278          }
8279       }
8280       if(HwInfo->jChipType >= SIS_661) {
8281          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
8282          if(temp1 & 0x01) temp |= 0x10;
8283          if(temp1 & 0x02) temp |= 0x01;
8284          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xec,(temp & 0xff));
8285       } else {
8286          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
8287          if(temp1 == 0x01) temp |= 0x01;
8288          if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
8289          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xea,(temp & 0xff));
8290       }
8291       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
8292    }
8293 }
8294 #endif
8295
8296 static void
8297 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8298                  USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8299 {
8300   USHORT vclkindex;
8301   USHORT temp, reg1, reg2;
8302
8303   if(SiS_Pr->UseCustomMode) {
8304      reg1 = SiS_Pr->CSR2B;
8305      reg2 = SiS_Pr->CSR2C;
8306   } else {
8307      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8308                                  HwInfo);
8309      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
8310      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
8311   }
8312
8313   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8314      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
8315         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
8316         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
8317         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
8318      } else {
8319         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
8320         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
8321      }
8322   } else {
8323      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
8324      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
8325      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
8326   }
8327   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
8328   temp = 0x08;
8329   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
8330   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
8331 }
8332
8333 /* Set 301 VGA2 registers */
8334 static void
8335 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8336               USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8337 {
8338   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
8339   ULONG tempebx,tempeax,templong;
8340
8341   if(ModeNo <= 0x13) {
8342      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8343      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
8344   } else {
8345      if(SiS_Pr->UseCustomMode) {
8346         modeflag = SiS_Pr->CModeFlag;
8347         resinfo = 0;
8348      } else {
8349         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8350         resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
8351      }
8352   }
8353
8354   if(HwInfo->jChipType >= SIS_315H) {
8355      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
8356         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
8357            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
8358         }
8359      }
8360   }
8361
8362   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
8363      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8364         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
8365      }
8366   }
8367
8368   if(HwInfo->jChipType >= SIS_315H) {
8369      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
8370         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
8371            if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
8372               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
8373            }
8374 #ifdef SET_EMI
8375            if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
8376               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
8377               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
8378               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
8379            }
8380 #endif
8381         }
8382         return;
8383      }
8384   }
8385
8386   temp = SiS_Pr->SiS_RVBHCFACT;
8387   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,temp);
8388
8389   tempbx = SiS_Pr->SiS_RVBHCMAX;
8390   temp = tempbx & 0x00FF;
8391   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,temp);
8392
8393   temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
8394
8395   tempcx = SiS_Pr->SiS_VGAHT - 1;
8396   temp = tempcx & 0x00FF;
8397   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,temp);
8398
8399   temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
8400   temp2 |= temp;
8401
8402   tempcx = SiS_Pr->SiS_VGAVT - 1;
8403   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
8404
8405   temp = tempcx & 0x00FF;
8406   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,temp);
8407
8408   temp = temp2 | ((tempcx & 0xFF00) >> 8);
8409   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
8410
8411   tempbx = SiS_Pr->SiS_VGAHDE;
8412   if(modeflag & HalfDCLK)  tempbx >>= 1;
8413   if(HwInfo->jChipType >= SIS_661) {
8414      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
8415   }
8416
8417   temp = 0xA0;
8418   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
8419      temp = 0;
8420      if(tempbx > 800) {
8421         temp = 0xA0;
8422         if(tempbx != 1024) {
8423            temp = 0xC0;
8424            if(tempbx != 1280) temp = 0;
8425         }
8426      }
8427   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8428      if(tempbx <= 800) {
8429         temp = 0x80;
8430      }
8431   } else {
8432      temp = 0x80;
8433      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8434         temp = 0;
8435         if(tempbx > 800) temp = 0x60;
8436      }
8437   }
8438
8439   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
8440      temp = 0;
8441      if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
8442   }
8443
8444   if(HwInfo->jChipType < SIS_661) {
8445      if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp = 0;
8446   }
8447
8448   if(SiS_Pr->SiS_VBType & VB_SIS301) {
8449      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
8450         temp |= 0x0A;
8451   }
8452
8453   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
8454
8455   tempebx = SiS_Pr->SiS_VDE;
8456
8457   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
8458      if(!(temp & 0xE0)) tempebx >>=1;
8459   }
8460
8461   tempcx = SiS_Pr->SiS_RVBHRS;
8462   temp = tempcx & 0x00FF;
8463   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,temp);
8464
8465   tempeax = SiS_Pr->SiS_VGAVDE;
8466   tempcx |= 0x4000;
8467   if(tempeax <= tempebx) {
8468      tempcx ^= 0x4000;
8469   } else {
8470      tempeax -= tempebx;
8471   }
8472
8473   templong = (tempeax * 256 * 1024) % tempebx;
8474   tempeax = (tempeax * 256 * 1024) / tempebx;
8475   tempebx = tempeax;
8476   if(templong != 0) tempebx++;
8477
8478   temp = (USHORT)(tempebx & 0x000000FF);
8479   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
8480   temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
8481   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
8482
8483   tempbx = (USHORT)(tempebx >> 16);
8484   temp = tempbx & 0x00FF;
8485   temp <<= 4;
8486   temp |= ((tempcx & 0xFF00) >> 8);
8487   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
8488
8489   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8490
8491      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
8492
8493      tempbx = 0;
8494      tempax = SiS_Pr->SiS_VGAHDE;
8495      if(modeflag & HalfDCLK)            tempax >>= 1;
8496      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
8497      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8498         if(tempax > 800) tempax -= 800;
8499      } else {
8500         if(tempax > 800) {
8501            tempbx = 8;
8502            if(tempax == 1024)
8503               tempax *= 25;
8504            else
8505               tempax *= 20;
8506
8507            temp = tempax % 32;
8508            tempax /= 32;
8509            tempax--;
8510            if (temp!=0) tempax++;
8511         }
8512      }
8513      tempax--;
8514      temp = ((tempax & 0xFF00) >> 8) & 0x03;
8515      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                     /* From 1.10.7w */
8516         if(ModeNo > 0x13) {                                     /* From 1.10.7w */
8517            if(resinfo == SIS_RI_1024x768) tempax = 0x1f;        /* From 1.10.7w */
8518         }                                                       /* From 1.10.7w */
8519      }                                                          /* From 1.10.7w */
8520      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
8521      temp <<= 4;
8522      temp |= tempbx;
8523      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
8524
8525      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
8526         if(IS_SIS550650740660) {
8527            temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
8528         } else {
8529            temp = 0x0036;
8530         }
8531      } else {
8532         temp = 0x0036;
8533      }
8534      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8535         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
8536            temp |= 0x01;
8537            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8538               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
8539                  temp &= 0xFE;
8540               }
8541            }
8542         }
8543      }
8544      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
8545
8546      tempbx = SiS_Pr->SiS_HT;
8547      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
8548      tempbx >>= 1;
8549      tempbx -= 2;
8550      temp = ((tempbx & 0x0700) >> 8) << 3;
8551      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
8552      temp = tempbx & 0x00FF;
8553      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,temp);
8554
8555      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
8556         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8557            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
8558            /* LCD-too-dark-error-source, see FinalizeLCD() */
8559         }
8560         if(HwInfo->jChipType >= SIS_315H) {
8561            if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
8562               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
8563            }
8564         }
8565 #ifdef SET_EMI
8566         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
8567            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
8568            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
8569            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
8570         }
8571 #endif
8572      }
8573
8574   }  /* 301B */
8575
8576   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8577 }
8578
8579 /*********************************************/
8580 /*         SET PART 5 REGISTER GROUP         */
8581 /*********************************************/
8582
8583 /* Set 301 Palette address port registers */
8584 static void
8585 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8586               PSIS_HW_INFO HwInfo)
8587 {
8588
8589   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
8590
8591   if(SiS_Pr->SiS_ModeType == ModeVGA) {
8592      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
8593         SiS_EnableCRT2(SiS_Pr);
8594         SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8595      }
8596   }
8597 }
8598
8599 /*********************************************/
8600 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
8601 /*********************************************/
8602
8603 static void
8604 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8605                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8606 {
8607   USHORT tempah,i,modeflag,j;
8608   USHORT ResIndex,DisplayType;
8609   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
8610
8611   if(ModeNo <= 0x13) {
8612      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8613   } else {
8614      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8615   }
8616
8617   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8618      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8619      (SiS_Pr->SiS_CustomT == CUT_PANEL848))
8620      return;
8621
8622   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8623                           &ResIndex, &DisplayType))) return;
8624
8625   if(HwInfo->jChipType < SIS_315H) {
8626      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8627   }
8628
8629   switch(DisplayType) {
8630     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
8631     case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
8632     case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
8633     case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
8634     case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
8635     case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
8636     case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
8637     case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
8638     case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
8639     case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
8640     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
8641     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
8642     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
8643     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
8644     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
8645     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
8646     case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
8647     case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
8648     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
8649     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
8650     case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
8651     case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
8652     case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
8653     case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
8654     case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
8655     case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
8656     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
8657     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
8658     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
8659     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
8660     case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
8661     case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
8662     case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
8663     case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
8664     case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
8665     case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1;          break;
8666     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
8667     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
8668     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
8669     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
8670     case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
8671     case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
8672     case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
8673     case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
8674     case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
8675     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
8676     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
8677   }
8678
8679   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
8680
8681   tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8682   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8683
8684   for(i=0x02,j=1;i<=0x05;i++,j++){
8685     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8686     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8687   }
8688   for(i=0x06,j=5;i<=0x07;i++,j++){
8689     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8690     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8691   }
8692   for(i=0x10,j=7;i<=0x11;i++,j++){
8693     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8694     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8695   }
8696   for(i=0x15,j=9;i<=0x16;i++,j++){
8697     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8698     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8699   }
8700   for(i=0x0A,j=11;i<=0x0C;i++,j++){
8701     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8702     SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8703   }
8704
8705   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8706   tempah &= 0xE0;
8707   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8708
8709   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8710   tempah &= 0x01;
8711   tempah <<= 5;
8712   if(modeflag & DoubleScanMode)  tempah |= 0x080;
8713   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8714
8715   /* 650/LVDS BIOS - doesn't make sense */
8716   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8717      if(modeflag & HalfDCLK)
8718         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8719   }
8720 }
8721
8722 /*********************************************/
8723 /*              SET CRT2 ECLK                */
8724 /*********************************************/
8725
8726 static void
8727 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8728            USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8729 {
8730   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
8731   USHORT clkbase, vclkindex=0;
8732   UCHAR  sr2b, sr2c;
8733
8734   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
8735         SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8736         if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
8737            RefreshRateTableIndex--;
8738         }
8739         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8740                                     RefreshRateTableIndex, HwInfo);
8741         SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8742   } else {
8743         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8744                                     RefreshRateTableIndex, HwInfo);
8745   }
8746
8747   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8748   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8749
8750   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8751      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
8752         if(ROMAddr[0x220] & 0x01) {
8753            sr2b = ROMAddr[0x227];
8754            sr2c = ROMAddr[0x228];
8755         }
8756      }
8757   }
8758
8759   clkbase = 0x02B;
8760   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8761      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8762         clkbase += 3;
8763      }
8764   }
8765
8766   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
8767   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8768   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8769   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8770   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8771   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8772   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8773   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8774   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8775   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8776 }
8777
8778 /*********************************************/
8779 /*           SET UP CHRONTEL CHIPS           */
8780 /*********************************************/
8781
8782 static void
8783 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8784                USHORT RefreshRateTableIndex)
8785 {
8786   USHORT temp, tempbx, tempcl;
8787   USHORT TVType, resindex;
8788   const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8789
8790   if(ModeNo <= 0x13)
8791         tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8792   else
8793         tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8794
8795   TVType = 0;
8796   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8797   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8798         TVType += 2;
8799         if(SiS_Pr->SiS_ModeType > ModeVGA) {
8800            if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8801         }
8802         if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8803                 TVType = 4;
8804                 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8805         } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8806                 TVType = 6;
8807                 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8808         }
8809   }
8810   switch(TVType) {
8811         case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8812         case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8813         case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8814         case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8815         case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8816         case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8817         case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8818         case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8819         case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8820         default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8821   }
8822   resindex = tempcl & 0x3F;
8823
8824   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8825
8826 #ifdef SIS300
8827
8828      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8829
8830      /* We don't support modes >800x600 */
8831      if (resindex > 5) return;
8832
8833      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8834         SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8835         SiS_SetCH700x(SiS_Pr,0x6909);   /* Black level for PAL (105)*/
8836      } else {
8837         SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8838         SiS_SetCH700x(SiS_Pr,0x7109);   /* Black level for NTSC (113)*/
8839      }
8840
8841      temp = CHTVRegData[resindex].Reg[0];
8842      tempbx=((temp&0x00FF)<<8)|0x00;    /* Mode register */
8843      SiS_SetCH700x(SiS_Pr,tempbx);
8844      temp = CHTVRegData[resindex].Reg[1];
8845      tempbx=((temp&0x00FF)<<8)|0x07;    /* Start active video register */
8846      SiS_SetCH700x(SiS_Pr,tempbx);
8847      temp = CHTVRegData[resindex].Reg[2];
8848      tempbx=((temp&0x00FF)<<8)|0x08;    /* Position overflow register */
8849      SiS_SetCH700x(SiS_Pr,tempbx);
8850      temp = CHTVRegData[resindex].Reg[3];
8851      tempbx=((temp&0x00FF)<<8)|0x0A;    /* Horiz Position register */
8852      SiS_SetCH700x(SiS_Pr,tempbx);
8853      temp = CHTVRegData[resindex].Reg[4];
8854      tempbx=((temp&0x00FF)<<8)|0x0B;    /* Vertical Position register */
8855      SiS_SetCH700x(SiS_Pr,tempbx);
8856
8857      /* Set minimum flicker filter for Luma channel (SR1-0=00),
8858                 minimum text enhancement (S3-2=10),
8859                 maximum flicker filter for Chroma channel (S5-4=10)
8860                 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8861       */
8862      SiS_SetCH700x(SiS_Pr,0x2801);
8863
8864      /* Set video bandwidth
8865             High bandwith Luma composite video filter(S0=1)
8866             low bandwith Luma S-video filter (S2-1=00)
8867             disable peak filter in S-video channel (S3=0)
8868             high bandwidth Chroma Filter (S5-4=11)
8869             =00110001=0x31
8870      */
8871      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
8872
8873      /* Register 0x3D does not exist in non-macrovision register map
8874             (Maybe this is a macrovision register?)
8875       */
8876 #ifndef SIS_CP
8877      SiS_SetCH70xx(SiS_Pr,0x003D);
8878 #endif
8879
8880      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8881             all other bits a read-only. Macrovision?
8882       */
8883      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8884
8885      /* Register 0x11 only contains 3 writable bits (S0-S2) for
8886             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8887       */
8888      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8889
8890      /* Clear DSEN
8891       */
8892      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8893
8894      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {             /* ---- NTSC ---- */
8895        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8896          if(resindex == 0x04) {                         /* 640x480 overscan: Mode 16 */
8897            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8898            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
8899          } else if(resindex == 0x05) {                  /* 800x600 overscan: Mode 23 */
8900            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);      /* 0x18-0x1f: FSCI 469,762,048 */
8901            SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8902            SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8903            SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8904            SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8905            SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8906            SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8907            SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8908            SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);       /* Loop filter on for mode 23 */
8909            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
8910          }
8911        } else {
8912          if(resindex == 0x04) {                          /* ----- 640x480 underscan; Mode 17 */
8913            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off */
8914            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8915          } else if(resindex == 0x05) {                   /* ----- 800x600 underscan: Mode 24 */
8916 #if 0
8917            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8918            SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);       /* FSCI for mode 24 is 428,554,851 */
8919            SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);       /* 198b3a63 */
8920            SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8921            SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8922            SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8923            SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8924            SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8925            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off for mode 24 */
8926            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
8927 #endif     /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8928            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off */
8929            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8930          }
8931        }
8932      } else {                                           /* ---- PAL ---- */
8933            /* We don't play around with FSCI in PAL mode */
8934          if(resindex == 0x04) {
8935            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8936            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8937          } else {
8938            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8939            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8940          }
8941      }
8942      
8943 #endif  /* 300 */
8944
8945   } else {
8946
8947      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8948
8949 #ifdef SIS315H
8950
8951      /* We don't support modes >1024x768 */
8952      if (resindex > 6) return;
8953
8954      temp = CHTVRegData[resindex].Reg[0];
8955      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8956         temp |= 0x10;
8957      }
8958      tempbx=((temp & 0x00FF) << 8) | 0x00;
8959      SiS_SetCH701x(SiS_Pr,tempbx);
8960
8961      temp = CHTVRegData[resindex].Reg[1];
8962      tempbx=((temp & 0x00FF) << 8) | 0x01;
8963      SiS_SetCH701x(SiS_Pr,tempbx);
8964
8965      temp = CHTVRegData[resindex].Reg[2];
8966      tempbx=((temp & 0x00FF) << 8) | 0x02;
8967      SiS_SetCH701x(SiS_Pr,tempbx);
8968
8969      temp = CHTVRegData[resindex].Reg[3];
8970      tempbx=((temp & 0x00FF) << 8) | 0x04;
8971      SiS_SetCH701x(SiS_Pr,tempbx);
8972
8973      temp = CHTVRegData[resindex].Reg[4];
8974      tempbx=((temp & 0x00FF) << 8) | 0x03;
8975      SiS_SetCH701x(SiS_Pr,tempbx);
8976
8977      temp = CHTVRegData[resindex].Reg[5];
8978      tempbx=((temp & 0x00FF) << 8) | 0x05;
8979      SiS_SetCH701x(SiS_Pr,tempbx);
8980
8981      temp = CHTVRegData[resindex].Reg[6];
8982      tempbx=((temp & 0x00FF) << 8) | 0x06;
8983      SiS_SetCH701x(SiS_Pr,tempbx);
8984
8985      temp = CHTVRegData[resindex].Reg[7];
8986      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8987         temp = 0x66;
8988      }
8989      tempbx=((temp & 0x00FF) << 8) | 0x07;
8990      SiS_SetCH701x(SiS_Pr,tempbx);
8991
8992      temp = CHTVRegData[resindex].Reg[8];
8993      tempbx=((temp & 0x00FF) << 8) | 0x08;
8994      SiS_SetCH701x(SiS_Pr,tempbx);
8995
8996      temp = CHTVRegData[resindex].Reg[9];
8997      tempbx=((temp & 0x00FF) << 8) | 0x15;
8998      SiS_SetCH701x(SiS_Pr,tempbx);
8999
9000      temp = CHTVRegData[resindex].Reg[10];
9001      tempbx=((temp & 0x00FF) << 8) | 0x1f;
9002      SiS_SetCH701x(SiS_Pr,tempbx);
9003
9004      temp = CHTVRegData[resindex].Reg[11];
9005      tempbx=((temp & 0x00FF) << 8) | 0x0c;
9006      SiS_SetCH701x(SiS_Pr,tempbx);
9007
9008      temp = CHTVRegData[resindex].Reg[12];
9009      tempbx=((temp & 0x00FF) << 8) | 0x0d;
9010      SiS_SetCH701x(SiS_Pr,tempbx);
9011
9012      temp = CHTVRegData[resindex].Reg[13];
9013      tempbx=((temp & 0x00FF) << 8) | 0x0e;
9014      SiS_SetCH701x(SiS_Pr,tempbx);
9015
9016      temp = CHTVRegData[resindex].Reg[14];
9017      tempbx=((temp & 0x00FF) << 8) | 0x0f;
9018      SiS_SetCH701x(SiS_Pr,tempbx);
9019
9020      temp = CHTVRegData[resindex].Reg[15];
9021      tempbx=((temp & 0x00FF) << 8) | 0x10;
9022      SiS_SetCH701x(SiS_Pr,tempbx);
9023
9024      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
9025      /* D1 should be set for PAL, PAL-N and NTSC-J,
9026         but I won't do that for PAL unless somebody
9027         tells me to do so. Since the BIOS uses
9028         non-default CIV values and blacklevels,
9029         this might be compensated anyway.
9030       */
9031      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
9032      SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
9033
9034 #endif  /* 315 */
9035
9036   }
9037
9038 #ifdef SIS_CP
9039   SIS_CP_INIT301_CP3
9040 #endif
9041
9042 }
9043
9044 void
9045 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9046 {
9047   USHORT temp;
9048
9049   /* Enable Chrontel 7019 LCD panel backlight */
9050   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
9051      if(HwInfo->jChipType == SIS_740) {
9052         SiS_SetCH701x(SiS_Pr,0x6566);
9053      } else {
9054         temp = SiS_GetCH701x(SiS_Pr,0x66);
9055         temp |= 0x20;
9056         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
9057      }
9058   }
9059 }
9060
9061 void
9062 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
9063 {
9064   USHORT temp;
9065
9066   /* Disable Chrontel 7019 LCD panel backlight */
9067   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
9068      temp = SiS_GetCH701x(SiS_Pr,0x66);
9069      temp &= 0xDF;
9070      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
9071   }
9072 }
9073
9074 #ifdef SIS315H  /* ----------- 315 series only ---------- */
9075
9076 static void
9077 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9078 {
9079   UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
9080   UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
9081   UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
9082   UCHAR asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
9083   UCHAR asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
9084   UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
9085   UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
9086   UCHAR *tableptr = NULL;
9087   int i;
9088
9089   /* Set up Power up/down timing */
9090
9091   if(HwInfo->jChipType == SIS_740) {
9092      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
9093         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
9094         else                                      tableptr = table1024_740;
9095      } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
9096                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
9097                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
9098         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
9099         else                                      tableptr = table1400_740;
9100      } else return;
9101   } else {
9102      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
9103         tableptr = table1024_650;
9104      } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
9105                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
9106                (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
9107         tableptr = table1400_650;
9108      } else return;
9109   }
9110
9111   for(i=0; i<5; i++) {
9112      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
9113   }
9114 }
9115
9116 static void
9117 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9118 {
9119   UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
9120                             0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
9121   UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
9122                             0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
9123   UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
9124                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
9125   UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
9126                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
9127   UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
9128                             0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
9129   UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
9130                             0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
9131   UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
9132                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
9133   UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
9134                             0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
9135   UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
9136                             0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
9137   UCHAR *tableptr = NULL;
9138   USHORT tempbh;
9139   int i;
9140
9141   if(HwInfo->jChipType == SIS_740) {
9142      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
9143         tableptr = table1024_740;
9144      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
9145         tableptr = table1280_740;
9146      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
9147         tableptr = table1400_740;
9148      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
9149         tableptr = table1600_740;
9150      } else return;
9151   } else {
9152      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
9153         tableptr = table1024_650;
9154      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
9155         tableptr = table1280_650;
9156      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
9157         tableptr = table1400_650;
9158      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
9159         tableptr = table1600_650;
9160      } else return;
9161   }
9162
9163   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
9164   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
9165      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
9166      if(tempbh == 0xc8) {
9167         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) return;
9168      } else if(tempbh == 0xdb) {
9169         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return;
9170         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
9171      } else if(tempbh == 0xde) {
9172         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) return;
9173      }
9174   }
9175
9176   if(HwInfo->jChipType == SIS_740) {
9177      tempbh = 0x0d;
9178   } else {
9179      tempbh = 0x0c;
9180   }
9181   for(i = 0; i < tempbh; i++) {
9182      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
9183   }
9184   SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
9185   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
9186   tempbh |= 0xc0;
9187   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
9188
9189   if(HwInfo->jChipType == SIS_740) {
9190      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
9191      tempbh &= 0xfb;
9192      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
9193      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
9194      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
9195      tempbh |= 0x40;
9196      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
9197      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
9198      tempbh &= 0x3f;
9199      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
9200   }
9201 }
9202
9203 static void
9204 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
9205 {
9206   unsigned char temp, temp1;
9207
9208   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
9209   SiS_SetCH701x(SiS_Pr,0x3e49);
9210   temp = SiS_GetCH701x(SiS_Pr,0x47);
9211   temp &= 0x7f; /* Use external VSYNC */
9212   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
9213   SiS_LongDelay(SiS_Pr,3);
9214   temp = SiS_GetCH701x(SiS_Pr,0x47);
9215   temp |= 0x80; /* Use internal VSYNC */
9216   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
9217   SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
9218 }
9219
9220 void
9221 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9222 {
9223   USHORT temp;
9224
9225   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
9226      if(HwInfo->jChipType == SIS_740) {
9227         temp = SiS_GetCH701x(SiS_Pr,0x1c);
9228         temp |= 0x04;   /* Invert XCLK phase */
9229         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
9230      }
9231      if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
9232         temp = SiS_GetCH701x(SiS_Pr,0x01);
9233         temp &= 0x3f;
9234         temp |= 0x80;   /* Enable YPrPb (HDTV) */
9235         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
9236      }
9237      if(SiS_IsChScart(SiS_Pr, HwInfo)) {
9238         temp = SiS_GetCH701x(SiS_Pr,0x01);
9239         temp &= 0x3f;
9240         temp |= 0xc0;   /* Enable SCART + CVBS */
9241         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
9242      }
9243      if(HwInfo->jChipType == SIS_740) {
9244         SiS_ChrontelResetVSync(SiS_Pr);
9245         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
9246      } else {
9247         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
9248         temp = SiS_GetCH701x(SiS_Pr,0x49);
9249         if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
9250            temp = SiS_GetCH701x(SiS_Pr,0x73);
9251            temp |= 0x60;
9252            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
9253         }
9254         temp = SiS_GetCH701x(SiS_Pr,0x47);
9255         temp &= 0x7f;
9256         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
9257         SiS_LongDelay(SiS_Pr,2);
9258         temp = SiS_GetCH701x(SiS_Pr,0x47);
9259         temp |= 0x80;
9260         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
9261      }
9262   }
9263 }
9264
9265 void
9266 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9267 {
9268   USHORT temp;
9269
9270   /* Complete power down of LVDS */
9271   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
9272      if(HwInfo->jChipType == SIS_740) {
9273         SiS_LongDelay(SiS_Pr,1);
9274         SiS_GenericDelay(SiS_Pr,0x16ff);
9275         SiS_SetCH701x(SiS_Pr,0xac76);
9276         SiS_SetCH701x(SiS_Pr,0x0066);
9277      } else {
9278         SiS_LongDelay(SiS_Pr,2);
9279         temp = SiS_GetCH701x(SiS_Pr,0x76);
9280         temp &= 0xfc;
9281         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
9282         SiS_SetCH701x(SiS_Pr,0x0066);
9283      }
9284   }
9285 }
9286
9287 static void
9288 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9289 {
9290      USHORT temp;
9291
9292      if(HwInfo->jChipType == SIS_740) {
9293
9294         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
9295         temp &= 0x01;
9296         if(!temp) {
9297
9298            if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
9299               temp = SiS_GetCH701x(SiS_Pr,0x49);
9300               SiS_SetCH701x(SiS_Pr,0x3e49);
9301            }
9302            /* Reset Chrontel 7019 datapath */
9303            SiS_SetCH701x(SiS_Pr,0x1048);
9304            SiS_LongDelay(SiS_Pr,1);
9305            SiS_SetCH701x(SiS_Pr,0x1848);
9306
9307            if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
9308               SiS_ChrontelResetVSync(SiS_Pr);
9309               SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
9310            }
9311
9312         } else {
9313
9314            /* Clear/set/clear GPIO */
9315            temp = SiS_GetCH701x(SiS_Pr,0x5c);
9316            temp &= 0xef;
9317            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
9318            temp = SiS_GetCH701x(SiS_Pr,0x5c);
9319            temp |= 0x10;
9320            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
9321            temp = SiS_GetCH701x(SiS_Pr,0x5c);
9322            temp &= 0xef;
9323            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
9324            temp = SiS_GetCH701x(SiS_Pr,0x61);
9325            if(!temp) {
9326               SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
9327            }
9328         }
9329
9330      } else { /* 650 */
9331         /* Reset Chrontel 7019 datapath */
9332         SiS_SetCH701x(SiS_Pr,0x1048);
9333         SiS_LongDelay(SiS_Pr,1);
9334         SiS_SetCH701x(SiS_Pr,0x1848);
9335      }
9336 }
9337
9338 void
9339 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9340 {
9341      USHORT temp;
9342
9343      if(HwInfo->jChipType == SIS_740) {
9344
9345         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
9346            SiS_ChrontelResetVSync(SiS_Pr);
9347         }
9348
9349      } else {
9350
9351         SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
9352         temp = SiS_GetCH701x(SiS_Pr,0x49);
9353         temp &= 1;
9354         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
9355            temp = SiS_GetCH701x(SiS_Pr,0x47);
9356            temp &= 0x70;
9357            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
9358            SiS_LongDelay(SiS_Pr,3);
9359            temp = SiS_GetCH701x(SiS_Pr,0x47);
9360            temp |= 0x80;
9361            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
9362         }
9363
9364      }
9365 }
9366
9367 static void
9368 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
9369 {
9370      USHORT temp,temp1;
9371
9372      if(HwInfo->jChipType == SIS_740) {
9373
9374         temp = SiS_GetCH701x(SiS_Pr,0x61);
9375         if(temp < 1) {
9376            temp++;
9377            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
9378         }
9379         SiS_SetCH701x(SiS_Pr,0x4566);  /* Panel power on */
9380         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on */
9381         SiS_LongDelay(SiS_Pr,1);
9382         SiS_GenericDelay(SiS_Pr,0x16ff);
9383
9384      } else {  /* 650 */
9385
9386         temp1 = 0;
9387         temp = SiS_GetCH701x(SiS_Pr,0x61);
9388         if(temp < 2) {
9389            temp++;
9390            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
9391            temp1 = 1;
9392         }
9393         SiS_SetCH701x(SiS_Pr,0xac76);
9394         temp = SiS_GetCH701x(SiS_Pr,0x66);
9395         temp |= 0x5f;
9396         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
9397         if(ModeNo > 0x13) {
9398            if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
9399               SiS_GenericDelay(SiS_Pr,0x3ff);
9400            } else {
9401               SiS_GenericDelay(SiS_Pr,0x2ff);
9402            }
9403         } else {
9404            if(!temp1)
9405               SiS_GenericDelay(SiS_Pr,0x2ff);
9406         }
9407         temp = SiS_GetCH701x(SiS_Pr,0x76);
9408         temp |= 0x03;
9409         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
9410         temp = SiS_GetCH701x(SiS_Pr,0x66);
9411         temp &= 0x7f;
9412         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
9413         SiS_LongDelay(SiS_Pr,1);
9414
9415      }
9416 }
9417
9418 static void
9419 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9420 {
9421      USHORT temp,tempcl,tempch;
9422
9423      SiS_LongDelay(SiS_Pr, 1);
9424      tempcl = 3;
9425      tempch = 0;
9426
9427      do {
9428        temp = SiS_GetCH701x(SiS_Pr,0x66);
9429        temp &= 0x04;  /* PLL stable? -> bail out */
9430        if(temp == 0x04) break;
9431
9432        if(HwInfo->jChipType == SIS_740) {
9433           /* Power down LVDS output, PLL normal operation */
9434           SiS_SetCH701x(SiS_Pr,0xac76);
9435        }
9436
9437        SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
9438
9439        if(tempcl == 0) {
9440            if(tempch == 3) break;
9441            SiS_ChrontelResetDB(SiS_Pr,HwInfo);
9442            tempcl = 3;
9443            tempch++;
9444        }
9445        tempcl--;
9446        temp = SiS_GetCH701x(SiS_Pr,0x76);
9447        temp &= 0xfb;  /* Reset PLL */
9448        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
9449        SiS_LongDelay(SiS_Pr,2);
9450        temp = SiS_GetCH701x(SiS_Pr,0x76);
9451        temp |= 0x04;  /* PLL normal operation */
9452        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
9453        if(HwInfo->jChipType == SIS_740) {
9454           SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
9455        } else {
9456           SiS_SetCH701x(SiS_Pr,0x6078);
9457        }
9458        SiS_LongDelay(SiS_Pr,2);
9459     } while(0);
9460
9461     SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
9462 }
9463
9464 void
9465 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9466 {
9467      USHORT temp;
9468
9469      temp = SiS_GetCH701x(SiS_Pr,0x03);
9470      temp |= 0x80;      /* Set datapath 1 to TV   */
9471      temp &= 0xbf;      /* Set datapath 2 to LVDS */
9472      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
9473
9474      if(HwInfo->jChipType == SIS_740) {
9475
9476         temp = SiS_GetCH701x(SiS_Pr,0x1c);
9477         temp &= 0xfb;   /* Normal XCLK phase */
9478         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
9479
9480         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
9481
9482         temp = SiS_GetCH701x(SiS_Pr,0x64);
9483         temp |= 0x40;   /* ? Bit not defined */
9484         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
9485
9486         temp = SiS_GetCH701x(SiS_Pr,0x03);
9487         temp &= 0x3f;   /* D1 input to both LVDS and TV */
9488         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
9489
9490         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
9491            SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
9492            SiS_LongDelay(SiS_Pr, 1);
9493            SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
9494            SiS_ChrontelResetDB(SiS_Pr, HwInfo);
9495            SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
9496            SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
9497         } else {
9498            temp = SiS_GetCH701x(SiS_Pr,0x66);
9499            if(temp != 0x45) {
9500               SiS_ChrontelResetDB(SiS_Pr, HwInfo);
9501               SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
9502               SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
9503            }
9504         }
9505
9506      } else { /* 650 */
9507
9508         SiS_ChrontelResetDB(SiS_Pr,HwInfo);
9509         SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
9510         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
9511         SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
9512         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on, LVDS normal operation */
9513
9514      }
9515
9516 }
9517 #endif  /* 315 series  */
9518
9519 /*********************************************/
9520 /*      MAIN: SET CRT2 REGISTER GROUP        */
9521 /*********************************************/
9522
9523 BOOLEAN
9524 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
9525 {
9526 #ifdef SIS300
9527    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
9528 #endif
9529    USHORT ModeIdIndex, RefreshRateTableIndex;
9530 #if 0
9531    USHORT temp;
9532 #endif
9533
9534    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
9535
9536    if(!SiS_Pr->UseCustomMode) {
9537       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
9538    } else {
9539       ModeIdIndex = 0;
9540    }
9541
9542    /* Used for shifting CR33 */
9543    SiS_Pr->SiS_SelectCRT2Rate = 4;
9544
9545    SiS_UnLockCRT2(SiS_Pr, HwInfo);
9546
9547    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9548
9549    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
9550
9551    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9552       SiS_DisableBridge(SiS_Pr,HwInfo);
9553       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
9554          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
9555       }
9556       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9557    }
9558
9559    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
9560       SiS_LockCRT2(SiS_Pr, HwInfo);
9561       SiS_DisplayOn(SiS_Pr);
9562       return TRUE;
9563    }
9564
9565    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
9566
9567    /* Set up Panel Link for LVDS, 301BDH and 30xLV(for LCDA) */
9568    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
9569        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
9570        ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
9571       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
9572    } else {
9573       SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
9574    }
9575
9576 #ifdef LINUX_XF86
9577 #ifdef TWDEBUG
9578   xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
9579   xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
9580   xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
9581   xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
9582   xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
9583 #endif
9584 #endif
9585
9586    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9587       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
9588    }
9589
9590    if(SiS_Pr->SiS_VBType & VB_SISVB) {
9591
9592         if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9593
9594            SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
9595 #ifdef SIS315H
9596            SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
9597 #endif
9598            SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9599            SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
9600 #ifdef SIS315H
9601            SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo);
9602 #endif
9603            SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9604
9605            /* For 301BDH (Panel link initialization): */
9606            if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
9607               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
9608                  if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
9609                     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
9610                        SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
9611                                        RefreshRateTableIndex,HwInfo);
9612                     }
9613                  }
9614               }
9615               SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
9616                               RefreshRateTableIndex,HwInfo);
9617            }
9618         }
9619
9620    } else {
9621
9622         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
9623            if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
9624               SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
9625                               RefreshRateTableIndex,HwInfo);
9626            }
9627         }
9628
9629         SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
9630                         RefreshRateTableIndex,HwInfo);
9631
9632         if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9633            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
9634               if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
9635                  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
9636 #ifdef SIS315H
9637                     SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
9638 #endif
9639                  }
9640               }
9641               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9642                  SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,
9643                                RefreshRateTableIndex);
9644               }
9645            }
9646         }
9647
9648    }
9649
9650 #ifdef SIS300
9651    if(HwInfo->jChipType < SIS_315H) {
9652       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9653          if(SiS_Pr->SiS_UseOEM) {
9654             if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
9655                if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
9656                   SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
9657                                     RefreshRateTableIndex);
9658                }
9659             } else {
9660                SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
9661                                  RefreshRateTableIndex);
9662             }
9663          }
9664          if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9665             if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
9666                (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
9667                SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
9668             }
9669             if(HwInfo->jChipType == SIS_730) {
9670                SiS_DisplayOn(SiS_Pr);
9671             }
9672          }
9673       }
9674       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9675           if(HwInfo->jChipType != SIS_730) {
9676              SiS_DisplayOn(SiS_Pr);
9677           }
9678       }
9679    }
9680 #endif
9681
9682 #ifdef SIS315H
9683    if(HwInfo->jChipType >= SIS_315H) {
9684       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9685          if(HwInfo->jChipType < SIS_661) {
9686             SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9687             if(SiS_Pr->SiS_UseOEM) {
9688                SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
9689             }
9690          } else {
9691             SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9692          }
9693          SiS_CRT2AutoThreshold(SiS_Pr);
9694       }
9695    }
9696 #endif
9697
9698    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9699       SiS_EnableBridge(SiS_Pr, HwInfo);
9700    }
9701
9702    SiS_DisplayOn(SiS_Pr);
9703
9704    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9705       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9706          /* Disable LCD panel when using TV */
9707          SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
9708       } else {
9709          /* Disable TV when using LCD */
9710          SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
9711       }
9712    }
9713
9714    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9715       SiS_LockCRT2(SiS_Pr,HwInfo);
9716    }
9717
9718    return TRUE;
9719 }
9720
9721
9722 /*********************************************/
9723 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
9724 /*********************************************/
9725
9726 void
9727 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9728 {
9729   /* Switch on LCD backlight on SiS30xLV */
9730   SiS_DDC2Delay(SiS_Pr,0xff00);
9731   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9732      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9733      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
9734   }
9735   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9736      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9737   }
9738 }
9739
9740 void
9741 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9742 {
9743   /* Switch off LCD backlight on SiS30xLV */
9744   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9745   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
9746   SiS_DDC2Delay(SiS_Pr,0xe000);
9747 }
9748
9749 /*********************************************/
9750 /*          DDC RELATED FUNCTIONS            */
9751 /*********************************************/
9752
9753 static void
9754 SiS_SetupDDCN(SiS_Private *SiS_Pr)
9755 {
9756   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9757   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
9758   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9759      SiS_Pr->SiS_DDC_NData &= 0x0f;
9760      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
9761   }
9762 }
9763
9764 /* The Chrontel 700x is connected to the 630/730 via
9765  * the 630/730's DDC/I2C port.
9766  *
9767  * On 630(S)T chipset, the index changed from 0x11 to
9768  * 0x0a, possibly for working around the DDC problems
9769  */
9770
9771 static BOOLEAN
9772 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
9773 {
9774   USHORT tempah,temp,i;
9775
9776   for(i=0; i<20; i++) {                         /* Do 20 attempts to write */
9777      if(i) {
9778         SiS_SetStop(SiS_Pr);
9779         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9780      }
9781      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
9782      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9783      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
9784      if(temp) continue;                         /*    (ERROR: no ack) */
9785      tempah = tempbx & 0x00FF;                  /* Write RAB */
9786      tempah |= myor;                            /* (700x: set bit 7, see datasheet) */
9787      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9788      if(temp) continue;                         /*    (ERROR: no ack) */
9789      tempah = (tempbx & 0xFF00) >> 8;
9790      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write data */
9791      if(temp) continue;                         /*    (ERROR: no ack) */
9792      if(SiS_SetStop(SiS_Pr)) continue;          /* Set stop condition */
9793      SiS_Pr->SiS_ChrontelInit = 1;
9794      return TRUE;
9795   }
9796   return FALSE;
9797 }
9798
9799 /* Write to Chrontel 700x */
9800 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9801 void
9802 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9803 {
9804   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9805
9806   if(!(SiS_Pr->SiS_ChrontelInit)) {
9807      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9808      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9809      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9810      SiS_SetupDDCN(SiS_Pr);
9811   }
9812
9813   if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9814       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9815      SiS_Pr->SiS_DDC_Index = 0x0a;              /* Bit 7 = SC;  Bit 6 = SD */
9816      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
9817      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
9818      SiS_SetupDDCN(SiS_Pr);
9819
9820      SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9821   }
9822 }
9823
9824 /* Write to Chrontel 701x */
9825 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9826 void
9827 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9828 {
9829   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9830   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9831   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9832   SiS_SetupDDCN(SiS_Pr);
9833   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9834
9835   SiS_SetChReg(SiS_Pr, tempbx, 0);
9836 }
9837
9838 void
9839 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9840 {
9841    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9842       SiS_SetCH700x(SiS_Pr,tempbx);
9843    else
9844       SiS_SetCH701x(SiS_Pr,tempbx);
9845 }
9846
9847 static USHORT
9848 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9849 {
9850   USHORT tempah,temp,i;
9851
9852   for(i=0; i<20; i++) {                         /* Do 20 attempts to read */
9853      if(i) {
9854         SiS_SetStop(SiS_Pr);
9855         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9856      }
9857      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
9858      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9859      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
9860      if(temp) continue;                         /*        (ERROR: no ack) */
9861      tempah = SiS_Pr->SiS_DDC_ReadAddr | myor;  /* Write RAB (700x: | 0x80) */
9862      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9863      if(temp) continue;                         /*        (ERROR: no ack) */
9864      if (SiS_SetStart(SiS_Pr)) continue;        /* Re-start */
9865      tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9866      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* DAB (S0=1=read) */
9867      if(temp) continue;                         /*        (ERROR: no ack) */
9868      tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);  /* Read byte */
9869      if(SiS_SetStop(SiS_Pr)) continue;          /* Stop condition */
9870      SiS_Pr->SiS_ChrontelInit = 1;
9871      return(tempah);
9872   }
9873   return 0xFFFF;
9874 }
9875
9876 /* Read from Chrontel 700x */
9877 /* Parameter is [Register no (S7-S0)] */
9878 USHORT
9879 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9880 {
9881   USHORT result;
9882
9883   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9884
9885   if(!(SiS_Pr->SiS_ChrontelInit)) {
9886      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9887      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9888      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9889      SiS_SetupDDCN(SiS_Pr);
9890   }
9891
9892   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9893
9894   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9895       (!SiS_Pr->SiS_ChrontelInit) ) {
9896
9897      SiS_Pr->SiS_DDC_Index = 0x0a;
9898      SiS_Pr->SiS_DDC_Data  = 0x80;
9899      SiS_Pr->SiS_DDC_Clk   = 0x40;
9900      SiS_SetupDDCN(SiS_Pr);
9901
9902      result = SiS_GetChReg(SiS_Pr,0x80);
9903   }
9904   return(result);
9905 }
9906
9907 /* Read from Chrontel 701x */
9908 /* Parameter is [Register no (S7-S0)] */
9909 USHORT
9910 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9911 {
9912   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9913   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9914   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9915   SiS_SetupDDCN(SiS_Pr);
9916   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9917
9918   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9919
9920   return(SiS_GetChReg(SiS_Pr,0));
9921 }
9922
9923 /* Read from Chrontel 70xx */
9924 /* Parameter is [Register no (S7-S0)] */
9925 USHORT
9926 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9927 {
9928    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9929       return(SiS_GetCH700x(SiS_Pr, tempbx));
9930    else
9931       return(SiS_GetCH701x(SiS_Pr, tempbx));
9932 }
9933
9934 /* Our own DDC functions */
9935 USHORT
9936 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9937                 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9938 {
9939      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9940      unsigned char flag, cr32;
9941      USHORT        temp = 0, myadaptnum = adaptnum;
9942
9943      if(adaptnum != 0) {
9944         if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9945         if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9946      }  
9947      
9948      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9949      
9950      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9951
9952      SiS_Pr->SiS_DDC_SecAddr = 0;
9953      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9954      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9955      SiS_Pr->SiS_DDC_Index = 0x11;
9956      flag = 0xff;
9957
9958      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9959
9960 #if 0
9961      if(VBFlags & VB_SISBRIDGE) {
9962         if(myadaptnum == 0) {
9963            if(!(cr32 & 0x20)) {
9964               myadaptnum = 2;
9965               if(!(cr32 & 0x10)) {
9966                  myadaptnum = 1;
9967                  if(!(cr32 & 0x08)) {
9968                     myadaptnum = 0;
9969                  }
9970               }
9971            }
9972         }
9973      }
9974 #endif
9975
9976      if(VGAEngine == SIS_300_VGA) {             /* 300 series */
9977         
9978         if(myadaptnum != 0) {
9979            flag = 0;
9980            if(VBFlags & VB_SISBRIDGE) {
9981               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9982               SiS_Pr->SiS_DDC_Index = 0x0f;
9983            }
9984         }
9985
9986         if(!(VBFlags & VB_301)) {
9987            if((cr32 & 0x80) && (checkcr32)) {
9988               if(myadaptnum >= 1) {
9989                  if(!(cr32 & 0x08)) {
9990                      myadaptnum = 1;
9991                      if(!(cr32 & 0x10)) return 0xFFFF;
9992                  }
9993               }
9994            }
9995         }
9996
9997         temp = 4 - (myadaptnum * 2);
9998         if(flag) temp = 0;
9999
10000      } else {                                           /* 315/330 series */
10001
10002         /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
10003
10004         if(VBFlags & VB_SISBRIDGE) {
10005            if(myadaptnum == 2) {
10006               myadaptnum = 1;
10007            }
10008         }
10009
10010         if(myadaptnum == 1) {
10011            flag = 0;
10012            if(VBFlags & VB_SISBRIDGE) {
10013               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
10014               SiS_Pr->SiS_DDC_Index = 0x0f;
10015            }
10016         }
10017
10018         if((cr32 & 0x80) && (checkcr32)) {
10019            if(myadaptnum >= 1) {
10020               if(!(cr32 & 0x08)) {
10021                  myadaptnum = 1;
10022                  if(!(cr32 & 0x10)) return 0xFFFF;
10023               }
10024            }
10025         }
10026
10027         temp = myadaptnum;
10028         if(myadaptnum == 1) {
10029            temp = 0;
10030            if(VBFlags & VB_LVDS) flag = 0xff;
10031         }
10032
10033         if(flag) temp = 0;
10034     }
10035     
10036     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
10037     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
10038
10039     SiS_SetupDDCN(SiS_Pr);
10040
10041 #ifdef TWDEBUG
10042     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
10043                 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
10044 #endif
10045     
10046     return 0;
10047 }
10048
10049 USHORT
10050 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
10051 {
10052    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
10053    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
10054         return 0xFFFF;
10055    }
10056    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
10057         return 0xFFFF;
10058    }
10059    return(0);
10060 }
10061
10062 USHORT
10063 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
10064 {
10065    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
10066    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
10067         return 0xFFFF;
10068    }
10069    return(0);
10070 }
10071
10072 USHORT
10073 SiS_PrepareDDC(SiS_Private *SiS_Pr)
10074 {
10075    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
10076    if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
10077    return(0);
10078 }
10079
10080 void
10081 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
10082 {
10083    SiS_SetSCLKLow(SiS_Pr);
10084    if(yesno) {
10085       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10086                       SiS_Pr->SiS_DDC_Index,
10087                       SiS_Pr->SiS_DDC_NData,
10088                       SiS_Pr->SiS_DDC_Data);
10089    } else {
10090       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10091                       SiS_Pr->SiS_DDC_Index,
10092                       SiS_Pr->SiS_DDC_NData,
10093                       0);
10094    }
10095    SiS_SetSCLKHigh(SiS_Pr);
10096 }
10097
10098 USHORT
10099 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
10100 {
10101     unsigned char mask, value;
10102     USHORT  temp, ret=0;
10103     BOOLEAN failed = FALSE;
10104
10105     SiS_SetSwitchDDC2(SiS_Pr);
10106     if(SiS_PrepareDDC(SiS_Pr)) {
10107          SiS_SetStop(SiS_Pr);
10108 #ifdef TWDEBUG
10109          xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
10110 #endif
10111          return(0xFFFF);
10112     }
10113     mask = 0xf0;
10114     value = 0x20;
10115     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
10116        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
10117        SiS_SendACK(SiS_Pr, 0);
10118        if(temp == 0) {
10119            mask = 0xff;
10120            value = 0xff;
10121        } else {
10122            failed = TRUE;
10123            ret = 0xFFFF;
10124 #ifdef TWDEBUG
10125            xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
10126 #endif
10127        }
10128     }
10129     if(failed == FALSE) {
10130        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
10131        SiS_SendACK(SiS_Pr, 1);
10132        temp &= mask;
10133        if(temp == value) ret = 0;
10134        else {
10135           ret = 0xFFFF;
10136 #ifdef TWDEBUG
10137           xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
10138 #endif
10139           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
10140              if(temp == 0x30) ret = 0;
10141           }
10142        }
10143     }
10144     SiS_SetStop(SiS_Pr);
10145     return(ret);
10146 }
10147
10148 USHORT
10149 SiS_ProbeDDC(SiS_Private *SiS_Pr)
10150 {
10151    USHORT flag;
10152
10153    flag = 0x180;
10154    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
10155    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
10156    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
10157    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
10158    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
10159    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
10160    if(!(flag & 0x1a)) flag = 0;
10161    return(flag);
10162 }
10163
10164 USHORT
10165 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
10166 {
10167    USHORT flag, length, i;
10168    unsigned char chksum,gotcha;
10169
10170    if(DDCdatatype > 4) return 0xFFFF;  
10171
10172    flag = 0;
10173    SiS_SetSwitchDDC2(SiS_Pr);
10174    if(!(SiS_PrepareDDC(SiS_Pr))) {
10175       length = 127;
10176       if(DDCdatatype != 1) length = 255;
10177       chksum = 0;
10178       gotcha = 0;
10179       for(i=0; i<length; i++) {
10180          buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
10181          chksum += buffer[i];
10182          gotcha |= buffer[i];
10183          SiS_SendACK(SiS_Pr, 0);
10184       }
10185       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
10186       chksum += buffer[i];
10187       SiS_SendACK(SiS_Pr, 1);
10188       if(gotcha) flag = (USHORT)chksum;
10189       else flag = 0xFFFF;
10190    } else {
10191       flag = 0xFFFF;
10192    }
10193    SiS_SetStop(SiS_Pr);
10194    return(flag);
10195 }
10196
10197 /* Our private DDC functions
10198
10199    It complies somewhat with the corresponding VESA function
10200    in arguments and return values.
10201
10202    Since this is probably called before the mode is changed,
10203    we use our pre-detected pSiS-values instead of SiS_Pr as
10204    regards chipset and video bridge type.
10205
10206    Arguments:
10207        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
10208                  CRT2 DDC is only supported on SiS301, 301B, 302B.
10209        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
10210        buffer: ptr to 256 data bytes which will be filled with read data.
10211
10212    Returns 0xFFFF if error, otherwise
10213        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
10214        if DDCdatatype = 0:  Returns supported DDC modes
10215
10216  */
10217 USHORT
10218 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
10219               USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
10220 {
10221    unsigned char sr1f,cr17=1;
10222    USHORT result;
10223
10224    if(adaptnum > 2) return 0xFFFF;
10225    if(DDCdatatype > 4) return 0xFFFF;
10226    if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
10227    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
10228
10229    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
10230    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
10231    if(VGAEngine == SIS_300_VGA) {
10232       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
10233       if(!cr17) {
10234          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
10235          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
10236          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
10237       }
10238    }
10239    if((sr1f) || (!cr17)) {
10240       SiS_WaitRetrace1(SiS_Pr);
10241       SiS_WaitRetrace1(SiS_Pr);
10242       SiS_WaitRetrace1(SiS_Pr);
10243       SiS_WaitRetrace1(SiS_Pr);
10244    }
10245
10246    if(DDCdatatype == 0) {
10247       result = SiS_ProbeDDC(SiS_Pr);
10248    } else {
10249       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
10250    }
10251    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
10252    if(VGAEngine == SIS_300_VGA) {
10253       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
10254    }
10255    return result;
10256 }
10257
10258 #ifdef LINUX_XF86
10259
10260 static BOOLEAN
10261 checkedid1(unsigned char *buffer)
10262 {
10263    /* Check header */
10264    if((buffer[0] != 0x00) ||
10265       (buffer[1] != 0xff) ||
10266       (buffer[2] != 0xff) ||
10267       (buffer[3] != 0xff) ||
10268       (buffer[4] != 0xff) ||
10269       (buffer[5] != 0xff) ||
10270       (buffer[6] != 0xff) ||
10271       (buffer[7] != 0x00))
10272       return FALSE;
10273
10274    /* Check EDID version and revision */
10275    if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
10276
10277    /* Check week of manufacture for sanity */
10278    if(buffer[0x10] > 53) return FALSE;
10279
10280    /* Check year of manufacture for sanity */
10281    if(buffer[0x11] > 40) return FALSE;
10282
10283    return TRUE;
10284 }
10285
10286 static BOOLEAN
10287 checkedid2(unsigned char *buffer)
10288 {
10289    USHORT year = buffer[6] | (buffer[7] << 8);
10290
10291    /* Check EDID version */
10292    if((buffer[0] & 0xf0) != 0x20) return FALSE;
10293
10294    /* Check week of manufacture for sanity */
10295    if(buffer[5] > 53) return FALSE;
10296
10297    /* Check year of manufacture for sanity */
10298    if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
10299
10300    return TRUE;
10301 }
10302
10303 /* Sense the LCD parameters (CR36, CR37) via DDC */
10304 /* SiS30x(B) only */
10305 USHORT
10306 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10307 {
10308    USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
10309    USHORT index, myindex, lumsize, numcodes;
10310    unsigned char cr37=0, seekcode;
10311    BOOLEAN checkexpand = FALSE;
10312    int retry, i;
10313    unsigned char buffer[256];
10314
10315    for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
10316    SiS_Pr->CP_HaveCustomData = FALSE;
10317    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
10318
10319    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10320    if(pSiS->VBFlags & VB_30xBDH) return 0;
10321   
10322    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
10323    
10324    SiS_Pr->SiS_DDC_SecAddr = 0x00;
10325    
10326    /* Probe supported DA's */
10327    flag = SiS_ProbeDDC(SiS_Pr);
10328 #ifdef TWDEBUG
10329    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10330         "CRT2 DDC capabilities 0x%x\n", flag);
10331 #endif  
10332    if(flag & 0x10) {
10333       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;        /* EDID V2 (FP) */
10334       DDCdatatype = 4;
10335    } else if(flag & 0x08) {
10336       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;        /* EDID V2 (P&D-D Monitor) */
10337       DDCdatatype = 3;
10338    } else if(flag & 0x02) {
10339       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;        /* EDID V1 */
10340       DDCdatatype = 1;
10341    } else return 0;                             /* no DDC support (or no device attached) */
10342    
10343    /* Read the entire EDID */
10344    retry = 2;
10345    do {
10346       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10347          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10348                 "CRT2: DDC read failed (attempt %d), %s\n",
10349                 (3-retry), (retry == 1) ? "giving up" : "retrying");
10350          retry--;
10351          if(retry == 0) return 0xFFFF;
10352       } else break;
10353    } while(1);
10354
10355 #ifdef TWDEBUG
10356    for(i=0; i<256; i+=16) {
10357        xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10358         "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
10359         buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
10360         buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
10361         buffer[i+8],  buffer[i+9], buffer[i+10], buffer[i+11],
10362         buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
10363    }
10364 #endif   
10365    
10366    /* Analyze EDID and retrieve LCD panel information */
10367    paneltype = 0;
10368    switch(DDCdatatype) {
10369    case 1:                                                      /* Analyze EDID V1 */
10370       /* Catch a few clear cases: */
10371       if(!(checkedid1(buffer))) {
10372          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10373                 "CRT2: EDID corrupt\n");
10374          return 0;
10375       }
10376
10377       if(!(buffer[0x14] & 0x80)) {
10378          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10379                 "CRT2: Attached display expects analog input (0x%02x)\n",
10380                 buffer[0x14]);
10381          return 0;
10382       }
10383
10384       if((buffer[0x18] & 0x18) != 0x08) {
10385          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10386                 "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
10387                 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
10388                   ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
10389                      "undefined"),
10390                 buffer[0x18]);
10391          return 0;
10392       }
10393
10394       /* Now analyze the first Detailed Timing Block and see
10395        * if the preferred timing mode is stored there. If so,
10396        * check if this is a standard panel for which we already
10397        * know the timing.
10398        */
10399
10400       paneltype = Panel_Custom;
10401       checkexpand = FALSE;
10402
10403       if(buffer[0x18] & 0x02) {
10404
10405          xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
10406          yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
10407
10408          SiS_Pr->CP_PreferredX = xres;
10409          SiS_Pr->CP_PreferredY = yres;
10410
10411          switch(xres) {
10412             case 800:
10413                 if(yres == 600) {
10414                    paneltype = Panel_800x600;
10415                    checkexpand = TRUE;
10416                 }
10417                 break;
10418             case 1024:
10419                 if(yres == 768) {
10420                    paneltype = Panel_1024x768;
10421                    checkexpand = TRUE;
10422                 }
10423                 break;
10424             case 1280:
10425                 if(yres == 1024) {
10426                    paneltype = Panel_1280x1024;
10427                    checkexpand = TRUE;
10428                 } else if(yres == 960) {
10429                    if(pSiS->VGAEngine == SIS_300_VGA) {
10430                       paneltype = Panel300_1280x960;
10431                    } else {
10432                       paneltype = Panel310_1280x960;
10433                    }
10434                 } else if(yres == 768) {
10435                    if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
10436                        ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
10437                        ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
10438                       paneltype = Panel_1280x768;
10439                       checkexpand = FALSE;
10440                       cr37 |= 0x10;
10441                    }
10442                 }
10443                 break;
10444             case 1400:
10445                 if(pSiS->VGAEngine == SIS_315_VGA) {
10446                    if(yres == 1050) {
10447                       paneltype = Panel310_1400x1050;
10448                       checkexpand = TRUE;
10449                    }
10450                 }
10451                 break;
10452 #if 0       /* Treat this as custom, as we have no valid timing data yet */
10453             case 1600:
10454                 if(pSiS->VGAEngine == SIS_315_VGA) {
10455                    if(yres == 1200) {
10456                       paneltype = Panel310_1600x1200;
10457                       checkexpand = TRUE;
10458                    }
10459                 }
10460                 break;
10461 #endif
10462          }
10463
10464          if(paneltype != Panel_Custom) {
10465             if((buffer[0x47] & 0x18) == 0x18) {
10466                cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
10467             } else {
10468                /* What now? There is no digital separate output timing... */
10469                xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10470                    "CRT2: Unable to retrieve Sync polarity information\n");
10471                cr37 |= 0xc0;  /* Default */
10472             }
10473          }
10474
10475       }
10476
10477       /* If we still don't know what panel this is, we take it
10478        * as a custom panel and derive the timing data from the
10479        * detailed timing blocks
10480        */
10481       if(paneltype == Panel_Custom) {
10482
10483          BOOLEAN havesync = FALSE;
10484          int i, temp, base = 0x36;
10485          unsigned long estpack;
10486          unsigned short estx[] = {
10487                 720, 720, 640, 640, 640, 640, 800, 800,
10488                 800, 800, 832,1024,1024,1024,1024,1280,
10489                 1152
10490          };
10491          unsigned short esty[] = {
10492                 400, 400, 480, 480, 480, 480, 600, 600,
10493                 600, 600, 624, 768, 768, 768, 768,1024,
10494                 870
10495          };
10496
10497          paneltype = 0;
10498          SiS_Pr->CP_Supports64048075 = TRUE;
10499
10500          /* Find the maximum resolution */
10501
10502          /* 1. From Established timings */
10503          estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
10504          for(i=16; i>=0; i--) {
10505              if(estpack & (1 << i)) {
10506                 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
10507                 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
10508              }
10509          }
10510
10511          /* 2. From Standard Timings */
10512          for(i=0x26; i < 0x36; i+=2) {
10513             if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
10514                temp = (buffer[i] + 31) * 8;
10515                if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
10516                switch((buffer[i+1] & 0xc0) >> 6) {
10517                case 0x03: temp = temp * 9 / 16; break;
10518                case 0x02: temp = temp * 4 / 5;  break;
10519                case 0x01: temp = temp * 3 / 4;  break;
10520                }
10521                if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
10522             }
10523          }
10524
10525          /* Now extract the Detailed Timings and convert them into modes */
10526
10527          for(i = 0; i < 4; i++, base += 18) {
10528
10529             /* Is this a detailed timing block or a monitor descriptor? */
10530             if(buffer[base] || buffer[base+1] || buffer[base+2]) {
10531
10532                xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
10533                yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
10534
10535                SiS_Pr->CP_HDisplay[i] = xres;
10536                SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
10537                SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
10538                SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
10539                SiS_Pr->CP_HBlankStart[i] = xres + 1;
10540                SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10541
10542                SiS_Pr->CP_VDisplay[i] = yres;
10543                SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
10544                SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
10545                SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
10546                SiS_Pr->CP_VBlankStart[i] = yres + 1;
10547                SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10548
10549                SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
10550
10551                SiS_Pr->CP_DataValid[i] = TRUE;
10552
10553                /* Sort out invalid timings, interlace and too high clocks */
10554                if((SiS_Pr->CP_HDisplay[i] & 7)                                          ||
10555                   (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])                   ||
10556                   (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])                    ||
10557                   (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])                      ||
10558                   (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i])                  ||
10559                   (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])                     ||
10560                   (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])                       ||
10561                   (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])                   ||
10562                   (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])                    ||
10563                   (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])                      ||
10564                   (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])                   ||
10565                   (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])                     ||
10566                   (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])                       ||
10567                   (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10568                    ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))    ||
10569                   (buffer[base+17] & 0x80)) {
10570
10571                   SiS_Pr->CP_DataValid[i] = FALSE;
10572
10573                } else {
10574
10575                   paneltype = Panel_Custom;
10576
10577                   SiS_Pr->CP_HaveCustomData = TRUE;
10578
10579                   if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10580                   if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10581                   if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10582
10583                   SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10584                   SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10585
10586                   /* By default we drive the LCD at 75Hz in 640x480 mode; if
10587                    * the panel does not provide this mode, use 60hz
10588                    */
10589                   if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
10590
10591                   /* We must assume the panel can scale, since we have
10592                    * no scaling data
10593                    */
10594                   checkexpand = FALSE;
10595                   cr37 |= 0x10;
10596
10597                   /* Extract the sync polarisation information. This only works
10598                    * if the Flags indicate a digital separate output.
10599                    */
10600                   if((buffer[base+17] & 0x18) == 0x18) {
10601                      SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10602                      SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10603                      SiS_Pr->CP_SyncValid[i] = TRUE;
10604                      if(!havesync) {
10605                         cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10606                         havesync = TRUE;
10607                      }
10608                   } else {
10609                      SiS_Pr->CP_SyncValid[i] = FALSE;
10610                   }
10611                }
10612             }
10613          }
10614          if(!havesync) {
10615             xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10616                    "CRT2: Unable to retrieve Sync polarity information\n");
10617          }
10618       }
10619
10620       if(paneltype && checkexpand) {
10621          /* If any of the Established low-res modes is supported, the
10622           * panel can scale automatically. For 800x600 panels, we only 
10623           * check the even lower ones.
10624           */
10625          if(paneltype == Panel_800x600) {
10626             if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10627          } else {
10628             if(buffer[0x23])        cr37 |= 0x10;
10629          }
10630       }
10631        
10632       break;
10633       
10634    case 3:                                                      /* Analyze EDID V2 */
10635    case 4:
10636       index = 0;
10637
10638       if(!(checkedid2(buffer))) {
10639          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10640                 "CRT2: EDID corrupt\n");
10641          return 0;
10642       }
10643
10644       if((buffer[0x41] & 0x0f) == 0x03) {
10645          index = 0x42 + 3;
10646          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10647                 "CRT2: Display supports TMDS input on primary interface\n");
10648       } else if((buffer[0x41] & 0xf0) == 0x30) {
10649          index = 0x46 + 3;
10650          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10651                 "CRT2: Display supports TMDS input on secondary interface\n");
10652       } else {
10653          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10654                 "CRT2: Display does not support TMDS video interface (0x%02x)\n", 
10655                 buffer[0x41]);
10656          return 0;
10657       }
10658
10659       paneltype = Panel_Custom;
10660       SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
10661       SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
10662       switch(xres) {
10663          case 800:
10664              if(yres == 600) {
10665                 paneltype = Panel_800x600;
10666                 checkexpand = TRUE;
10667              }
10668              break;
10669          case 1024:
10670              if(yres == 768) {
10671                 paneltype = Panel_1024x768;
10672                 checkexpand = TRUE;
10673              }
10674              break;
10675          case 1152:
10676              if(yres == 768) {
10677                 if(pSiS->VGAEngine == SIS_300_VGA) {
10678                    paneltype = Panel300_1152x768;
10679                 } else {
10680                    paneltype = Panel310_1152x768;
10681                 }
10682                 checkexpand = TRUE;
10683              }
10684              break;
10685          case 1280:
10686              if(yres == 960) {
10687                 if(pSiS->VGAEngine == SIS_315_VGA) {
10688                    paneltype = Panel310_1280x960;
10689                 } else {
10690                    paneltype = Panel300_1280x960;
10691                 }
10692              } else if(yres == 1024) {
10693                 paneltype = Panel_1280x1024;
10694                 checkexpand = TRUE;
10695              }
10696              /* 1280x768 treated as custom here */
10697              break;
10698          case 1400:
10699              if(pSiS->VGAEngine == SIS_315_VGA) {
10700                 if(yres == 1050) {
10701                    paneltype = Panel310_1400x1050;
10702                    checkexpand = TRUE;
10703                 }
10704              }
10705              break;
10706 #if 0    /* Treat this one as custom since we have no timing data yet */
10707          case 1600:
10708              if(pSiS->VGAEngine == SIS_315_VGA) {
10709                 if(yres == 1200) {
10710                    paneltype = Panel310_1600x1200;
10711                    checkexpand = TRUE;
10712                 }
10713              }
10714              break;
10715 #endif
10716       }
10717
10718       /* Determine if RGB18 or RGB24 */
10719       if(index) {
10720          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10721             cr37 |= 0x01;
10722          }
10723       }
10724
10725       if(checkexpand) {
10726          /* TODO - for now, we let the panel scale */
10727          cr37 |= 0x10;
10728       }
10729
10730       /* Now seek 4-Byte Timing codes and extract sync pol info */
10731       index = 0x80;
10732       if(buffer[0x7e] & 0x20) {                     /* skip Luminance Table (if provided) */
10733          lumsize = buffer[0x80] & 0x1f;
10734          if(buffer[0x80] & 0x80) lumsize *= 3;
10735          lumsize++;  /* luminance header byte */
10736          index += lumsize;
10737       }
10738       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
10739       index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
10740       numcodes = (buffer[0x7f] & 0xf8) >> 3;
10741       if(numcodes) {
10742          myindex = index;
10743          seekcode = (xres - 256) / 16;
10744          for(i=0; i<numcodes; i++) {
10745             if(buffer[myindex] == seekcode) break;
10746             myindex += 4;
10747          }
10748          if(buffer[myindex] == seekcode) {
10749             cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10750          } else {
10751             xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10752                 "CRT2: Unable to retrieve Sync polarity information\n");
10753          }
10754       } else {
10755          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10756              "CRT2: Unable to retrieve Sync polarity information\n");
10757       }
10758
10759       /* Now seek the detailed timing descriptions for custom panels */
10760       if(paneltype == Panel_Custom) {
10761
10762          SiS_Pr->CP_Supports64048075 = TRUE;
10763
10764          index += (numcodes * 4);
10765          numcodes = buffer[0x7f] & 0x07;
10766          for(i=0; i<numcodes; i++, index += 18) {
10767             xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10768             yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10769
10770             SiS_Pr->CP_HDisplay[i] = xres;
10771             SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10772             SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10773             SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10774             SiS_Pr->CP_HBlankStart[i] = xres + 1;
10775             SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10776
10777             SiS_Pr->CP_VDisplay[i] = yres;
10778             SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10779             SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10780             SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10781             SiS_Pr->CP_VBlankStart[i] = yres + 1;
10782             SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10783
10784             SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10785
10786             SiS_Pr->CP_DataValid[i] = TRUE;
10787
10788             if((SiS_Pr->CP_HDisplay[i] & 7)                                             ||
10789                (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])                      ||
10790                (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])                       ||
10791                (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])                         ||
10792                (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i])                     ||
10793                (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])                        ||
10794                (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])                          ||
10795                (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])                      ||
10796                (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])                       ||
10797                (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])                         ||
10798                (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])                      ||
10799                (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])                        ||
10800                (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])                          ||
10801                (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10802                 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))       ||
10803                (buffer[index + 17] & 0x80)) {
10804
10805                SiS_Pr->CP_DataValid[i] = FALSE;
10806
10807             } else {
10808
10809                SiS_Pr->CP_HaveCustomData = TRUE;
10810
10811                if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10812
10813                SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10814                SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10815                SiS_Pr->CP_SyncValid[i] = TRUE;
10816
10817                SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10818                SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10819
10820                /* We must assume the panel can scale, since we have
10821                 * no scaling data
10822                 */
10823                cr37 |= 0x10;
10824
10825             }
10826          }
10827
10828       }
10829
10830       break;
10831
10832    }
10833
10834    /* 1280x960 panels are always RGB24, unable to scale and use
10835     * high active sync polarity
10836     */
10837    if(pSiS->VGAEngine == SIS_315_VGA) {
10838       if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10839    } else {
10840       if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10841    }
10842
10843    for(i = 0; i < 7; i++) {
10844       if(SiS_Pr->CP_DataValid[i]) {
10845          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10846             "Non-standard LCD timing data no. %d:\n", i);
10847          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10848             "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10849             SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10850             SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10851          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10852             "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10853             SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10854             SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10855          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10856             "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10857          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10858             "   To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10859             SiS_Pr->CP_HDisplay[i],
10860             SiS_Pr->CP_VDisplay[i]);
10861       }
10862    }
10863
10864    if(paneltype) {
10865        if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10866        if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10867        cr37 &= 0xf1;
10868        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
10869        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xf1,cr37);
10870        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10871 #ifdef TWDEBUG
10872        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
10873         "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10874 #endif  
10875    }
10876    return 0;
10877 }
10878    
10879 USHORT
10880 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10881 {
10882    USHORT DDCdatatype,flag;
10883    BOOLEAN foundcrt = FALSE;
10884    int retry;
10885    unsigned char buffer[256];
10886
10887    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10888
10889    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10890    
10891    SiS_Pr->SiS_DDC_SecAddr = 0x00;
10892    
10893    /* Probe supported DA's */
10894    flag = SiS_ProbeDDC(SiS_Pr);
10895    if(flag & 0x10) {
10896       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;        /* EDID V2 (FP) */
10897       DDCdatatype = 4;
10898    } else if(flag & 0x08) {
10899       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;        /* EDID V2 (P&D-D Monitor) */
10900       DDCdatatype = 3;
10901    } else if(flag & 0x02) {
10902       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;        /* EDID V1 */
10903       DDCdatatype = 1;
10904    } else {
10905         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10906                 "Do DDC answer\n");
10907         return 0;                               /* no DDC support (or no device attached) */
10908    }
10909
10910    /* Read the entire EDID */
10911    retry = 2;
10912    do {
10913       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10914          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10915                 "CRT2: DDC read failed (attempt %d), %s\n",
10916                 (3-retry), (retry == 1) ? "giving up" : "retrying");
10917          retry--;
10918          if(retry == 0) return 0xFFFF;
10919       } else break;
10920    } while(1);
10921
10922    /* Analyze EDID. We don't have many chances to
10923     * distinguish a flat panel from a CRT...
10924     */
10925    switch(DDCdatatype) {
10926    case 1:
10927       if(!(checkedid1(buffer))) {
10928           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10929                 "CRT2: EDID corrupt\n");
10930           return 0;
10931       }
10932       if(buffer[0x14] & 0x80) {                 /* Display uses digital input */
10933           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10934                 "CRT2: Attached display expects digital input\n");
10935           return 0;
10936       }
10937       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10938       SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10939       foundcrt = TRUE;
10940       break;
10941    case 3:
10942    case 4:
10943       if(!(checkedid2(buffer))) {
10944           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10945                 "CRT2: EDID corrupt\n");
10946           return 0;
10947       }
10948       if( ((buffer[0x41] & 0x0f) != 0x01) &&    /* Display does not support analog input */
10949           ((buffer[0x41] & 0x0f) != 0x02) &&
10950           ((buffer[0x41] & 0xf0) != 0x10) &&
10951           ((buffer[0x41] & 0xf0) != 0x20) ) {
10952           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10953                 "CRT2: Attached display does not support analog input (0x%02x)\n",
10954                 buffer[0x41]);
10955           return 0;
10956       }
10957       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10958       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10959       foundcrt = TRUE;
10960       break;
10961    }
10962
10963    if(foundcrt) {
10964       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10965    }
10966    return(0);
10967 }
10968
10969 #endif
10970
10971 void
10972 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10973 {
10974   USHORT tempbl;
10975
10976   tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10977   tempbl = (((tempbl & tempbh) << 8) | tempax);
10978   SiS_SetCH70xx(SiS_Pr,tempbl);
10979 }
10980
10981 /* Generic I2C functions for Chrontel & DDC --------- */
10982
10983 void
10984 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10985 {
10986   SiS_SetSCLKHigh(SiS_Pr);
10987   SiS_WaitRetrace1(SiS_Pr);
10988
10989   SiS_SetSCLKLow(SiS_Pr);
10990   SiS_WaitRetrace1(SiS_Pr);
10991 }
10992
10993 USHORT
10994 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10995 {
10996    SiS_WaitRetrace1(SiS_Pr);
10997    return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10998 }
10999
11000 /* Set I2C start condition */
11001 /* This is done by a SD high-to-low transition while SC is high */
11002 USHORT
11003 SiS_SetStart(SiS_Private *SiS_Pr)
11004 {
11005   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                                /* (SC->low)  */
11006   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11007                   SiS_Pr->SiS_DDC_Index,
11008                   SiS_Pr->SiS_DDC_NData,
11009                   SiS_Pr->SiS_DDC_Data);                                   /* SD->high */
11010   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* SC->high */
11011   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11012                   SiS_Pr->SiS_DDC_Index,
11013                   SiS_Pr->SiS_DDC_NData,
11014                   0x00);                                                   /* SD->low = start condition */
11015   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* (SC->low) */
11016   return 0;
11017 }
11018
11019 /* Set I2C stop condition */
11020 /* This is done by a SD low-to-high transition while SC is high */
11021 USHORT
11022 SiS_SetStop(SiS_Private *SiS_Pr)
11023 {
11024   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                                /* (SC->low) */
11025   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11026                   SiS_Pr->SiS_DDC_Index,
11027                   SiS_Pr->SiS_DDC_NData,
11028                   0x00);                                                   /* SD->low   */
11029   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* SC->high  */
11030   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11031                   SiS_Pr->SiS_DDC_Index,
11032                   SiS_Pr->SiS_DDC_NData,
11033                   SiS_Pr->SiS_DDC_Data);                                   /* SD->high = stop condition */
11034   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* (SC->high) */
11035   return 0;
11036 }
11037
11038 /* Write 8 bits of data */
11039 USHORT
11040 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
11041 {
11042   USHORT i,flag,temp;
11043
11044   flag = 0x80;
11045   for(i=0; i<8; i++) {
11046     SiS_SetSCLKLow(SiS_Pr);                                                   /* SC->low */
11047     if(tempax & flag) {
11048       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11049                       SiS_Pr->SiS_DDC_Index,
11050                       SiS_Pr->SiS_DDC_NData,
11051                       SiS_Pr->SiS_DDC_Data);                                  /* Write bit (1) to SD */
11052     } else {
11053       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11054                       SiS_Pr->SiS_DDC_Index,
11055                       SiS_Pr->SiS_DDC_NData,
11056                       0x00);                                                  /* Write bit (0) to SD */
11057     }
11058     SiS_SetSCLKHigh(SiS_Pr);                                                  /* SC->high */
11059     flag >>= 1;
11060   }
11061   temp = SiS_CheckACK(SiS_Pr);                                                /* Check acknowledge */
11062   return(temp);
11063 }
11064
11065 USHORT
11066 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
11067 {
11068   USHORT i,temp,getdata;
11069
11070   getdata=0;
11071   for(i=0; i<8; i++) {
11072     getdata <<= 1;
11073     SiS_SetSCLKLow(SiS_Pr);
11074     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11075                     SiS_Pr->SiS_DDC_Index,
11076                     SiS_Pr->SiS_DDC_NData,
11077                     SiS_Pr->SiS_DDC_Data);
11078     SiS_SetSCLKHigh(SiS_Pr);
11079     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
11080     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
11081   }
11082   return(getdata);
11083 }
11084
11085 USHORT
11086 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
11087 {
11088   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11089                   SiS_Pr->SiS_DDC_Index,
11090                   SiS_Pr->SiS_DDC_NClk,
11091                   0x00);                                        /* SetSCLKLow()  */
11092   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
11093   return 0;
11094 }
11095
11096 USHORT
11097 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
11098 {
11099   USHORT temp, watchdog=1000;
11100
11101   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11102                   SiS_Pr->SiS_DDC_Index,
11103                   SiS_Pr->SiS_DDC_NClk,
11104                   SiS_Pr->SiS_DDC_Clk);                         /* SetSCLKHigh()  */
11105   do {
11106     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
11107   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
11108   if (!watchdog) {
11109 #ifdef TWDEBUG
11110         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
11111 #endif
11112         return 0xFFFF;
11113   }
11114   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
11115   return 0;
11116 }
11117
11118 /* Check I2C acknowledge */
11119 /* Returns 0 if ack ok, non-0 if ack not ok */
11120 USHORT
11121 SiS_CheckACK(SiS_Private *SiS_Pr)
11122 {
11123   USHORT tempah;
11124
11125   SiS_SetSCLKLow(SiS_Pr);                                          /* (SC->low) */
11126   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
11127                   SiS_Pr->SiS_DDC_Index,
11128                   SiS_Pr->SiS_DDC_NData,
11129                   SiS_Pr->SiS_DDC_Data);                           /* (SD->high) */
11130   SiS_SetSCLKHigh(SiS_Pr);                                         /* SC->high = clock impulse for ack */
11131   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
11132   SiS_SetSCLKLow(SiS_Pr);                                          /* SC->low = end of clock impulse */
11133   if(tempah & SiS_Pr->SiS_DDC_Data) return(1);                     /* Ack OK if bit = 0 */
11134   else return(0);
11135 }
11136
11137 /* End of I2C functions ----------------------- */
11138
11139
11140 /* =============== SiS 315/330 O.E.M. ================= */
11141
11142 #ifdef SIS315H
11143
11144 static USHORT
11145 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11146 {
11147   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11148   USHORT romptr;
11149
11150   if(HwInfo->jChipType < SIS_330) {
11151      romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
11152      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
11153         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
11154   } else {
11155      romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
11156      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
11157         romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
11158   }
11159   return(romptr);
11160 }
11161
11162 static USHORT
11163 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11164 {
11165   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11166   USHORT romptr;
11167
11168   if(HwInfo->jChipType < SIS_330) {
11169      romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
11170      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
11171         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
11172   } else {
11173      romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
11174      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
11175         romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
11176   }
11177   return(romptr);
11178 }
11179
11180 static USHORT
11181 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11182 {
11183   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11184   USHORT romptr;
11185
11186   if(HwInfo->jChipType < SIS_330) {
11187      romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
11188      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
11189         romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
11190   } else {
11191      romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8);
11192      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
11193         romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8);
11194   }
11195   return(romptr);
11196 }
11197
11198 static USHORT
11199 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11200 {
11201   USHORT index;
11202
11203   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11204      if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
11205         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
11206            index >>= 4;
11207            index *= 3;
11208            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
11209            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
11210            return index;
11211         }
11212      }
11213   }
11214
11215   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
11216   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
11217   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
11218   index--;
11219   index *= 3;
11220   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
11221   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
11222   return index;
11223 }
11224
11225 static USHORT
11226 GetLCDPtrIndex(SiS_Private *SiS_Pr)
11227 {
11228   USHORT index;
11229
11230   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
11231   index--;
11232   index *= 3;
11233   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
11234   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
11235
11236   return index;
11237 }
11238
11239 static USHORT
11240 GetTVPtrIndex(SiS_Private *SiS_Pr)
11241 {
11242   USHORT index;
11243
11244   index = 0;
11245   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
11246   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
11247
11248   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
11249
11250   index <<= 1;
11251
11252   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
11253      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
11254      index++;
11255   }
11256
11257   return index;
11258 }
11259
11260 static ULONG
11261 GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
11262 {
11263    USHORT index = 0, temp = 0;
11264
11265    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
11266    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
11267    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
11268    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
11269    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
11270       index = 4;
11271       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
11272       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
11273    }
11274
11275    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11276       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
11277          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
11278          index += 8;
11279          temp++;
11280       }
11281       temp += 0x0100;
11282    }
11283    return(ULONG)(index | (temp << 16));
11284 }
11285
11286 static int
11287 GetOEMTVPtr661(SiS_Private *SiS_Pr)
11288 {
11289    int index = 0;
11290
11291    if(SiS_Pr->SiS_TVMode & TVSetPAL)       index = 2;
11292    if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
11293    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
11294    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
11295    if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
11296
11297    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
11298
11299    return index;
11300 }
11301
11302 static void
11303 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11304 {
11305   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11306   USHORT delay=0,index,myindex,temp,romptr=0;
11307   BOOLEAN dochiptest = TRUE;
11308
11309   /* Find delay (from ROM, internal tables, PCI subsystem) */
11310
11311   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {                    /* ------------ VGA */
11312      
11313      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11314         romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
11315         if(!romptr) return;
11316         delay = ROMAddr[romptr];
11317      } else {
11318         delay = 0x04;
11319         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
11320            if(IS_SIS650) {
11321               delay = 0x0a;
11322            } else if(IS_SIS740) {
11323               delay = 0x00;
11324            } else if(HwInfo->jChipType < SIS_330) {
11325               delay = 0x0c;
11326            } else {
11327               delay = 0x0c;
11328            }
11329         }
11330         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11331            delay = 0x00;
11332         }
11333      }
11334
11335   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ---------- LCD/LCDA */
11336
11337      BOOLEAN gotitfrompci = FALSE;
11338
11339      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
11340
11341      /* Could we detect a PDC for LCD? If yes, use it */
11342
11343      if(SiS_Pr->PDC) {
11344         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11345            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDC & 0x0f) << 4));
11346         }
11347         return;
11348      }
11349
11350      /* This is a piece of typical SiS crap: They code the OEM LCD
11351       * delay into the code, at no defined place in the BIOS.
11352       * We now have to start doing a PCI subsystem check here.
11353       */
11354
11355      switch(SiS_Pr->SiS_CustomT) {
11356      case CUT_COMPAQ1280:
11357      case CUT_COMPAQ12802:
11358         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
11359            gotitfrompci = TRUE;
11360            dochiptest = FALSE;
11361            delay = 0x03;
11362         }
11363         break;
11364      case CUT_CLEVO1400:
11365      case CUT_CLEVO14002:
11366         /* if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { */
11367            gotitfrompci = TRUE;
11368            dochiptest = FALSE;
11369            delay = 0x02;
11370         /* } */
11371         break;
11372      case CUT_CLEVO1024:
11373      case CUT_CLEVO10242:
11374         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
11375            gotitfrompci = TRUE;
11376            dochiptest = FALSE;
11377            delay = 0x33;
11378            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11379            delay &= 0x0f;
11380         }
11381         break;
11382      }
11383
11384      /* Could we find it through the PCI ID? If no, use ROM or table */
11385
11386      if(!gotitfrompci) {
11387
11388         index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
11389         myindex = GetLCDPtrIndex(SiS_Pr);
11390
11391         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11392
11393            if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
11394
11395               if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11396                  /* Always use the second pointer on 650; some BIOSes */
11397                  /* still carry old 301 data at the first location    */
11398                  /* romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  */
11399                  /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
11400                  romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
11401                  if(!romptr) return;
11402                  delay = ROMAddr[(romptr + index)];
11403               } else {
11404                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
11405               }
11406
11407           } else {
11408
11409              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
11410              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
11411                 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
11412
11413           }
11414
11415         } else if((ROMAddr) && SiS_Pr->SiS_UseROM &&
11416                   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
11417
11418            /* Data for 1280x1024 wrong in BIOS */
11419            romptr = GetLCDromptr(SiS_Pr, HwInfo);
11420            if(!romptr) return;
11421            delay = ROMAddr[(romptr + index)];
11422
11423         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11424
11425            if(IS_SIS740) delay = 0x03;
11426            else          delay = 0x00;
11427
11428         } else {
11429
11430            delay = SiS310_LCDDelayCompensation_301[myindex];
11431            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
11432               if(IS_SIS740) delay = 0x01;
11433               else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
11434            } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
11435               if(IS_SIS740) delay = 0x01;
11436               else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
11437            }
11438
11439         }
11440
11441      }  /* got it from PCI */
11442
11443      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11444         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
11445         dochiptest = FALSE;
11446      }
11447      
11448   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /* ------------ TV */
11449
11450      index = GetTVPtrIndex(SiS_Pr);
11451      
11452      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11453
11454         if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
11455
11456            if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11457               /* Always use the second pointer on 650; some BIOSes */
11458               /* still carry old 301 data at the first location    */
11459               /* romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);  */
11460               /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
11461               romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
11462               if(!romptr) return;
11463               delay = ROMAddr[romptr + index];
11464
11465            } else {
11466
11467               delay = SiS310_TVDelayCompensation_301B[index];
11468
11469            }
11470
11471         } else {
11472
11473            switch(SiS_Pr->SiS_CustomT) {
11474            case CUT_COMPAQ1280:
11475            case CUT_COMPAQ12802:
11476            case CUT_CLEVO1400:
11477            case CUT_CLEVO14002:
11478               delay = 0x02;
11479               dochiptest = FALSE;
11480               break;
11481            case CUT_CLEVO1024:
11482            case CUT_CLEVO10242:
11483               delay = 0x03;
11484               dochiptest = FALSE;
11485               break;
11486            default:
11487               delay = SiS310_TVDelayCompensation_651301LV[index];
11488               if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
11489                  delay = SiS310_TVDelayCompensation_651302LV[index];
11490               }
11491            }
11492         }
11493
11494      } else if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11495
11496         romptr = GetTVromptr(SiS_Pr, HwInfo);
11497         if(!romptr) return;
11498         delay = ROMAddr[romptr + index];
11499
11500      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11501
11502         delay = SiS310_TVDelayCompensation_LVDS[index];
11503
11504      } else {
11505
11506         delay = SiS310_TVDelayCompensation_301[index];
11507         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11508            if(IS_SIS740) {
11509               delay = SiS310_TVDelayCompensation_740301B[index];
11510            } else {
11511               delay = SiS310_TVDelayCompensation_301B[index];
11512            }
11513         }
11514
11515      }
11516
11517      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {  /* LCDA */
11518         delay &= 0x0f;
11519         dochiptest = FALSE;
11520      }
11521     
11522   } else return;
11523
11524   /* Write delay */
11525
11526   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11527
11528      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
11529
11530         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11531         if(temp == 8) {         /* 1400x1050 BIOS (COMPAL) */
11532            delay &= 0x0f;
11533            delay |= 0xb0;
11534         } else if(temp == 6) {
11535            delay &= 0x0f;
11536            delay |= 0xc0;
11537         } else if(temp > 7) {   /* 1280x1024 BIOS (which one?) */
11538            delay = 0x35;
11539         }
11540         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11541
11542      } else {
11543
11544         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11545
11546      }
11547
11548   } else {  /* LVDS */
11549
11550      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11551         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11552      } else {
11553         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
11554            delay <<= 4;
11555            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
11556         } else {
11557            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11558         }
11559      }
11560
11561   }
11562
11563 }
11564
11565 static void
11566 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11567                USHORT ModeNo,USHORT ModeIdIndex)
11568 {
11569   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11570   USHORT index,temp,temp1,romptr=0;
11571
11572   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11573
11574   if(ModeNo<=0x13)
11575      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
11576   else
11577      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
11578
11579   temp = GetTVPtrIndex(SiS_Pr);
11580   temp >>= 1;     /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11581   temp1 = temp;
11582
11583   if(ROMAddr && SiS_Pr->SiS_UseROM) {
11584      if(HwInfo->jChipType >= SIS_661) {
11585         romptr = ROMAddr[0x260] | (ROMAddr[0x261] << 8);
11586         temp1 = GetOEMTVPtr661(SiS_Pr);
11587         temp1 >>= 1;
11588      } else if(HwInfo->jChipType >= SIS_330) {
11589         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
11590      } else {
11591         romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
11592      }
11593   }
11594
11595   if(romptr) {
11596      temp1 <<= 1;
11597      temp = ROMAddr[romptr + temp1 + index];
11598   } else {
11599      temp = SiS310_TVAntiFlick1[temp][index];
11600   }
11601   temp <<= 4;
11602
11603   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
11604 }
11605
11606 static void
11607 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11608                USHORT ModeNo,USHORT ModeIdIndex)
11609 {
11610   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11611   USHORT index,temp,temp1,romptr=0;
11612
11613   temp = GetTVPtrIndex(SiS_Pr);
11614   temp >>= 1;                   /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11615   temp1 = temp;
11616
11617   if(ModeNo<=0x13)
11618      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
11619   else
11620      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11621
11622   if(ROMAddr && SiS_Pr->SiS_UseROM) {
11623      if(HwInfo->jChipType >= SIS_661) {
11624         romptr = ROMAddr[0x26c] | (ROMAddr[0x26d] << 8);
11625         temp1 = GetOEMTVPtr661(SiS_Pr);
11626         temp1 >>= 1;
11627      } else if(HwInfo->jChipType >= SIS_330) {
11628         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
11629      } else {
11630         romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
11631      }
11632   }
11633
11634   if(romptr) {
11635      temp1 <<= 1;
11636      temp = ROMAddr[romptr + temp1 + index];
11637   } else {
11638      temp = SiS310_TVEdge1[temp][index];
11639   }
11640   temp <<= 5;
11641   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
11642 }
11643
11644 static void
11645 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11646            USHORT ModeNo,USHORT ModeIdIndex)
11647 {
11648   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11649   USHORT index, myindex, oldindex,temp, i, j, flag1 = 0, flag2 = 0, romptr = 0;
11650   ULONG  lindex;
11651
11652   if(ModeNo<=0x13) {
11653     index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
11654   } else {
11655     index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
11656   }
11657
11658   oldindex = index;
11659
11660   if((HwInfo->jChipType >= SIS_661) && ROMAddr && SiS_Pr->SiS_UseROM) {
11661      if(ModeNo > 0x13) {
11662         index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndexROM661;
11663      }
11664      lindex = GetOEMTVPtr661_2(SiS_Pr);
11665      if(lindex & 0x00ff0000) flag1 = 1;
11666      if(lindex & 0xff000000) flag2 = 1;
11667      lindex &= 0xffff;
11668
11669      /* NTSC-J: Use PAL filters */
11670      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) lindex = 1;
11671
11672      romptr = ROMAddr[0x268] | (ROMAddr[0x269] << 8);
11673      if(flag1) myindex = index * 7;
11674      else      myindex = index << 2;
11675
11676      if(romptr) {
11677         romptr += (lindex << 1);
11678         romptr = (ROMAddr[romptr] | (ROMAddr[romptr+1] << 8)) + myindex;
11679         if(romptr) {
11680            if((!flag1) && (flag2)) {
11681               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,0x00);
11682               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,0x00);
11683               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,0x00);
11684               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,ROMAddr[romptr++]);
11685            } else {
11686               for(i=0x35; i<=0x38; i++) {
11687                  SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
11688               }
11689            }
11690            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11691               for(j=0, i=0x48; i<=0x4a; i++, j++) {
11692                  SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
11693               }
11694            }
11695            return;
11696         }
11697      }
11698   }
11699
11700   index = oldindex;
11701
11702   temp = GetTVPtrIndex(SiS_Pr);
11703   temp >>= 1;                   /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11704
11705   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)        temp = 1;  /* NTSC-J uses PAL */
11706   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
11707   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
11708   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
11709
11710   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11711      for(i=0x35, j=0; i<=0x38; i++, j++) {
11712         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11713      }
11714      for(i=0x48; i<=0x4A; i++, j++) {
11715         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11716      }
11717   } else {
11718      for(i=0x35, j=0; i<=0x38; i++, j++) {
11719         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
11720      }
11721   }
11722 }
11723
11724 static void
11725 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11726              USHORT ModeNo,USHORT ModeIdIndex)
11727 {
11728   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11729   USHORT index,temp,i,j,resinfo,romptr=0;
11730   ULONG  lindex;
11731
11732   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11733
11734   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11735   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11736
11737   if(HwInfo->jChipType >= SIS_661) {
11738      lindex = GetOEMTVPtr661_2(SiS_Pr) & 0xffff;
11739      lindex <<= 2;
11740      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11741         romptr = ROMAddr[0x264] | (ROMAddr[0x265] << 8);
11742      }
11743      if(romptr) {
11744         romptr += lindex;
11745         for(j=0, i=0x31; i<=0x34; i++, j++) {
11746            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11747         }
11748      } else {
11749         for(j=0, i=0x31; i<=0x34; i++, j++) {
11750            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11751         }
11752      }
11753      return;
11754   }
11755
11756   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11757   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11758
11759   if(ModeNo<=0x13) {
11760      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11761   } else {
11762      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11763   }
11764
11765   temp = GetTVPtrIndex(SiS_Pr);
11766   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
11767    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
11768    */
11769   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11770      romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
11771      if(HwInfo->jChipType >= SIS_330) {
11772         romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
11773      }
11774      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11775         romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
11776         if(HwInfo->jChipType >= SIS_330) {
11777            romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
11778         }
11779         if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11780            romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
11781            if(HwInfo->jChipType >= SIS_330) {
11782               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
11783            }
11784         }
11785      }
11786   }
11787   if(romptr) {
11788      romptr += (temp << 2);
11789      for(j=0, i=0x31; i<=0x34; i++, j++) {
11790         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11791      }
11792   } else {
11793      index = temp % 2;
11794      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
11795      for(j=0, i=0x31; i<=0x34; i++, j++) {
11796         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11797            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11798         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11799            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11800         else
11801            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11802      }
11803   }
11804
11805   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11806      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11807         if((resinfo == SIS_RI_640x480) ||
11808            (resinfo == SIS_RI_800x600)) {
11809            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11810            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11811            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11812            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11813         } else if(resinfo == SIS_RI_1024x768) {
11814            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11815            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11816            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11817            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11818         }
11819      }
11820   }
11821 }
11822
11823 void
11824 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11825                   USHORT ModeNo,USHORT ModeIdIndex)
11826 {
11827    SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11828
11829    if(SiS_Pr->UseCustomMode) return;
11830
11831    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11832       SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11833       SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11834       SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11835       if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
11836          SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11837       }
11838    }
11839 }
11840
11841 static void
11842 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11843                 USHORT ModeIdIndex, USHORT RTI)
11844 {
11845    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11846    USHORT delay = 0, romptr = 0, index;
11847    UCHAR  *myptr = NULL;
11848    UCHAR  temp;
11849
11850    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11851       return;
11852
11853    delay = SiS_Pr->SiS_RefIndex[RTI].Ext_PDC;
11854
11855    delay &= 0xf0;
11856    delay >>= 4;
11857    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) delay <<= 12;  /* BIOS: 8, wrong */
11858
11859    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11860       index = GetOEMTVPtr661(SiS_Pr);
11861       if((ROMAddr) && SiS_Pr->SiS_UseROM) {
11862          romptr = ROMAddr[0x25c] | (ROMAddr[0x25d] << 8);
11863          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11864             romptr = ROMAddr[0x25e] | (ROMAddr[0x25f] << 8);
11865          }
11866       }
11867       if(romptr) myptr = &ROMAddr[romptr];
11868       if(!myptr) {
11869          myptr = (UCHAR *)SiS_TVDelay661_301;
11870          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11871             myptr = (UCHAR *)SiS_TVDelay661_301B;
11872          }
11873       }
11874       delay = myptr[index];
11875       if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) delay >>= 4;  /* Should test dual edge */
11876    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11877       if(SiS_Pr->PDC) {
11878          delay = SiS_Pr->PDC & 0x0f;
11879          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11880             delay |= (delay << 12);
11881          }
11882       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
11883          delay = 0x4444;  /* TEST THIS */
11884       } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11885          myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
11886          if(myptr) delay = myptr[4];
11887          else delay = 0x44;
11888          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11889             delay |= (delay << 8);
11890          }
11891       }
11892    }
11893
11894    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2d);
11895    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToRAMDAC)) {
11896       temp &= 0xf0;
11897       temp |= (delay & 0x000f);
11898    }
11899    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11900       temp &= 0x0f;
11901       temp |= ((delay & 0xf000) >> 8);
11902    }
11903    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,temp);
11904 }
11905
11906 static void
11907 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11908 {
11909    USHORT infoflag;
11910    UCHAR temp;
11911
11912    infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11913    if(ModeNo <= 0x13) {
11914       infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11915    }
11916    infoflag &= 0xc0;
11917    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11918       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
11919       if(temp & 0x20) infoflag = temp;
11920       if(temp & 0x01) infoflag |= 0x01;
11921    }
11922    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11923       temp = 0x0c;
11924       if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
11925       temp |= (infoflag >> 6);
11926       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11927    }
11928    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11929       temp = 0;
11930       if(infoflag & 0x01) temp |= 0x80;
11931       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11932       temp = 0x30;
11933       if(infoflag & 0x01) temp = 0x20;
11934       infoflag &= 0xc0;
11935       temp |= infoflag;
11936       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11937    }
11938 }
11939
11940 static void
11941 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11942 {
11943    UCHAR *myptr;
11944
11945    if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11946       if(SiS_Pr->LVDSHL != -1) {
11947          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11948       }
11949    }
11950
11951    myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
11952    if(myptr) {
11953       if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11954          if(SiS_Pr->LVDSHL == -1) {
11955             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE0,myptr[1] & 0x1f);
11956          } else {
11957             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE3,myptr[1] & 0x1c);
11958          }
11959       }
11960       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0x3f,myptr[2] & 0xc0);
11961    }
11962 }
11963
11964 void
11965 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11966                   USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11967 {
11968    if(SiS_Pr->SiS_VBType & VB_SISVB) {
11969
11970       SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11971
11972       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11973          SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11974          SetPanelParms661(SiS_Pr,HwInfo);
11975       }
11976
11977       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11978          SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11979          SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11980          SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11981          if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
11982             SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11983          }
11984       }
11985    }
11986 }
11987
11988 /* FinalizeLCD
11989  * This finalizes some CRT2 registers for the very panel used.
11990  * If we have a backup if these registers, we use it; otherwise
11991  * we set the register according to most BIOSes. However, this
11992  * function looks quite different in every BIOS, so you better
11993  * pray that we have a backup...
11994  */
11995 void
11996 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11997                 PSIS_HW_INFO HwInfo)
11998 {
11999   USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
12000   USHORT resinfo,modeflag;
12001
12002   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
12003
12004   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
12005      if(SiS_Pr->LVDSHL != -1) {
12006         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
12007      }
12008   }
12009
12010   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
12011   if(SiS_Pr->UseCustomMode) return;
12012
12013   switch(SiS_Pr->SiS_CustomT) {
12014   case CUT_COMPAQ1280:
12015   case CUT_COMPAQ12802:
12016   case CUT_CLEVO1400:
12017   case CUT_CLEVO14002:
12018      return;
12019   }
12020
12021   if(ModeNo <= 0x13) {
12022      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
12023      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
12024   } else {
12025      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
12026      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
12027   }
12028
12029   if(IS_SIS650) {
12030      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
12031         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
12032            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
12033         } else {
12034            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
12035         }
12036      }
12037   }
12038
12039   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
12040      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12041         /* Maybe all panels? */
12042         if(SiS_Pr->LVDSHL == -1) {
12043            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
12044         }
12045         return;
12046      }
12047   }
12048
12049   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
12050      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
12051         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12052            if(SiS_Pr->LVDSHL == -1) {
12053               /* Maybe all panels? */
12054               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
12055            }
12056            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
12057               tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
12058               if(tempch == 3) {
12059                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
12060                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
12061                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
12062                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
12063               }
12064            }
12065            return;
12066         }
12067      }
12068   }
12069
12070   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
12071      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12072 #ifdef SET_EMI
12073         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
12074            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
12075            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
12076            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
12077         }
12078 #endif
12079      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
12080         if(SiS_Pr->LVDSHL == -1) {
12081            /* Maybe ACER only? */
12082            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
12083         }
12084      }
12085      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
12086      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
12087         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
12088            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
12089         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12090            if(tempch == 0x03) {
12091               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
12092               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
12093               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
12094               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
12095            }
12096            if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
12097               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
12098               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
12099               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
12100               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
12101               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
12102               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
12103               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
12104               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
12105               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
12106               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
12107            } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {  /* 1.10.8w */
12108               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
12109               if(ModeNo <= 0x13) {
12110                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
12111                  if((resinfo == 0) || (resinfo == 2)) return;
12112                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
12113                  if((resinfo == 1) || (resinfo == 3)) return;
12114               }
12115               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
12116               if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
12117                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
12118 #if 0
12119                  tempbx = 806;  /* 0x326 */                      /* other older BIOSes */
12120                  tempbx--;
12121                  temp = tempbx & 0xff;
12122                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
12123                  temp = (tempbx >> 8) & 0x03;
12124                  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
12125 #endif
12126               }
12127            } else if(ModeNo <= 0x13) {
12128               if(ModeNo <= 1) {
12129                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
12130                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
12131                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
12132                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
12133               }
12134               if(!(modeflag & HalfDCLK)) {
12135                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
12136                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
12137                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
12138                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
12139                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
12140                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
12141                  if(ModeNo == 0x12) {
12142                     switch(tempch) {
12143                        case 0:
12144                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
12145                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
12146                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
12147                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
12148                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
12149                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
12150                           break;
12151                        case 2:
12152                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
12153                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
12154                           break;
12155                        case 3:
12156                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
12157                           break;
12158                     }
12159                  }
12160               }
12161            }
12162         }
12163      } else {
12164         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
12165         tempcl &= 0x0f;
12166         tempbh &= 0x70;
12167         tempbh >>= 4;
12168         tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
12169         tempbx = (tempbh << 8) | tempbl;
12170         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12171            if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
12172               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
12173                  tempbx = 770;
12174               } else {
12175                  if(tempbx > 770) tempbx = 770;
12176                  if(SiS_Pr->SiS_VGAVDE < 600) {
12177                     tempax = 768 - SiS_Pr->SiS_VGAVDE;
12178                     tempax >>= 4;                                /* 1.10.7w; 1.10.6s: 3;  */
12179                     if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
12180                     tempbx -= tempax;
12181                  }
12182               }
12183            } else return;
12184         }
12185         temp = tempbx & 0xff;
12186         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
12187         temp = ((tempbx & 0xff00) >> 4) | tempcl;
12188         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
12189      }
12190   }
12191 }
12192
12193 #endif
12194
12195 /*  =================  SiS 300 O.E.M. ================== */
12196
12197 #ifdef SIS300
12198
12199 void
12200 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12201                USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
12202 {
12203   USHORT crt2crtc=0, modeflag, myindex=0;
12204   UCHAR  temp;
12205   int i;
12206
12207   if(ModeNo <= 0x13) {
12208      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
12209      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
12210   } else {
12211      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
12212      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
12213   }
12214
12215   crt2crtc &= 0x3f;
12216
12217   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
12218      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
12219   }
12220
12221   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
12222      if(modeflag & HalfDCLK) myindex = 1;
12223
12224      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
12225         for(i=0; i<7; i++) {
12226            if(barco_p1[myindex][crt2crtc][i][0]) {
12227               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
12228                               barco_p1[myindex][crt2crtc][i][0],
12229                               barco_p1[myindex][crt2crtc][i][2],
12230                               barco_p1[myindex][crt2crtc][i][1]);
12231            }
12232         }
12233      }
12234      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
12235      if(temp & 0x80) {
12236         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
12237         temp++;
12238         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
12239      }
12240   }
12241 }
12242
12243 static USHORT
12244 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
12245 {
12246   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12247   USHORT tempbx=0,romptr=0;
12248   UCHAR customtable300[] = {
12249         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
12250         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
12251   };
12252   UCHAR customtable630[] = {
12253         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
12254         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
12255   };
12256
12257   if(HwInfo->jChipType == SIS_300) {
12258
12259     tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
12260     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
12261     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
12262        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
12263     }
12264     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12265        if(ROMAddr[0x235] & 0x80) {
12266           tempbx = SiS_Pr->SiS_LCDTypeInfo;
12267           if(Flag) {
12268              romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
12269              if(romptr) {
12270                 tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
12271              } else {
12272                 tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
12273              }
12274              if(tempbx == 0xFF) return 0xFFFF;
12275           }
12276           tempbx <<= 1;
12277           if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
12278        }
12279     }
12280
12281   } else {
12282
12283     if(Flag) {
12284        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12285           romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
12286           if(romptr) {
12287              tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
12288           } else {
12289              tempbx = 0xff;
12290           }
12291        } else {
12292           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
12293        }
12294        if(tempbx == 0xFF) return 0xFFFF;
12295        tempbx <<= 2;
12296        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
12297        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
12298        return tempbx;
12299     }
12300     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
12301     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
12302     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
12303   }
12304   return tempbx;
12305 }
12306
12307 static void
12308 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12309                USHORT ModeNo,USHORT ModeIdIndex)
12310 {
12311   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12312   USHORT index,temp,romptr=0;
12313
12314   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
12315
12316   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12317      if(!(ROMAddr[0x237] & 0x01)) return;
12318      if(!(ROMAddr[0x237] & 0x02)) return;
12319      romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
12320   }
12321
12322   /* The Panel Compensation Delay should be set according to tables
12323    * here. Unfortunately, various BIOS versions don't case about
12324    * a uniform way using eg. ROM byte 0x220, but use different
12325    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
12326    * Thus we don't set this if the user select a custom pdc or if
12327    * we otherwise detected a valid pdc.
12328    */
12329   if(SiS_Pr->PDC) return;
12330
12331   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
12332
12333   if(SiS_Pr->UseCustomMode)
12334      index = 0;
12335   else
12336      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
12337
12338   if(HwInfo->jChipType != SIS_300) {
12339      if(romptr) {
12340         romptr += (temp * 2);
12341         romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12342         romptr += index;
12343         temp = ROMAddr[romptr];
12344      } else {
12345         if(SiS_Pr->SiS_VBType & VB_SISVB) {
12346            temp = SiS300_OEMLCDDelay2[temp][index];
12347         } else {
12348            temp = SiS300_OEMLCDDelay3[temp][index];
12349         }
12350      }
12351   } else {
12352      if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
12353         if(romptr) {
12354            romptr += (temp * 2);
12355            romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12356            romptr += index;
12357            temp = ROMAddr[romptr];
12358         } else {
12359            temp = SiS300_OEMLCDDelay5[temp][index];
12360         }
12361      } else {
12362         if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12363            romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
12364            if(romptr) {
12365               romptr += (temp * 2);
12366               romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12367               romptr += index;
12368               temp = ROMAddr[romptr];
12369            } else {
12370               temp = SiS300_OEMLCDDelay4[temp][index];
12371            }
12372         } else {
12373            temp = SiS300_OEMLCDDelay4[temp][index];
12374         }
12375      }
12376   }
12377   temp &= 0x3c;
12378   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
12379 }
12380
12381 static void
12382 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12383               USHORT ModeNo,USHORT ModeIdIndex)
12384 {
12385 #if 0  /* Unfinished; Data table missing */
12386   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12387   USHORT index,temp;
12388
12389   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12390      if(!(ROMAddr[0x237] & 0x01)) return;
12391      if(!(ROMAddr[0x237] & 0x04)) return;
12392      /* No rom pointer in BIOS header! */
12393   }
12394
12395   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
12396   if(temp = 0xFFFF) return;
12397
12398   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
12399   for(i=0x14, j=0; i<=0x17; i++, j++) {
12400       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
12401   }
12402   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
12403
12404   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
12405   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
12406   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
12407   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
12408   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
12409       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
12410   }
12411 #endif
12412 }
12413
12414 static USHORT
12415 GetOEMTVPtr(SiS_Private *SiS_Pr)
12416 {
12417   USHORT index;
12418
12419   index = 0;
12420   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
12421   if(SiS_Pr->SiS_VBType & VB_SISVB) {
12422      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
12423      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
12424      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
12425   } else {
12426      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
12427      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
12428   }
12429   return index;
12430 }
12431
12432 static void
12433 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12434               USHORT ModeNo,USHORT ModeIdIndex)
12435 {
12436   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12437   USHORT index,temp,romptr=0;
12438
12439   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12440      if(!(ROMAddr[0x238] & 0x01)) return;
12441      if(!(ROMAddr[0x238] & 0x02)) return;
12442      romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8);
12443   }
12444
12445   temp = GetOEMTVPtr(SiS_Pr);
12446
12447   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
12448
12449   if(romptr) {
12450      romptr += (temp * 2);
12451      romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12452      romptr += index;
12453      temp = ROMAddr[romptr];
12454   } else {
12455      if(SiS_Pr->SiS_VBType & VB_SISVB) {
12456         temp = SiS300_OEMTVDelay301[temp][index];
12457      } else {
12458         temp = SiS300_OEMTVDelayLVDS[temp][index];
12459      }
12460   }
12461   temp &= 0x3c;
12462   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
12463 }
12464
12465 static void
12466 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12467                   USHORT ModeNo, USHORT ModeIdIndex)
12468 {
12469   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12470   USHORT index,temp,romptr=0;
12471
12472   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12473      if(!(ROMAddr[0x238] & 0x01)) return;
12474      if(!(ROMAddr[0x238] & 0x04)) return;
12475      romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8);
12476   }
12477
12478   temp = GetOEMTVPtr(SiS_Pr);
12479
12480   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
12481
12482   if(romptr) {
12483      romptr += (temp * 2);
12484      romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12485      romptr += index;
12486      temp = ROMAddr[romptr];
12487   } else {
12488      temp = SiS300_OEMTVFlicker[temp][index];
12489   }
12490   temp &= 0x70;
12491   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
12492 }
12493
12494 static void
12495 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12496                 USHORT ModeNo,USHORT ModeIdIndex)
12497 {
12498   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12499   USHORT index,i,j,temp,romptr=0;
12500
12501   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12502
12503   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
12504
12505   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12506      if(!(ROMAddr[0x238] & 0x01)) return;
12507      if(!(ROMAddr[0x238] & 0x08)) return;
12508      romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8);
12509   }
12510
12511   temp = GetOEMTVPtr(SiS_Pr);
12512
12513   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12514
12515   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12516      for(i=0x31, j=0; i<=0x34; i++, j++) {
12517         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12518      }
12519   } else {
12520      if(romptr) {
12521         romptr += (temp * 2);
12522         romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12523         romptr += (index * 4);
12524         for(i=0x31, j=0; i<=0x34; i++, j++) {
12525            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12526         }
12527      } else {
12528         for(i=0x31, j=0; i<=0x34; i++, j++) {
12529            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
12530         }
12531      }
12532   }
12533 }
12534
12535 static void
12536 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12537               USHORT ModeNo,USHORT ModeIdIndex)
12538 {
12539   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
12540   USHORT index,temp,i,j,romptr=0;
12541
12542   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12543
12544   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
12545      if(!(ROMAddr[0x238] & 0x01)) return;
12546      if(!(ROMAddr[0x238] & 0x10)) return;
12547      romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8);
12548   }
12549
12550   temp = GetOEMTVPtr(SiS_Pr);
12551
12552   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
12553   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
12554   /* NTSCJ uses NTSC filters */
12555
12556   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12557
12558   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12559       for(i=0x35, j=0; i<=0x38; i++, j++) {
12560         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12561       }
12562       for(i=0x48; i<=0x4A; i++, j++) {
12563         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12564       }
12565   } else {
12566       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
12567          romptr += (temp * 2);
12568          romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
12569          romptr += (index * 4);
12570          for(i=0x35, j=0; i<=0x38; i++, j++) {
12571             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12572          }
12573       } else {
12574          for(i=0x35, j=0; i<=0x38; i++, j++) {
12575             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
12576          }
12577       }
12578   }
12579 }
12580
12581 static USHORT
12582 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12583 {
12584    USHORT ModeIdIndex;
12585    UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
12586
12587    if(*ModeNo <= 5) *ModeNo |= 1;
12588
12589    for(ModeIdIndex=0; ; ModeIdIndex++) {
12590       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
12591       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
12592    }
12593
12594    if(*ModeNo != 0x07) {
12595       if(*ModeNo > 0x03) return ModeIdIndex;
12596       if(VGAINFO & 0x80) return ModeIdIndex;
12597       ModeIdIndex++;
12598    }
12599
12600    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
12601                                        /* else 350 lines */
12602    return ModeIdIndex;
12603 }
12604
12605 void
12606 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12607                   USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
12608 {
12609   USHORT OEMModeIdIndex=0;
12610
12611   if(!SiS_Pr->UseCustomMode) {
12612      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
12613      if(!(OEMModeIdIndex)) return;
12614   }
12615
12616   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12617      SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12618      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12619         SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12620      }
12621   }
12622   if(SiS_Pr->UseCustomMode) return;
12623   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12624      SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
12625      if(SiS_Pr->SiS_VBType & VB_SISVB) {
12626         SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12627         SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12628         SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12629      }
12630   }
12631 }
12632 #endif
12633