VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / video / sis / init301.c
1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4  * Mode initializing code (CRT2 section)
5  * for SiS 300/305/540/630/730 and
6  *     SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
7  * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
8  *
9  * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
10  *
11  * If distributed as part of the Linux kernel, the following license terms
12  * apply:
13  *
14  * * This program is free software; you can redistribute it and/or modify
15  * * it under the terms of the GNU General Public License as published by
16  * * the Free Software Foundation; either version 2 of the named License,
17  * * or any later version.
18  * *
19  * * This program is distributed in the hope that it will be useful,
20  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * * GNU General Public License for more details.
23  * *
24  * * You should have received a copy of the GNU General Public License
25  * * along with this program; if not, write to the Free Software
26  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
27  *
28  * Otherwise, the following license terms apply:
29  *
30  * * Redistribution and use in source and binary forms, with or without
31  * * modification, are permitted provided that the following conditions
32  * * are met:
33  * * 1) Redistributions of source code must retain the above copyright
34  * *    notice, this list of conditions and the following disclaimer.
35  * * 2) Redistributions in binary form must reproduce the above copyright
36  * *    notice, this list of conditions and the following disclaimer in the
37  * *    documentation and/or other materials provided with the distribution.
38  * * 3) The name of the author may not be used to endorse or promote products
39  * *    derived from this software without specific prior written permission.
40  * *
41  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
42  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  *
52  * Author:      Thomas Winischhofer <thomas@winischhofer.net>
53  *
54  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55  * Used by permission.
56  *
57  * TW says: This code looks awful, I know. But please don't do anything about
58  * this otherwise debugging will be hell.
59  * The code is extremely fragile as regards the different chipsets, different
60  * video bridges and combinations thereof. If anything is changed, extreme
61  * care has to be taken that that change doesn't break it for other chipsets,
62  * bridges or combinations thereof.
63  * All comments in this file are by me, regardless if marked TW or not.
64  *
65  */
66
67 #if 1
68 #define SET_EMI         /* 302LV/ELV: Set EMI values */
69 #endif
70
71 #define COMPAL_HACK     /* Needed for Compal 1400x1050 (EMI) */
72 #define COMPAQ_HACK     /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73 #define ASUS_HACK       /* Needed for Asus A2H 1024x768 (EMI) */
74
75 #include "init301.h"
76
77 #ifdef SIS300
78 #include "oem300.h"
79 #endif
80
81 #ifdef SIS315H
82 #include "oem310.h"
83 #endif
84
85 #define SiS_I2CDELAY      1000
86 #define SiS_I2CDELAYSHORT  150
87
88 static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
89
90 /*********************************************/
91 /*         HELPER: Lock/Unlock CRT2          */
92 /*********************************************/
93
94 void
95 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
96 {
97    if(HwInfo->jChipType >= SIS_315H)
98       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99    else
100       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101 }
102
103 void
104 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
105 {
106    if(HwInfo->jChipType >= SIS_315H)
107       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108    else
109       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
110 }
111
112 /*********************************************/
113 /*            HELPER: Write SR11             */
114 /*********************************************/
115
116 static void
117 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
118 {
119    if(HwInfo->jChipType >= SIS_661) {
120       DataAND &= 0x0f;
121       DataOR  &= 0x0f;
122    }
123    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
124 }
125
126 /*********************************************/
127 /*    HELPER: Get Pointer to LCD structure   */
128 /*********************************************/
129
130 #ifdef SIS315H
131 static UCHAR *
132 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
133 {
134    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
135    UCHAR  *myptr = NULL;
136    USHORT romindex = 0;
137
138    /* Use the BIOS tables only for LVDS panels; DVI is unreliable
139     * due to the variaty of panels the BIOS doesn't know about.
140     */
141
142    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
143       myptr = (UCHAR *)SiS_LCDStruct661;
144       romindex = SISGETROMW(0x100);
145       if(romindex) {
146          romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
147          myptr = &ROMAddr[romindex];
148       }
149    }
150    return myptr;
151 }
152
153 static USHORT
154 GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
155 {
156    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
157    USHORT romptr = 0;
158
159    /* Use the BIOS tables only for LVDS panels; DVI is unreliable
160     * due to the variaty of panels the BIOS doesn't know about.
161     */
162
163    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
164       romptr = SISGETROMW(0x102);
165       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
166    }
167
168    return(romptr);
169 }
170 #endif
171
172 /*********************************************/
173 /*           Adjust Rate for CRT2            */
174 /*********************************************/
175
176 static BOOLEAN
177 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
178                    USHORT RefreshRateTableIndex, USHORT *i,
179                    PSIS_HW_INFO HwInfo)
180 {
181   USHORT checkmask=0,modeid,infoflag;
182
183   modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
184
185   if(SiS_Pr->SiS_VBType & VB_SISVB) {
186
187      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
188
189         checkmask |= SupportRAMDAC2;
190         if(HwInfo->jChipType >= SIS_315H) {
191            checkmask |= SupportRAMDAC2_135;
192            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
193               checkmask |= SupportRAMDAC2_162;
194               if(SiS_Pr->SiS_VBType & VB_SIS301C) {
195                  checkmask |= SupportRAMDAC2_202;
196               }
197            }
198         }
199
200      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
201
202         checkmask |= SupportLCD;
203         if(HwInfo->jChipType >= SIS_315H) {
204            if(SiS_Pr->SiS_VBType & VB_SISVB) {
205               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
206                  if(modeid == 0x2e) checkmask |= Support64048060Hz;
207               }
208            }
209         }
210
211      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
212
213         checkmask |= SupportHiVision;
214
215      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
216
217         checkmask |= SupportTV;
218         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
219            checkmask |= SupportTV1024;
220            if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
221               if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
222                  checkmask |= SupportYPbPr750p;
223               }
224            }
225         }
226
227      }
228
229   } else {      /* LVDS */
230
231      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
232         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
233            checkmask |= SupportCHTV;
234         }
235      }
236
237      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
238         checkmask |= SupportLCD;
239      }
240
241   }
242
243   /* Look backwards in table for matching CRT2 mode */
244   for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
245      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
246      if(infoflag & checkmask) return TRUE;
247      if((*i) == 0) break;
248   }
249
250   /* Look through the whole mode-section of the table from the beginning
251    * for a matching CRT2 mode if no mode was found yet.
252    */
253   for((*i) = 0; ; (*i)++) {
254      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
255         return FALSE;
256      }
257      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
258      if(infoflag & checkmask) return TRUE;
259   }
260   return TRUE;
261 }
262
263 /*********************************************/
264 /*              Get rate index               */
265 /*********************************************/
266
267 USHORT
268 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
269                PSIS_HW_INFO HwInfo)
270 {
271   SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
272                                0x01, 0x01, 0x01, 0x01,
273                                0x01, 0x01, 0x01, 0x01,
274                                0x01, 0x01, 0x01, 0x01,
275                                0x00, 0x00, 0x00, 0x00 };
276   USHORT RefreshRateTableIndex,i,backup_i;
277   USHORT modeflag,index,temp,backupindex;
278
279   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
280   if(ModeNo == 0xfe) return 0;
281
282   if(ModeNo <= 0x13) {
283      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
284   } else {
285      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
286   }
287
288   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
289      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
290         if(modeflag & HalfDCLK) return 0;
291      }
292   }
293
294   if(ModeNo < 0x14) return 0xFFFF;
295
296   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
297   backupindex = index;
298
299   if(index > 0) index--;
300
301   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
302      if(SiS_Pr->SiS_VBType & VB_SISVB) {
303         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
304            if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
305            else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
306         }
307         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
308            if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
309               temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
310               if(index > temp) index = temp;
311            }
312         }
313      } else {
314         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
315         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
316            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
317         }
318      }
319   }
320
321   RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
322   ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
323
324   if(HwInfo->jChipType >= SIS_315H) {
325      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
326         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
327             (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
328            if(backupindex <= 1) RefreshRateTableIndex++;
329         }
330      }
331   }
332
333   i = 0;
334   do {
335      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
336      temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
337      temp &= ModeInfoFlag;
338      if(temp < SiS_Pr->SiS_ModeType) break;
339      i++;
340      index--;
341   } while(index != 0xFFFF);
342
343   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
344      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
345         temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
346         if(temp & InterlaceMode) i++;
347      }
348   }
349
350   i--;
351
352   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
353      backup_i = i;
354      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
355         i = backup_i;
356      }
357   }
358
359   return(RefreshRateTableIndex + i);
360 }
361
362 /*********************************************/
363 /*            STORE CRT2 INFO in CR34        */
364 /*********************************************/
365
366 static void
367 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
368 {
369   USHORT temp1,temp2;
370
371   /* Store CRT1 ModeNo in CR34 */
372   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
373   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
374   temp2 = ~(SetInSlaveMode >> 8);
375   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
376 }
377
378 /*********************************************/
379 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
380 /*********************************************/
381
382 #ifdef SIS300
383 static BOOLEAN
384 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
385 {
386   UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
387   USHORT temp,temp1;
388
389   if(SiS_Pr->SiS_UseROM) {
390      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
391         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
392         temp1 = SISGETROMW(0x23b);
393         if(temp1 & temp) return TRUE;
394      }
395   }
396   return FALSE;
397 }
398
399 static BOOLEAN
400 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
401 {
402   UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
403   USHORT temp,temp1;
404
405   if(SiS_Pr->SiS_UseROM) {
406      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
407         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
408         temp1 = SISGETROMW(0x23d);
409         if(temp1 & temp) return TRUE;
410      }
411   }
412   return FALSE;
413 }
414 #endif
415
416 /*********************************************/
417 /*          HELPER: DELAY FUNCTIONS          */
418 /*********************************************/
419
420 void
421 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
422 {
423   USHORT i, j;
424
425   for(i=0; i<delaytime; i++) {
426      j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
427   }
428 }
429
430 #if defined(SIS300) || defined(SIS315H)
431 static void
432 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
433 {
434   USHORT temp,flag;
435
436   flag = SiS_GetRegByte(0x61) & 0x10;
437
438   while(delay) {
439      temp = SiS_GetRegByte(0x61) & 0x10;
440      if(temp == flag) continue;
441      flag = temp;
442      delay--;
443   }
444 }
445 #endif
446
447 #ifdef SIS315H
448 static void
449 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
450 {
451   while(delay--) {
452      SiS_GenericDelay(SiS_Pr,0x19df);
453   }
454 }
455 #endif
456
457 #if defined(SIS300) || defined(SIS315H)
458 static void
459 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
460 {
461   while(delay--) {
462      SiS_GenericDelay(SiS_Pr,0x42);
463   }
464 }
465 #endif
466
467 static void
468 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
469 {
470 #if defined(SIS300) || defined(SIS315H)
471   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
472   USHORT PanelID, DelayIndex, Delay=0;
473 #endif
474
475   if(HwInfo->jChipType < SIS_315H) {
476
477 #ifdef SIS300
478
479       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
480       if(SiS_Pr->SiS_VBType & VB_SISVB) {
481          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
482       }
483       DelayIndex = PanelID >> 4;
484       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
485          Delay = 3;
486       } else {
487          if(DelayTime >= 2) DelayTime -= 2;
488          if(!(DelayTime & 0x01)) {
489             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
490          } else {
491             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
492          }
493          if(SiS_Pr->SiS_UseROM) {
494             if(ROMAddr[0x220] & 0x40) {
495                if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
496                else                    Delay = (USHORT)ROMAddr[0x226];
497             }
498          }
499       }
500       SiS_ShortDelay(SiS_Pr, Delay);
501
502 #endif  /* SIS300 */
503
504    } else {
505
506 #ifdef SIS315H
507
508       if((HwInfo->jChipType >= SIS_661)    ||
509          (HwInfo->jChipType <= SIS_315PRO) ||
510          (HwInfo->jChipType == SIS_330)) {
511
512          if(!(DelayTime & 0x01)) {
513             SiS_DDC2Delay(SiS_Pr, 0x1000);
514          } else {
515             SiS_DDC2Delay(SiS_Pr, 0x4000);
516          }
517
518       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
519          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
520          (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {                  /* 315 series, LVDS; Special */
521
522          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
523             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
524             if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
525                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
526             }
527             if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
528                DelayIndex = PanelID & 0x0f;
529             } else {
530                DelayIndex = PanelID >> 4;
531             }
532             if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
533                Delay = 3;
534             } else {
535                if(DelayTime >= 2) DelayTime -= 2;
536                if(!(DelayTime & 0x01)) {
537                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
538                } else {
539                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
540                }
541                if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
542                   if(ROMAddr[0x13c] & 0x40) {
543                      if(!(DelayTime & 0x01)) {
544                         Delay = (USHORT)ROMAddr[0x17e];
545                      } else {
546                         Delay = (USHORT)ROMAddr[0x17f];
547                      }
548                   }
549                }
550             }
551             SiS_ShortDelay(SiS_Pr, Delay);
552          }
553
554       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                        /* 315 series, all bridges */
555
556          DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
557          if(!(DelayTime & 0x01)) {
558             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
559          } else {
560             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
561          }
562          Delay <<= 8;
563          SiS_DDC2Delay(SiS_Pr, Delay);
564
565       }
566
567 #endif /* SIS315H */
568
569    }
570 }
571
572 #ifdef SIS315H
573 static void
574 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
575                       USHORT DelayTime, USHORT DelayLoop)
576 {
577    int i;
578    for(i=0; i<DelayLoop; i++) {
579       SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
580    }
581 }
582 #endif
583
584 /*********************************************/
585 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
586 /*********************************************/
587
588 void
589 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
590 {
591   USHORT watchdog;
592
593   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
594   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
595
596   watchdog = 65535;
597   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
598   watchdog = 65535;
599   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
600 }
601
602 #if defined(SIS300) || defined(SIS315H)
603 static void
604 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
605 {
606   USHORT watchdog;
607
608   watchdog = 65535;
609   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
610   watchdog = 65535;
611   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
612 }
613 #endif
614
615 static void
616 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
617 {
618   if(HwInfo->jChipType < SIS_315H) {
619 #ifdef SIS300
620      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
621         if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
622      }
623      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
624         SiS_WaitRetrace1(SiS_Pr);
625      } else {
626         SiS_WaitRetrace2(SiS_Pr, 0x25);
627      }
628 #endif
629   } else {
630 #ifdef SIS315H
631      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
632         SiS_WaitRetrace1(SiS_Pr);
633      } else {
634         SiS_WaitRetrace2(SiS_Pr, 0x30);
635      }
636 #endif
637   }
638 }
639
640 static void
641 SiS_VBWait(SiS_Private *SiS_Pr)
642 {
643   USHORT tempal,temp,i,j;
644
645   temp = 0;
646   for(i=0; i<3; i++) {
647     for(j=0; j<100; j++) {
648        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
649        if(temp & 0x01) {
650           if((tempal & 0x08))  continue;
651           else break;
652        } else {
653           if(!(tempal & 0x08)) continue;
654           else break;
655        }
656     }
657     temp ^= 0x01;
658   }
659 }
660
661 static void
662 SiS_VBLongWait(SiS_Private *SiS_Pr)
663 {
664   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
665      SiS_VBWait(SiS_Pr);
666   } else {
667      SiS_WaitRetrace1(SiS_Pr);
668   }
669 }
670
671 /*********************************************/
672 /*               HELPER: MISC                */
673 /*********************************************/
674
675 #ifdef SIS300
676 static BOOLEAN
677 SiS_Is301B(SiS_Private *SiS_Pr)
678 {
679   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
680   return FALSE;
681 }
682 #endif
683
684 static BOOLEAN
685 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
686 {
687   USHORT flag;
688
689   if(HwInfo->jChipType == SIS_730) {
690      flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
691      if(flag & 0x20) return TRUE;
692   }
693   flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
694   if(flag & 0x20) return TRUE;
695   return FALSE;
696 }
697
698 BOOLEAN
699 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
700 {
701 #ifdef SIS315H
702   USHORT flag;
703
704   if(HwInfo->jChipType >= SIS_315H) {
705      if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
706         flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
707         if(flag & EnableDualEdge) return TRUE;
708      }
709   }
710 #endif
711   return FALSE;
712 }
713
714 BOOLEAN
715 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
716 {
717 #ifdef SIS315H
718   USHORT flag;
719
720   if(HwInfo->jChipType >= SIS_315H) {
721      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
722      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
723   }
724 #endif
725   return FALSE;
726 }
727
728 #ifdef SIS315H
729 static BOOLEAN
730 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
731 {
732   if(SiS_IsVAMode(SiS_Pr,HwInfo))   return TRUE;
733   if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
734   return FALSE;
735 }
736 #endif
737
738 static BOOLEAN
739 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
740 {
741 #ifdef SIS315H
742   if(HwInfo->jChipType >= SIS_315H) {
743      if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
744         (SiS_IsVAMode(SiS_Pr, HwInfo))) {
745         if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
746      }
747   }
748 #endif
749   return FALSE;
750 }
751
752 #ifdef SIS315H
753 static BOOLEAN
754 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
755 {
756   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
757   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
758      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
759   }
760   return FALSE;
761 }
762 #endif
763
764 #ifdef SIS315H
765 static BOOLEAN
766 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
767 {
768   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
769   return FALSE;
770 }
771 #endif
772
773 #ifdef SIS315H
774 static BOOLEAN
775 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
776 {
777   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
778      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
779   }
780   return FALSE;
781 }
782 #endif
783
784 #ifdef SIS315H
785 static BOOLEAN
786 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
787 {
788   USHORT flag;
789
790   if(HwInfo->jChipType == SIS_650) {
791      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
792      flag &= 0xF0;
793      /* Check for revision != A0 only */
794      if((flag == 0xe0) || (flag == 0xc0) ||
795         (flag == 0xb0) || (flag == 0x90)) return FALSE;
796   } else if(HwInfo->jChipType >= SIS_661) return FALSE;
797   return TRUE;
798 }
799 #endif
800
801 #ifdef SIS315H
802 static BOOLEAN
803 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
804 {
805   USHORT flag;
806
807   if(HwInfo->jChipType >= SIS_315H) {
808      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
809      if(flag & EnableCHYPbPr) return TRUE;  /* = YPrPb = 0x08 */
810   }
811   return FALSE;
812 }
813 #endif
814
815 #ifdef SIS315H
816 static BOOLEAN
817 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
818 {
819   USHORT flag;
820
821   if(HwInfo->jChipType >= SIS_315H) {
822      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
823      if(flag & EnableCHScart) return TRUE;  /* = Scart = 0x04 */
824   }
825   return FALSE;
826 }
827 #endif
828
829 #ifdef SIS315H
830 static BOOLEAN
831 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
832 {
833   USHORT flag;
834
835   if(HwInfo->jChipType >= SIS_315H) {
836      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
837      if(flag & SetCRT2ToTV)        return TRUE;
838      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
839      if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
840      if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
841   } else {
842      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
843      if(flag & SetCRT2ToTV)        return TRUE;
844   }
845   return FALSE;
846 }
847 #endif
848
849 #ifdef SIS315H
850 static BOOLEAN
851 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
852 {
853   USHORT flag;
854
855   if(HwInfo->jChipType >= SIS_315H) {
856      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
857      if(flag & SetCRT2ToLCD) return TRUE;
858      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
859      if(flag & SetToLCDA)    return TRUE;
860   } else {
861      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
862      if(flag & SetCRT2ToLCD) return TRUE;
863   }
864   return FALSE;
865 }
866 #endif
867
868 static BOOLEAN
869 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
870 {
871   USHORT flag;
872
873   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
874      return TRUE;
875   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
876      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
877      if((flag == 1) || (flag == 2)) return TRUE;
878   }
879   return FALSE;
880 }
881
882 static BOOLEAN
883 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
884 {
885   USHORT flag;
886
887   if(SiS_BridgeIsOn(SiS_Pr)) {
888      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
889      if(HwInfo->jChipType < SIS_315H) {
890        flag &= 0xa0;
891        if((flag == 0x80) || (flag == 0x20)) return TRUE;
892      } else {
893        flag &= 0x50;
894        if((flag == 0x40) || (flag == 0x10)) return TRUE;
895      }
896   }
897   return FALSE;
898 }
899
900 static BOOLEAN
901 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
902 {
903   USHORT flag1;
904
905   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
906   if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
907   return FALSE;
908 }
909
910 /*********************************************/
911 /*       GET VIDEO BRIDGE CONFIG INFO        */
912 /*********************************************/
913
914 /* Setup general purpose IO for Chrontel communication */
915 void
916 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
917 {
918    unsigned long  acpibase;
919    unsigned short temp;
920
921    if(!(SiS_Pr->SiS_ChSW)) return;
922
923 #ifndef LINUX_XF86
924    SiS_SetRegLong(0xcf8,0x80000874);                   /* get ACPI base */
925    acpibase = SiS_GetRegLong(0xcfc);
926 #else
927    acpibase = pciReadLong(0x00000800, 0x74);
928 #endif
929    acpibase &= 0xFFFF;
930    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
931    temp &= 0xFEFF;
932    SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
933    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
934    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
935    temp &= 0xFEFF;
936    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
937    SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
938    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
939 }
940
941 void
942 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
943               PSIS_HW_INFO HwInfo, int checkcrt2mode)
944 {
945   USHORT tempax,tempbx,temp;
946   USHORT modeflag, resinfo=0;
947
948   if(ModeNo <= 0x13) {
949      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
950   } else if(SiS_Pr->UseCustomMode) {
951      modeflag = SiS_Pr->CModeFlag;
952   } else {
953      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
954      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
955   }
956
957   SiS_Pr->SiS_SetFlag = 0;
958
959   SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
960
961   tempbx = 0;
962   if(SiS_BridgeIsOn(SiS_Pr)) {
963         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
964 #if 0
965         if(HwInfo->jChipType < SIS_661) {
966            /* NO - YPbPr not set yet ! */
967            if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
968               temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
969               temp |= SetCRT2ToHiVision;                                        /* 0x80 */
970            }
971            if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
972               temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
973               temp |= SetCRT2ToSVIDEO;                                          /* 0x08 */
974            }
975         }
976 #endif
977         tempbx |= temp;
978         tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
979         tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
980         tempbx |= tempax;
981
982 #ifdef SIS315H
983         if(HwInfo->jChipType >= SIS_315H) {
984            if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
985               if(ModeNo == 0x03) {
986                  /* Mode 0x03 is never in driver mode */
987                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
988               }
989               if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
990                  /* Reset LCDA setting if not driver mode */
991                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
992               }
993               if(IS_SIS650) {
994                  if(SiS_Pr->SiS_UseLCDA) {
995                     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
996                        if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
997                           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
998                        }
999                     }
1000                  }
1001               }
1002               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1003               if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1004                  tempbx |= SetCRT2ToLCDA;
1005               }
1006            }
1007
1008            if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1009               tempbx &= ~(SetCRT2ToRAMDAC);
1010            }
1011
1012            if(HwInfo->jChipType >= SIS_661) {
1013               tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1014               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1015               if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1016                  if(temp & 0x04) {
1017                     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1018                     if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1019                     else             tempbx |= SetCRT2ToYPbPr525750;
1020                  }
1021               } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
1022                  if(temp & 0x04) {
1023                     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1024                     if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1025                  }
1026               }
1027            }
1028
1029            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1030               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1031               if(temp & SetToLCDA) {
1032                  tempbx |= SetCRT2ToLCDA;
1033               }
1034               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1035                  if(temp & EnableCHYPbPr) {
1036                     tempbx |= SetCRT2ToCHYPbPr;
1037                  }
1038               }
1039            }
1040         }
1041
1042 #endif  /* SIS315H */
1043
1044         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1045            temp = SetCRT2ToSVIDEO   |
1046                   SetCRT2ToAVIDEO   |
1047                   SetCRT2ToSCART    |
1048                   SetCRT2ToLCDA     |
1049                   SetCRT2ToLCD      |
1050                   SetCRT2ToRAMDAC   |
1051                   SetCRT2ToHiVision |
1052                   SetCRT2ToYPbPr525750;
1053         } else {
1054            if(HwInfo->jChipType >= SIS_315H) {
1055               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1056                  temp = SetCRT2ToAVIDEO |
1057                         SetCRT2ToSVIDEO |
1058                         SetCRT2ToSCART  |
1059                         SetCRT2ToLCDA   |
1060                         SetCRT2ToLCD    |
1061                         SetCRT2ToCHYPbPr;
1062               } else {
1063                  temp = SetCRT2ToLCDA   |
1064                         SetCRT2ToLCD;
1065               }
1066            } else {
1067               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1068                  temp = SetCRT2ToTV | SetCRT2ToLCD;
1069               } else {
1070                  temp = SetCRT2ToLCD;
1071               }
1072            }
1073         }
1074
1075         if(!(tempbx & temp)) {
1076            tempax = DisableCRT2Display;
1077            tempbx = 0;
1078         }
1079
1080         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1081            USHORT clearmask = ( DriverMode         |
1082                                 DisableCRT2Display |
1083                                 LoadDACFlag        |
1084                                 SetNotSimuMode     |
1085                                 SetInSlaveMode     |
1086                                 SetPALTV           |
1087                                 SwitchCRT2         |
1088                                 SetSimuScanMode );
1089            if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1090            if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1091            if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1092            if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1093            if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1094            if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1095         } else {
1096            if(HwInfo->jChipType >= SIS_315H) {
1097               if(tempbx & SetCRT2ToLCDA) {
1098                  tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1099               }
1100            }
1101            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1102               if(tempbx & SetCRT2ToTV) {
1103                  tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1104               }
1105            }
1106            if(tempbx & SetCRT2ToLCD) {
1107               tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1108            }
1109            if(HwInfo->jChipType >= SIS_315H) {
1110               if(tempbx & SetCRT2ToLCDA) {
1111                  tempbx |= SetCRT2ToLCD;
1112               }
1113            }
1114         }
1115
1116         if(tempax & DisableCRT2Display) {
1117            if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1118               tempbx = SetSimuScanMode | DisableCRT2Display;
1119            }
1120         }
1121
1122         if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1123
1124         /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1125         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1126            if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1127                ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1128                modeflag &= (~CRT2Mode);
1129            }
1130         }
1131
1132         if(!(tempbx & SetSimuScanMode)) {
1133            if(tempbx & SwitchCRT2) {
1134               if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1135                  if( (HwInfo->jChipType >= SIS_315H) &&
1136                      (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1137                     if(resinfo != SIS_RI_1600x1200) {
1138                        tempbx |= SetSimuScanMode;
1139                     }
1140                  } else {
1141                     tempbx |= SetSimuScanMode;
1142                  }
1143               }
1144            } else {
1145               if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1146                  if(!(tempbx & DriverMode)) {
1147                     if(SiS_BridgeInSlavemode(SiS_Pr)) {
1148                        tempbx |= SetSimuScanMode;
1149                     }
1150                  }
1151               }
1152            }
1153         }
1154
1155         if(!(tempbx & DisableCRT2Display)) {
1156            if(tempbx & DriverMode) {
1157               if(tempbx & SetSimuScanMode) {
1158                  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1159                     if( (HwInfo->jChipType >= SIS_315H) &&
1160                         (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1161                        if(resinfo != SIS_RI_1600x1200) {
1162                           tempbx |= SetInSlaveMode;
1163                        }
1164                     } else {
1165                        tempbx |= SetInSlaveMode;
1166                     }
1167                  }
1168               }
1169            } else {
1170               tempbx |= SetInSlaveMode;
1171            }
1172         }
1173
1174   }
1175
1176   SiS_Pr->SiS_VBInfo = tempbx;
1177
1178   if(HwInfo->jChipType == SIS_630) {
1179      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1180   }
1181
1182 #ifdef TWDEBUG
1183 #ifdef LINUX_KERNEL
1184   printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1185       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1186 #endif
1187 #ifdef LINUX_XF86
1188   xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1189       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1190 #endif
1191 #endif
1192 }
1193
1194 /*********************************************/
1195 /*           DETERMINE YPbPr MODE            */
1196 /*********************************************/
1197
1198 void
1199 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1200 {
1201
1202   UCHAR temp;
1203
1204   /* Note: This variable is only used on 30xLV systems.
1205    * CR38 has a different meaning on LVDS/CH7019 systems.
1206    * On 661 and later, these bits moved to CR35.
1207    *
1208    * On 301, 301B, only HiVision 1080i is supported.
1209    * On 30xLV, 301C, only YPbPr 1080i is supported.
1210    */
1211
1212   SiS_Pr->SiS_YPbPr = 0;
1213   if(HwInfo->jChipType >= SIS_661) return;
1214
1215   if(SiS_Pr->SiS_VBType) {
1216      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1217         SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1218      }
1219   }
1220
1221   if(HwInfo->jChipType >= SIS_315H) {
1222      if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1223         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1224         if(temp & 0x08) {
1225            switch((temp >> 4)) {
1226            case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1227            case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1228            case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1229            case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1230            }
1231         }
1232      }
1233   }
1234
1235 }
1236
1237 /*********************************************/
1238 /*           DETERMINE TVMode flag           */
1239 /*********************************************/
1240
1241 void
1242 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1243 {
1244   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1245   USHORT temp, temp1, resinfo = 0, romindex = 0;
1246   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1247
1248   SiS_Pr->SiS_TVMode = 0;
1249
1250   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1251   if(SiS_Pr->UseCustomMode) return;
1252
1253   if(ModeNo > 0x13) {
1254      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1255   }
1256
1257   if(HwInfo->jChipType < SIS_661) {
1258
1259      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1260
1261      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1262         temp = 0;
1263         if((HwInfo->jChipType == SIS_630) ||
1264            (HwInfo->jChipType == SIS_730)) {
1265            temp = 0x35;
1266            romindex = 0xfe;
1267         } else if(HwInfo->jChipType >= SIS_315H) {
1268            temp = 0x38;
1269            romindex = 0xf3;
1270            if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1271         }
1272         if(temp) {
1273            if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1274               OutputSelect = ROMAddr[romindex];
1275               if(!(OutputSelect & EnablePALMN)) {
1276                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1277               }
1278            }
1279            temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1280            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1281               if(temp1 & EnablePALM) {          /* 0x40 */
1282                  SiS_Pr->SiS_TVMode |= TVSetPALM;
1283                  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1284               } else if(temp1 & EnablePALN) {   /* 0x80 */
1285                  SiS_Pr->SiS_TVMode |= TVSetPALN;
1286               }
1287            } else {
1288               if(temp1 & EnableNTSCJ) {         /* 0x40 */
1289                  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1290               }
1291            }
1292         }
1293         /* Translate HiVision/YPbPr to our new flags */
1294         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1295            if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1296            else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1297            else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1298            else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1299            if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1300               SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1301               SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1302            } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1303               SiS_Pr->SiS_TVMode |= TVSetPAL;
1304            }
1305         }
1306      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1307         if(SiS_Pr->SiS_CHOverScan) {
1308            if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1309               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1310               if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1311                  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1312               }
1313            } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1314               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1315               if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1316                  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1317               }
1318            }
1319            if(SiS_Pr->SiS_CHSOverScan) {
1320               SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1321            }
1322         }
1323         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1324            temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1325            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1326               if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1327               else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1328            } else {
1329               if(temp & EnableNTSCJ) {
1330                  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1331               }
1332            }
1333         }
1334      }
1335
1336   } else {  /* 661 and later */
1337
1338      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1339      if(temp1 & 0x01) {
1340         SiS_Pr->SiS_TVMode |= TVSetPAL;
1341         if(temp1 & 0x08) {
1342            SiS_Pr->SiS_TVMode |= TVSetPALN;
1343         } else if(temp1 & 0x04) {
1344            if(SiS_Pr->SiS_VBType & VB_SISVB) {
1345               SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1346            }
1347            SiS_Pr->SiS_TVMode |= TVSetPALM;
1348         }
1349      } else {
1350         if(temp1 & 0x02) {
1351            SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1352         }
1353      }
1354      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1355         if(SiS_Pr->SiS_CHOverScan) {
1356            if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1357               SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1358            }
1359         }
1360      }
1361      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1362         if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1363            temp1 &= 0xe0;
1364            if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1365            else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1366            else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1367         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1368            SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1369         }
1370         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1371            if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1372               SiS_Pr->SiS_TVMode |= TVAspect169;
1373            } else {
1374               temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1375               if(temp1 & 0x02) {
1376                  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1377                     SiS_Pr->SiS_TVMode |= TVAspect169;
1378                  } else {
1379                     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1380                  }
1381               } else {
1382                  SiS_Pr->SiS_TVMode |= TVAspect43;
1383               }
1384            }
1385         }
1386      }
1387   }
1388
1389   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1390
1391   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1392
1393      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1394         SiS_Pr->SiS_TVMode |= TVSetPAL;
1395         SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1396      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1397         if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1398            SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1399         }
1400      }
1401
1402      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1403         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1404            SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1405         }
1406      }
1407
1408      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1409         /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1410         if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1411            if(resinfo == SIS_RI_1024x768) {
1412               SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1413            }
1414         }
1415      }
1416
1417      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1418      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1419         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1420         SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1421      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1422         SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1423      } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1424         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1425            SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1426         }
1427      }
1428
1429   }
1430
1431   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1432
1433 #ifdef TWDEBUG
1434   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1435 #endif
1436 }
1437
1438 /*********************************************/
1439 /*               GET LCD INFO                */
1440 /*********************************************/
1441
1442 static USHORT
1443 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1444 {
1445    USHORT temp = SiS_Pr->SiS_LCDResInfo;
1446    /* Translate my LCDResInfo to BIOS value */
1447    if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
1448    if(temp == Panel_1280x768_3)  temp = Panel_1280x768;
1449    return temp;
1450 }
1451
1452 static void
1453 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1454 {
1455 #ifdef SIS315H
1456    UCHAR  *ROMAddr;
1457    USHORT temp;
1458
1459 #ifdef TWDEBUG
1460    xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1461         SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1462         SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1463         SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1464         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1465         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1466         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1467 #endif
1468
1469    if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1470       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1471          SiS_Pr->SiS_NeedRomModeData = TRUE;
1472          SiS_Pr->PanelHT  = temp;
1473       }
1474       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1475          SiS_Pr->SiS_NeedRomModeData = TRUE;
1476          SiS_Pr->PanelVT  = temp;
1477       }
1478       SiS_Pr->PanelHRS = SISGETROMW(10);
1479       SiS_Pr->PanelHRE = SISGETROMW(12);
1480       SiS_Pr->PanelVRS = SISGETROMW(14);
1481       SiS_Pr->PanelVRE = SISGETROMW(16);
1482       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1483       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1484          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1485       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1486          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1487       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1488          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1489
1490 #ifdef TWDEBUG
1491       xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1492         SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1493         SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1494         SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1495         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1496         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1497         SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1498 #endif
1499
1500    }
1501 #endif
1502 }
1503
1504 void
1505 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1506                   PSIS_HW_INFO HwInfo)
1507 {
1508 #ifdef SIS300
1509   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1510 #endif
1511 #ifdef SIS315H
1512   UCHAR  *myptr = NULL;
1513 #endif
1514   USHORT temp,modeflag,resinfo=0;
1515   const unsigned char SiS300SeriesLCDRes[] =
1516          { 0,  1,  2,  3,  7,  4,  5,  8,
1517            0,  0, 10,  0,  0,  0,  0, 15 };
1518
1519   SiS_Pr->SiS_LCDResInfo  = 0;
1520   SiS_Pr->SiS_LCDTypeInfo = 0;
1521   SiS_Pr->SiS_LCDInfo     = 0;
1522   SiS_Pr->PanelHRS        = 999; /* HSync start */
1523   SiS_Pr->PanelHRE        = 999; /* HSync end */
1524   SiS_Pr->PanelVRS        = 999; /* VSync start */
1525   SiS_Pr->PanelVRE        = 999; /* VSync end */
1526   SiS_Pr->SiS_NeedRomModeData = FALSE;
1527
1528   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1529
1530   if(ModeNo <= 0x13) {
1531      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1532   } else if(SiS_Pr->UseCustomMode) {
1533      modeflag = SiS_Pr->CModeFlag;
1534   } else {
1535      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1536      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1537   }
1538
1539   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1540   if(!temp) return;
1541
1542   if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1543      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1544   } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1545      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1546   } else {
1547      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1548   }
1549   temp &= 0x0f;
1550   if(HwInfo->jChipType < SIS_315H) {
1551      /* Translate 300 series LCDRes to 315 series for unified usage */
1552      temp = SiS300SeriesLCDRes[temp];
1553   }
1554
1555   if(HwInfo->jChipType == SIS_550) {
1556      if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1557      if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1558   }
1559
1560   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* SiS LVDS */
1561      if(temp == Panel310_1280x768) {
1562         temp = Panel_1280x768_2;
1563 #ifdef SIS315H
1564         if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1565            if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
1566         }
1567 #endif
1568      }
1569   }
1570
1571   SiS_Pr->SiS_LCDResInfo = temp;
1572
1573   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1574      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1575         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1576      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1577         SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1578      }
1579   }
1580
1581   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1582      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1583         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1584   } else {
1585      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1586         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1587   }
1588
1589   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1590   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1591
1592   switch(SiS_Pr->SiS_LCDResInfo) {
1593      case Panel_320x480:    SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480;
1594                             SiS_Pr->PanelHT   =  400; SiS_Pr->PanelVT   =  525;
1595                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1596                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1597                             break;
1598      case Panel_640x480_2:
1599      case Panel_640x480_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1600                             SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1601                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1602                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1603                             break;
1604      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1605                                                       SiS_Pr->PanelVRE  =    3;
1606                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1607                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1608                             break;
1609      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1610                             SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1611                             SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1612                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1613                             SiS_Pr->PanelVCLKIdx300 = VCLK40;
1614                             SiS_Pr->PanelVCLKIdx315 = VCLK40;
1615                             break;
1616      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1617                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1618                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1619                             SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1620                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1621                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1622                             break;
1623      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1624                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1625                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1626                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1627                             if(HwInfo->jChipType < SIS_315H) {
1628                                SiS_Pr->PanelHRS = 23;
1629                                                       SiS_Pr->PanelVRE  =    5;
1630                             }
1631                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1632                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1633                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1634                             break;
1635      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
1636                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1637                             SiS_Pr->PanelHRS  =   24;
1638                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1639                             if(HwInfo->jChipType < SIS_315H) {
1640                                SiS_Pr->PanelHRS = 23;
1641                                                       SiS_Pr->PanelVRE  =    5;
1642                             }
1643                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1644                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1645                             break;
1646      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
1647                             break;
1648      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
1649                             SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
1650                             SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
1651                             SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
1652                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1653                             /* Data above for TMDS (projector); get from BIOS for LVDS */
1654                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1655                             break;
1656      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1657                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
1658                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
1659                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1660                             SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1661                             SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1662                             break;
1663      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1664                             SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
1665                             SiS_Pr->PanelHRS  =   16; SiS_Pr->PanelHRE  =   64;
1666                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1667                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1668                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1669                             break;
1670      case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1671                             SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  798;
1672                             SiS_Pr->PanelHRS   =  64; SiS_Pr->PanelHRE  =  128;
1673                             SiS_Pr->PanelVRS   =   3; SiS_Pr->PanelVRE  =    7;
1674                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
1675                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1676                             break;
1677      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1678                             SiS_Pr->PanelHT   = 1656; SiS_Pr->PanelVT   =  841;  /* 1408, 816 */
1679                             SiS_Pr->PanelHRS   =  32; SiS_Pr->PanelHRE  =  312;  /*   16,  64 */
1680                             SiS_Pr->PanelVRS   =  16; SiS_Pr->PanelVRE  =    8;  /*    4,   3 */
1681                             SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
1682                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1683                             break;
1684      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
1685                             SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
1686                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1687                             SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1688                             if(resinfo == SIS_RI_1280x1024) {
1689                                SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1690                                SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1691                             }
1692                             break;
1693      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1694                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1695                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1696                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1697                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1698                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1699                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1700                             break;
1701      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1702                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1703                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112; /* HRE OK for LVDS, not for LCDA */
1704                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1705                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1706                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1707                             break;
1708      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1709                             SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
1710                             SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
1711                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1712                             SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1713                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1714                             break;
1715      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1716                             SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
1717                             SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
1718                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1719                             SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1720                             SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1721                             break;
1722      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1723                             SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1724                             SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
1725                             SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
1726                             if(SiS_Pr->CP_PreferredIndex != -1) {
1727                                SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1728                                SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1729                                SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1730                                SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1731                                SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1732                                SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1733                                SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1734                                SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1735                                SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1736                                SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1737                                SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1738                                SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1739                             }
1740                             break;
1741      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1742                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1743                             break;
1744      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
1745                             SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1746                             break;
1747      default:               SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1748                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1749                             break;
1750   }
1751
1752   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1753   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1754
1755   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1756   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1757
1758 #ifdef SIS315H
1759   if(HwInfo->jChipType >= SIS_661) {
1760      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1761         if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1762      }
1763      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1764         if(SiS_Pr->SiS_ROMNew) {
1765            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1766         } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1767            if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1768         }
1769      }
1770   } else if(HwInfo->jChipType >= SIS_315H) {
1771      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1772         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1773      }
1774      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1775         SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1776         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1777         if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1778         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1779            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1780         }
1781      }
1782   }
1783 #endif
1784
1785   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1786      /* Always center screen on LVDS (if scaling is disabled) */
1787      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1788   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1789      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1790         /* Always center screen on SiS LVDS (if scaling is disabled) */
1791         SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1792      } else {
1793         /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
1794         SiS_Pr->SiS_LCDInfo |= LCDPass11;
1795         if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1796      }
1797   }
1798
1799   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1800      if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1801         SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
1802      }
1803   }
1804
1805   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1806      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
1807         if(modeflag & NoSupportLCDScale) {
1808            /* No scaling for this mode on any panel */
1809            SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1810         }
1811         switch(SiS_Pr->SiS_LCDResInfo) {
1812         case Panel_Custom:
1813                 /* For non-standard LCD resolution, we let the panel scale */
1814                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1815                 break;
1816         case Panel_1280x720:
1817                 if(SiS_Pr->PanelHT == 1650) {
1818                    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1819                 }
1820         case Panel_1280x768:    /* TMDS only */
1821                 /* No idea about the timing and zoom factors */
1822                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1823                 break;
1824         case Panel_1280x960:
1825                 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1826                 break;
1827         case Panel_1280x1024:
1828                 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1829                    if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1830                       ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1831                       ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
1832                       /* We do not scale to 1280x720/800/960 (B/C bridges only) */
1833                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1834                    }
1835                    if(((HwInfo->jChipType >= SIS_315H) &&
1836                        (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
1837                       ((HwInfo->jChipType < SIS_315H)  &&
1838                        (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
1839                       /* We do not scale to 1280x768 (B/C bridges only) */
1840                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1841                    }
1842                 }
1843                 break;
1844         case Panel_1400x1050:
1845                 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1846                    if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1847                       ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1848                       ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
1849                       ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
1850                       /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
1851                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1852                    }
1853                 }
1854                 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1855                    if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
1856                       if(SiS_Pr->UsePanelScaler == -1) {
1857                          /* Do not scale to 1280x720 by default (LVDS bridges) */
1858                          SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1859                       }
1860                    }
1861                 }
1862                 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
1863                    /* Do not scale to 1280x1024 (all bridges) */
1864                    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1865                 }
1866                 break;
1867         case Panel_1600x1200:
1868                 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1869                    /* No idea about the timing and zoom factors (C bridge only) */
1870                    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1871                 }
1872                 break;
1873         }
1874      }
1875   }
1876
1877 #ifdef SIS300
1878   if(HwInfo->jChipType < SIS_315H) {
1879      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1880         if(SiS_Pr->SiS_UseROM) {
1881            if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
1882               if(!(ROMAddr[0x235] & 0x02)) {
1883                  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1884               }
1885            }
1886         }
1887      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1888         if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
1889            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1890         }
1891      }
1892   }
1893 #endif
1894
1895   /* Special cases */
1896   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
1897      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1898   }
1899
1900   if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1901      SiS_Pr->SiS_LCDInfo |= LCDPass11;
1902   }
1903
1904   if(SiS_Pr->UseCustomMode) {
1905      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1906   }
1907
1908   /* (In)validate LCDPass11 flag */
1909   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1910      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1911   }
1912
1913   /* Special cases */
1914   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
1915       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
1916       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1917       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1918       (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1919      SiS_Pr->PanelHRS = 999;
1920      SiS_Pr->PanelHRE = 999;
1921   }
1922
1923   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1924       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1925       (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1926      SiS_Pr->PanelVRS = 999;
1927      SiS_Pr->PanelVRE = 999;
1928   }
1929
1930 #ifdef SIS315H
1931   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
1932      if(!(SiS_Pr->SiS_ROMNew)) {
1933         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1934            /* Enable 302LV/302ELV dual link mode.
1935             * For 661, this is done above.
1936             */
1937            if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1938               (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1939               /* (Sets this in SenseLCD; new paneltypes) */
1940               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1941            }
1942            if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1943               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1944               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1945               (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1946               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1947            }
1948         }
1949      }
1950   }
1951 #endif
1952
1953   if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
1954
1955      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1956         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
1957            if(ModeNo == 0x12) {
1958               if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
1959                  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1960               }
1961            } else if(ModeNo > 0x13) {
1962               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
1963                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1964                     if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
1965                        SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1966                     }
1967                  }
1968               }
1969            }
1970         }
1971      }
1972
1973      if(modeflag & HalfDCLK) {
1974         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
1975            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1976         } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1977            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1978         } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1979            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1980         } else if(ModeNo > 0x13) {
1981            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
1982               if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1983            } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
1984               if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1985            }
1986         }
1987      }
1988
1989   }
1990
1991   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1992      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
1993         SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1994      }
1995   } else {
1996      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1997   }
1998
1999 #ifdef LINUX_KERNEL
2000 #ifdef TWDEBUG
2001   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2002         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2003 #endif
2004 #endif
2005 #ifdef LINUX_XF86
2006   xf86DrvMsgVerb(0, X_PROBED, 4,
2007         "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2008         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2009 #endif
2010 }
2011
2012 /*********************************************/
2013 /*                 GET VCLK                  */
2014 /*********************************************/
2015
2016 USHORT
2017 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2018                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2019 {
2020   USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2021   USHORT modeflag,resinfo,tempbx;
2022   const UCHAR *CHTVVCLKPtr = NULL;
2023
2024   if(ModeNo <= 0x13) {
2025      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2026      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2027      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2028      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2029   } else {
2030      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2031      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2032      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2033      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2034      if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2035   }
2036
2037   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2038
2039      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2040
2041         CRT2Index >>= 6;
2042         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {       /*  LCD */
2043
2044            if(HwInfo->jChipType < SIS_315H) {
2045               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2046            } else {
2047               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2048               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2049                  VCLKIndex = VCLKIndexGEN;
2050                  switch(resinfo) {
2051                  /* Only those whose IndexGEN doesn't match VBVCLK array: */
2052                  case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
2053                                        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
2054                                           if(SiS_Pr->PanelHT == 1344) {
2055                                              VCLKIndex = VCLK_1280x720_2;
2056                                           }
2057                                        }
2058                                        break;
2059                  case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2060                  case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2061                  case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2062                  case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2063                  case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2064                  case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2065                  case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2066                  case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2067                  case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2068                  }
2069
2070                  if(ModeNo <= 0x13) {
2071                     if(HwInfo->jChipType <= SIS_315PRO) {
2072                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2073                     } else {
2074                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2075                     }
2076                  }
2077                  if(HwInfo->jChipType <= SIS_315PRO) {
2078                     if(VCLKIndex == 0) VCLKIndex = 0x41;
2079                     if(VCLKIndex == 1) VCLKIndex = 0x43;
2080                     if(VCLKIndex == 4) VCLKIndex = 0x44;
2081                  }
2082               }
2083            }
2084
2085         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                   /*  TV */
2086
2087            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2088               if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)             VCLKIndex = HiTVVCLKDIV2;
2089               else                                              VCLKIndex = HiTVVCLK;
2090               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2091                  if(modeflag & Charx8Dot)                       VCLKIndex = HiTVSimuVCLK;
2092                  else                                           VCLKIndex = HiTVTextVCLK;
2093               }
2094            } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)       VCLKIndex = YPbPr750pVCLK;
2095            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)         VCLKIndex = TVVCLKDIV2;
2096            else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)           VCLKIndex = TVVCLKDIV2;
2097            else                                                 VCLKIndex = TVVCLK;
2098
2099            if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2100            else                             VCLKIndex += TVCLKBASE_315;
2101
2102         } else {                                                        /* VGA2 */
2103
2104            VCLKIndex = VCLKIndexGEN;
2105            if(HwInfo->jChipType < SIS_315H) {
2106               if(ModeNo > 0x13) {
2107                  if( (HwInfo->jChipType == SIS_630) &&
2108                      (HwInfo->jChipRevision >= 0x30)) {
2109                     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2110                  }
2111                  /* Better VGA2 clock for 1280x1024@75 */
2112                  if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2113               }
2114            }
2115         }
2116
2117      } else {   /* If not programming CRT2 */
2118
2119         VCLKIndex = VCLKIndexGEN;
2120         if(HwInfo->jChipType < SIS_315H) {
2121            if(ModeNo > 0x13) {
2122               if( (HwInfo->jChipType != SIS_630) &&
2123                   (HwInfo->jChipType != SIS_300) ) {
2124                  if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2125               }
2126            }
2127         }
2128      }
2129
2130   } else {       /*   LVDS  */
2131
2132      VCLKIndex = CRT2Index;
2133
2134      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2135
2136         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2137
2138            VCLKIndex &= 0x1f;
2139            tempbx = 0;
2140            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2141            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2142               tempbx += 2;
2143               if(SiS_Pr->SiS_ModeType > ModeVGA) {
2144                  if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2145               }
2146               if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2147                  tempbx = 4;
2148                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2149               } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2150                  tempbx = 6;
2151                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2152               }
2153            }
2154            switch(tempbx) {
2155              case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2156              case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2157              case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2158              case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2159              case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2160              case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2161              case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2162              case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2163              case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2164              default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2165            }
2166            VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2167
2168         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2169
2170            if(HwInfo->jChipType < SIS_315H) {
2171               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2172            } else {
2173               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2174            }
2175
2176            /* Special Timing: Barco iQ Pro R series */
2177            if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2178
2179            /* Special Timing: 848x480 parallel lvds */
2180            if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2181               if(HwInfo->jChipType < SIS_315H) {
2182                  VCLKIndex = VCLK34_300;
2183                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2184               } else {
2185                  VCLKIndex = VCLK34_315;
2186                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2187               }
2188            }
2189
2190         } else {
2191
2192            VCLKIndex = VCLKIndexGEN;
2193            if(HwInfo->jChipType < SIS_315H) {
2194               if(ModeNo > 0x13) {
2195                  if( (HwInfo->jChipType == SIS_630) &&
2196                      (HwInfo->jChipRevision >= 0x30) ) {
2197                     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2198                  }
2199               }
2200            }
2201         }
2202
2203      } else {  /* if not programming CRT2 */
2204
2205         VCLKIndex = VCLKIndexGEN;
2206         if(HwInfo->jChipType < SIS_315H) {
2207            if(ModeNo > 0x13) {
2208               if( (HwInfo->jChipType != SIS_630) &&
2209                   (HwInfo->jChipType != SIS_300) ) {
2210                  if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2211               }
2212 #if 0
2213               if(HwInfo->jChipType == SIS_730) {
2214                  if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2215                  if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2216               }
2217 #endif
2218            }
2219         }
2220
2221      }
2222
2223   }
2224
2225 #ifdef TWDEBUG
2226   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2227 #endif
2228
2229   return(VCLKIndex);
2230 }
2231
2232 /*********************************************/
2233 /*        SET CRT2 MODE TYPE REGISTERS       */
2234 /*********************************************/
2235
2236 static void
2237 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2238                     PSIS_HW_INFO HwInfo)
2239 {
2240   USHORT i,j,modeflag;
2241   USHORT tempcl,tempah=0;
2242 #if defined(SIS300) || defined(SIS315H)
2243   USHORT tempbl;
2244 #endif
2245 #ifdef SIS315H
2246   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
2247   USHORT tempah2, tempbl2;
2248 #endif
2249
2250   if(ModeNo <= 0x13) {
2251      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2252   } else if(SiS_Pr->UseCustomMode) {
2253      modeflag = SiS_Pr->CModeFlag;
2254   } else {
2255      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2256   }
2257
2258   /* BIOS does not do this (neither 301 nor LVDS) */
2259   /* (But it's harmless; see SetCRT2Offset) */
2260   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
2261
2262   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2263
2264      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2265      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2266
2267   } else {
2268
2269      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2270      if(HwInfo->jChipType >= SIS_315H) {
2271         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2272      }
2273
2274      tempcl = SiS_Pr->SiS_ModeType;
2275
2276      if(HwInfo->jChipType < SIS_315H) {
2277
2278 #ifdef SIS300    /* ---- 300 series ---- */
2279
2280         /* For 301BDH: (with LCD via LVDS) */
2281         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2282            tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2283            tempbl &= 0xef;
2284            tempbl |= 0x02;
2285            if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2286               tempbl |= 0x10;
2287               tempbl &= 0xfd;
2288            }
2289            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2290         }
2291
2292         if(ModeNo > 0x13) {
2293            tempcl -= ModeVGA;
2294            if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
2295               tempah = ((0x10 >> tempcl) | 0x80);
2296            }
2297         } else tempah = 0x80;
2298
2299         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2300
2301 #endif  /* SIS300 */
2302
2303      } else {
2304
2305 #ifdef SIS315H    /* ------- 315/330 series ------ */
2306
2307         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2308            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2309               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2310            }
2311         }
2312
2313         if(ModeNo > 0x13) {
2314            tempcl -= ModeVGA;
2315            if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
2316               tempah = (0x08 >> tempcl);
2317               if (tempah == 0) tempah = 1;
2318               tempah |= 0x40;
2319            }
2320         } else tempah = 0x40;
2321
2322         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2323
2324 #endif  /* SIS315H */
2325
2326      }
2327
2328      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2329
2330      if(HwInfo->jChipType < SIS_315H) {
2331         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2332      } else {
2333         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2334            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2335         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2336            if(IS_SIS740) {
2337               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2338            } else {
2339               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2340            }
2341         }
2342      }
2343
2344      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2345
2346         tempah = 0x01;
2347         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2348            tempah |= 0x02;
2349         }
2350         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2351            tempah ^= 0x05;
2352            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2353               tempah ^= 0x01;
2354            }
2355         }
2356
2357         if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2358
2359         if(HwInfo->jChipType < SIS_315H) {
2360
2361            tempah = (tempah << 5) & 0xFF;
2362            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2363            tempah = (tempah >> 5) & 0xFF;
2364
2365         } else {
2366
2367            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2368
2369         }
2370
2371         if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2372            tempah |= 0x10;
2373         }
2374
2375         if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2376            if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2377               (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
2378               tempah |= 0x80;
2379            }
2380         } else {
2381            tempah |= 0x80;
2382         }
2383
2384         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2385            if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2386               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2387                  tempah |= 0x20;
2388               }
2389            }
2390         }
2391
2392         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2393
2394         tempah = 0;
2395
2396         if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2397
2398         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2399            if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2400               tempah |= 0x40;
2401            }
2402         }
2403
2404         if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2405            (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)  ||
2406            ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
2407             (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2408            tempah |= 0x80;
2409         }
2410
2411         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2412
2413      } else {  /* LVDS */
2414
2415         if(HwInfo->jChipType >= SIS_315H) {
2416
2417            /* LVDS can only be slave in 8bpp modes */
2418            tempah = 0x80;
2419            if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2420               if(SiS_Pr->SiS_VBInfo & DriverMode) {
2421                  tempah |= 0x02;
2422               }
2423            }
2424
2425            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2426               tempah |= 0x02;
2427            }
2428
2429            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2430               tempah ^= 0x01;
2431            }
2432
2433            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2434               tempah = 1;
2435            }
2436
2437            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2438
2439         } else {
2440
2441            tempah = 0;
2442            if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2443               tempah |= 0x02;
2444            }
2445            tempah <<= 5;
2446
2447            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2448
2449            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2450
2451         }
2452
2453      }
2454
2455   }  /* LCDA */
2456
2457   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2458
2459      if(HwInfo->jChipType >= SIS_315H) {
2460
2461 #ifdef SIS315H
2462
2463         unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2464
2465         /* The following is nearly unpreditable and varies from machine
2466          * to machine. Especially the 301DH seems to be a real trouble
2467          * maker. Some BIOSes simply set the registers (like in the
2468          * NoLCD-if-statements here), some set them according to the
2469          * LCDA stuff. It is very likely that some machines are not
2470          * treated correctly in the following, very case-orientated
2471          * code. What do I do then...?
2472          */
2473
2474         /* 740 variants match for 30xB, 301B-DH, 30xLV */
2475
2476         if(!(IS_SIS740)) {
2477            tempah = 0x04;                                                  /* For all bridges */
2478            tempbl = 0xfb;
2479            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2480               tempah = 0x00;
2481               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2482                  tempbl = 0xff;
2483               }
2484            }
2485            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2486         }
2487
2488         /* The following two are responsible for eventually wrong colors
2489          * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2490          * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2491          * in a 650 box (Jake). What is the criteria?
2492          */
2493
2494         if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2495            tempah = 0x30;
2496            tempbl = 0xc0;
2497            if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2498               ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2499               tempah = 0x00;
2500               tempbl = 0x00;
2501            }
2502            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2503            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2504         } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2505            /* Fixes "TV-blue-bug" on 315+301 */
2506            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);     /* For 301   */
2507            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2508         } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2509            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xLV */
2510            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2511         } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2512            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xB-DH rev b0 (or "DH on 651"?) */
2513            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2514         } else {
2515            tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB (and 301BDH rev b1) */
2516            tempbl = 0xcf; tempbl2 = 0x3f;
2517            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2518               tempah = tempah2 = 0x00;
2519               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2520                  tempbl = tempbl2 = 0xff;
2521               }
2522            }
2523            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2524            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2525         }
2526
2527         if(IS_SIS740) {
2528            tempah = 0x80;
2529            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2530            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2531         } else {
2532            tempah = 0x00;
2533            tempbl = 0x7f;
2534            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2535               tempbl = 0xff;
2536               if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2537            }
2538            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2539         }
2540
2541 #if 0
2542         if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2543            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
2544         }
2545 #endif
2546
2547 #endif /* SIS315H */
2548
2549      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2550
2551         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2552
2553         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2554            (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2555                (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2556            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2557         } else {
2558            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2559         }
2560
2561      }
2562
2563   } else {  /* LVDS */
2564
2565 #ifdef SIS315H
2566      if(HwInfo->jChipType >= SIS_315H) {
2567
2568         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2569
2570            tempah = 0x04;
2571            tempbl = 0xfb;
2572            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2573               tempah = 0x00;
2574               if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2575            }
2576            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2577
2578            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2579               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2580            }
2581
2582            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2583
2584         } else if(HwInfo->jChipType == SIS_550) {
2585
2586            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2587            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2588
2589         }
2590
2591      }
2592 #endif
2593
2594   }
2595
2596 }
2597
2598 /*********************************************/
2599 /*            GET RESOLUTION DATA            */
2600 /*********************************************/
2601
2602 USHORT
2603 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2604 {
2605   if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2606   else               return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2607 }
2608
2609 static void
2610 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2611                    PSIS_HW_INFO HwInfo)
2612 {
2613   USHORT xres,yres,modeflag=0,resindex;
2614
2615   if(SiS_Pr->UseCustomMode) {
2616      xres = SiS_Pr->CHDisplay;
2617      if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2618      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2619      yres = SiS_Pr->CVDisplay;
2620      if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2621      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2622      return;
2623   }
2624
2625   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2626
2627   if(ModeNo <= 0x13) {
2628      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2629      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2630   } else {
2631      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2632      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2633      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2634   }
2635
2636   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2637
2638      if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2639         if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2640            if(yres == 350) yres = 400;
2641         }
2642         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2643            if(ModeNo == 0x12) yres = 400;
2644         }
2645      }
2646
2647      if(modeflag & HalfDCLK)       xres *= 2;
2648      if(modeflag & DoubleScanMode) yres *= 2;
2649
2650   }
2651
2652   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2653
2654 #if 0
2655         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2656            if(xres == 720) xres = 640;
2657         }
2658 #endif
2659
2660         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2661            switch(SiS_Pr->SiS_LCDResInfo) {
2662            case Panel_1024x768:
2663               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2664                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2665                     if(yres == 350) yres = 357;
2666                     if(yres == 400) yres = 420;
2667                     if(yres == 480) yres = 525;
2668                  }
2669               }
2670               break;
2671            case Panel_1280x1024:
2672               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2673                  /* BIOS bug - does this regardless of scaling */
2674                  if(yres == 400) yres = 405;
2675               }
2676               if(yres == 350) yres = 360;
2677               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2678                  if(yres == 360) yres = 375;
2679               }
2680               break;
2681            case Panel_1600x1200:
2682               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2683                  if(yres == 1024) yres = 1056;
2684               }
2685               break;
2686            }
2687         }
2688
2689   } else {
2690
2691      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2692         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2693            if(xres == 720) xres = 640;
2694         }
2695      } else if(xres == 720) xres = 640;
2696
2697      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2698         yres = 400;
2699         if(HwInfo->jChipType >= SIS_315H) {
2700            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2701         } else {
2702            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2703         }
2704         if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN)  yres = 480;
2705      }
2706
2707   }
2708   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2709   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2710 }
2711
2712 /*********************************************/
2713 /*           GET CRT2 TIMING DATA            */
2714 /*********************************************/
2715
2716 static BOOLEAN
2717 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2718                    USHORT RefreshRateTableIndex, USHORT *ResIndex,
2719                    USHORT *DisplayType)
2720  {
2721   USHORT modeflag=0;
2722
2723   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2724      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2725         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2726      }
2727   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2728      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))    return FALSE;
2729   } else
2730      return FALSE;
2731
2732   if(ModeNo <= 0x13) {
2733      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2734      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2735   } else {
2736      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2737      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2738   }
2739
2740   (*ResIndex) &= 0x3F;
2741
2742   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2743      (*DisplayType) = 18;
2744      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2745      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2746         (*DisplayType) += 2;
2747         if(SiS_Pr->SiS_ModeType > ModeVGA) {
2748            if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2749         }
2750         if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2751            (*DisplayType) = 18;  /* PALM uses NTSC data */
2752            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2753         } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2754            (*DisplayType) = 20;  /* PALN uses PAL data  */
2755            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2756         }
2757      }
2758   } else {
2759      switch(SiS_Pr->SiS_LCDResInfo) {
2760      case Panel_640x480:   (*DisplayType) = 50; break;
2761      case Panel_640x480_2: (*DisplayType) = 52; break;
2762      case Panel_640x480_3: (*DisplayType) = 54; break;
2763      case Panel_800x600:   (*DisplayType) =  0; break;
2764      case Panel_1024x600:  (*DisplayType) = 23; break;
2765      case Panel_1024x768:  (*DisplayType) =  4; break;
2766      case Panel_1152x768:  (*DisplayType) = 27; break;
2767      case Panel_1280x768:  (*DisplayType) = 40; break;
2768      case Panel_1280x1024: (*DisplayType) =  8; break;
2769      case Panel_1400x1050: (*DisplayType) = 14; break;
2770      case Panel_1600x1200: (*DisplayType) = 36; break;
2771      default: return FALSE;
2772      }
2773
2774      if(modeflag & HalfDCLK) (*DisplayType)++;
2775
2776      switch(SiS_Pr->SiS_LCDResInfo) {
2777      case Panel_640x480:
2778      case Panel_640x480_2:
2779      case Panel_640x480_3:
2780         break;
2781      default:
2782         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2783      }
2784
2785      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2786         (*DisplayType) = 12;
2787         if(modeflag & HalfDCLK) (*DisplayType)++;
2788      }
2789   }
2790
2791 #if 0
2792   if(SiS_Pr->SiS_IF_DEF_FSTN) {
2793      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2794         (*DisplayType) = 22;
2795      }
2796   }
2797 #endif
2798
2799   return TRUE;
2800 }
2801
2802 static void
2803 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2804                USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2805                PSIS_HW_INFO HwInfo)
2806 {
2807   USHORT tempbx=0,tempal=0,resinfo=0;
2808
2809   if(ModeNo <= 0x13) {
2810      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2811   } else {
2812      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2813      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2814   }
2815
2816   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2817
2818      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2819
2820         tempbx = SiS_Pr->SiS_LCDResInfo;
2821         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2822
2823         if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2824            if     (resinfo == SIS_RI_1280x800)  tempal =  9;
2825            else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2826         }
2827
2828         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {  /* Pass 1:1 only (center-screen handled outside) */
2829            tempbx = 100;
2830            if(ModeNo >= 0x13) {
2831               tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2832               if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
2833                  (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
2834                  /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
2835                  if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        tempal = 0x08;
2836                  else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
2837                  else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
2838               }
2839            }
2840         }
2841
2842 #ifdef SIS315H
2843         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2844            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2845               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2846                  tempbx = 200;
2847                  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2848               }
2849            }
2850         }
2851 #endif
2852
2853      } else {                                                   /* TV */
2854
2855         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2856            /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2857            tempbx = 2;
2858            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2859               tempbx = 13;
2860               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2861            }
2862         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2863            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
2864            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2865            else                                         tempbx = 5;
2866            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2867         } else {
2868            if(SiS_Pr->SiS_TVMode & TVSetPAL)            tempbx = 3;
2869            else                                         tempbx = 4;
2870            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2871         }
2872
2873      }
2874
2875      tempal &= 0x3F;
2876
2877      if(ModeNo > 0x13) {
2878         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2879            if(tempal == 6) tempal = 7;
2880            if((resinfo == SIS_RI_720x480) ||
2881               (resinfo == SIS_RI_720x576) ||
2882               (resinfo == SIS_RI_768x576)) {
2883               tempal = 6;
2884               if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
2885                  if(resinfo == SIS_RI_720x480) tempal = 9;
2886               }
2887            }
2888            if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2889               if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
2890                  if(resinfo == SIS_RI_1024x768) tempal = 8;
2891               }
2892               if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
2893                  if((resinfo == SIS_RI_720x576) ||
2894                     (resinfo == SIS_RI_768x576)) {
2895                     tempal = 8;
2896                  }
2897                  if(resinfo == SIS_RI_1280x720) tempal = 9;
2898               }
2899            }
2900         }
2901      }
2902
2903      *CRT2Index = tempbx;
2904      *ResIndex = tempal;
2905
2906   } else {   /* LVDS, 301B-DH (if running on LCD) */
2907
2908      tempbx = 0;
2909      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2910         tempbx = 10;
2911         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2912         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2913            tempbx += 2;
2914            if(SiS_Pr->SiS_ModeType > ModeVGA) {
2915               if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2916            }
2917            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2918               tempbx = 90;
2919               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2920            } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2921               tempbx = 92;
2922               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2923            }
2924         }
2925      } else {
2926         switch(SiS_Pr->SiS_LCDResInfo) {
2927         case Panel_640x480:   tempbx = 6;  break;
2928         case Panel_640x480_2: tempbx = 30; break;
2929         case Panel_640x480_3: tempbx = 30; break;
2930         case Panel_800x600:   tempbx = 0;  break;
2931         case Panel_1024x600:  tempbx = 15; break;
2932         case Panel_1024x768:  tempbx = 2;  break;
2933         case Panel_1152x768:  tempbx = 17; break;
2934         case Panel_1280x768:  tempbx = 18; break;
2935         case Panel_1280x1024: tempbx = 4;  break;
2936         case Panel_1400x1050: tempbx = 8;  break;
2937         case Panel_1600x1200: tempbx = 21; break;
2938         case Panel_Barco1366: tempbx = 80; break;
2939         }
2940
2941         switch(SiS_Pr->SiS_LCDResInfo) {
2942         case Panel_640x480:
2943         case Panel_640x480_2:
2944         case Panel_640x480_3:
2945            break;
2946         default:
2947            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2948         }
2949
2950         if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
2951
2952         if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2953            tempbx = 82;
2954            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2955         } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2956            tempbx = 84;
2957            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2958         }
2959
2960      }
2961
2962      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2963         if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
2964         if(HwInfo->jChipType < SIS_315H) {
2965            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2966         }
2967      }
2968
2969      (*CRT2Index) = tempbx;
2970      (*ResIndex) = tempal & 0x1F;
2971   }
2972 }
2973
2974 static void
2975 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2976                    USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
2977 {
2978   USHORT tempax=0,tempbx=0;
2979   USHORT temp1=0,modeflag=0,tempcx=0;
2980   USHORT index;
2981
2982   SiS_Pr->SiS_RVBHCMAX  = 1;
2983   SiS_Pr->SiS_RVBHCFACT = 1;
2984
2985   if(ModeNo <= 0x13) {
2986
2987      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2988      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
2989
2990      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
2991      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
2992      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
2993
2994   } else {
2995
2996      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2997      index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2998
2999      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3000      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3001      tempax &= 0x03FF;
3002      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3003      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3004      tempcx &= 0x0100;
3005      tempcx <<= 2;
3006      tempbx |= tempcx;
3007      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3008
3009   }
3010
3011   if(temp1 & 0x01) tempbx |= 0x0100;
3012   if(temp1 & 0x20) tempbx |= 0x0200;
3013
3014   tempax += 5;
3015
3016   /* Charx8Dot is no more used (and assumed), so we set it */
3017   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3018      modeflag |= Charx8Dot;
3019   }
3020
3021   if(modeflag & Charx8Dot) tempax *= 8;
3022   else                     tempax *= 9;
3023
3024   if(modeflag & HalfDCLK)  tempax <<= 1;
3025
3026   tempbx++;
3027
3028   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3029   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3030 }
3031
3032 static void
3033 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3034                     USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3035 {
3036    USHORT CRT2Index, ResIndex;
3037    const SiS_LVDSDataStruct *LVDSData = NULL;
3038
3039    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3040
3041    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3042       SiS_Pr->SiS_RVBHCMAX  = 1;
3043       SiS_Pr->SiS_RVBHCFACT = 1;
3044       SiS_Pr->SiS_NewFlickerMode = 0;
3045       SiS_Pr->SiS_RVBHRS = 50;
3046       SiS_Pr->SiS_RY1COE = 0;
3047       SiS_Pr->SiS_RY2COE = 0;
3048       SiS_Pr->SiS_RY3COE = 0;
3049       SiS_Pr->SiS_RY4COE = 0;
3050    }
3051
3052    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3053
3054 #ifdef SIS315H
3055       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3056          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3057             if(SiS_Pr->UseCustomMode) {
3058                SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3059                SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3060             } else {
3061                if(ModeNo < 0x13) {
3062                   ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3063                } else {
3064                   ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3065                   /* Special for our 3 types, others custom (works with default) */
3066                   if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3067                      (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
3068                      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        ResIndex = 0x08;
3069                      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
3070                      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
3071                   }
3072                   /* Special for 1280x720 TMDS <> LVDS */
3073                   if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3074                      (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  720)) {
3075                      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
3076                         if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
3077                      }
3078                   }
3079                }
3080                SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3081                SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3082                SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3083                SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3084             }
3085          } else {
3086             SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3087             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3088          }
3089       } else {
3090          /* This handles custom modes and custom panels */
3091          SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3092          SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3093          SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3094          SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3095          SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3096          SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3097       }
3098
3099       SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3100
3101 #endif
3102
3103    } else {
3104
3105       /* 301BDH needs LVDS Data */
3106       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3107          SiS_Pr->SiS_IF_DEF_LVDS = 1;
3108       }
3109
3110       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3111                                 &CRT2Index, &ResIndex, HwInfo);
3112
3113       /* 301BDH needs LVDS Data */
3114       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3115          SiS_Pr->SiS_IF_DEF_LVDS = 0;
3116       }
3117
3118       switch (CRT2Index) {
3119          case  0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3120          case  1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
3121          case  2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3122          case  3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
3123          case  4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
3124          case  5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
3125          case  6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3126          case  7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
3127          case  8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
3128          case  9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
3129          case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3130          case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3131          case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3132          case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3133          case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
3134          case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3135          case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
3136          case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
3137          case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
3138          case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
3139          case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
3140          case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
3141          case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
3142          case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
3143          case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3144          case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3145          case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3146          case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
3147          case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3148          case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3149          case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3150          case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3151          case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3152          case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3153          case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;  /* Super Overscan */
3154          default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3155       }
3156
3157       SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3158       SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3159       SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3160       SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3161
3162       if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3163          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3164             if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3165                SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3166                SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3167                if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3168                   if(ResIndex < 0x08) {
3169                      SiS_Pr->SiS_HDE = 1280;
3170                      SiS_Pr->SiS_VDE = 1024;
3171                   }
3172                }
3173             }
3174          }
3175       }
3176    }
3177 }
3178
3179 static void
3180 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3181                    USHORT RefreshRateTableIndex,
3182                    PSIS_HW_INFO HwInfo)
3183 {
3184   UCHAR  *ROMAddr = NULL;
3185   USHORT tempax,tempbx,modeflag,romptr=0;
3186   USHORT resinfo,CRT2Index,ResIndex;
3187   const SiS_LCDDataStruct *LCDPtr = NULL;
3188   const SiS_TVDataStruct  *TVPtr  = NULL;
3189 #ifdef SIS315H
3190   SHORT  resinfo661;
3191 #endif
3192
3193   if(ModeNo <= 0x13) {
3194      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3195      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3196   } else if(SiS_Pr->UseCustomMode) {
3197      modeflag = SiS_Pr->CModeFlag;
3198      resinfo = 0;
3199   } else {
3200      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3201      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3202 #ifdef SIS315H
3203      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3204      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3205          (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3206          (resinfo661 >= 0)                     &&
3207          (SiS_Pr->SiS_NeedRomModeData) ) {
3208         if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3209            if((romptr = (SISGETROMW(21)))) {
3210               romptr += (resinfo661 * 10);
3211               ROMAddr = HwInfo->pjVirtualRomBase;
3212            }
3213         }
3214      }
3215 #endif
3216   }
3217   
3218   SiS_Pr->SiS_NewFlickerMode = 0;
3219   SiS_Pr->SiS_RVBHRS = 50;
3220   SiS_Pr->SiS_RY1COE = 0;
3221   SiS_Pr->SiS_RY2COE = 0;
3222   SiS_Pr->SiS_RY3COE = 0;
3223   SiS_Pr->SiS_RY4COE = 0;
3224
3225   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3226
3227   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3228
3229      if(SiS_Pr->UseCustomMode) {
3230
3231         SiS_Pr->SiS_RVBHCMAX  = 1;
3232         SiS_Pr->SiS_RVBHCFACT = 1;
3233         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3234         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3235         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3236         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3237         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3238         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3239
3240      } else {
3241
3242         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3243
3244      }
3245
3246   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3247
3248      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3249                     &CRT2Index,&ResIndex,HwInfo);
3250
3251      switch(CRT2Index) {
3252         case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3253         case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3254         case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3255         case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3256         case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3257         case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3258         case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3259         case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3260         case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3261         case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3262         case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3263         case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3264         case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3265         default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3266      }
3267
3268      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3269      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3270      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3271      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3272      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3273      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3274      SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3275      SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3276      if(modeflag & HalfDCLK) {
3277         SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3278      }
3279
3280      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3281
3282         if((resinfo == SIS_RI_1024x768)  ||
3283            (resinfo == SIS_RI_1280x1024) ||
3284            (resinfo == SIS_RI_1280x720)) {
3285            SiS_Pr->SiS_NewFlickerMode = 0x40;
3286         }
3287
3288         if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3289
3290         SiS_Pr->SiS_HT = ExtHiTVHT;
3291         SiS_Pr->SiS_VT = ExtHiTVVT;
3292         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3293            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3294               SiS_Pr->SiS_HT = StHiTVHT;
3295               SiS_Pr->SiS_VT = StHiTVVT;
3296 #if 0
3297               if(!(modeflag & Charx8Dot)) {
3298                  SiS_Pr->SiS_HT = StHiTextTVHT;
3299                  SiS_Pr->SiS_VT = StHiTextTVVT;
3300               }
3301 #endif
3302            }
3303         }
3304
3305      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3306
3307         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3308            SiS_Pr->SiS_HT = 1650;
3309            SiS_Pr->SiS_VT = 750;
3310         } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3311            SiS_Pr->SiS_HT = NTSCHT;
3312            SiS_Pr->SiS_VT = NTSCVT;
3313         } else {
3314            SiS_Pr->SiS_HT = NTSCHT;
3315            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3316            SiS_Pr->SiS_VT = NTSCVT;
3317         }
3318
3319      } else {
3320
3321         SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3322         SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3323         SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3324         SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3325
3326         if(modeflag & HalfDCLK) {
3327            SiS_Pr->SiS_RY1COE = 0x00;
3328            SiS_Pr->SiS_RY2COE = 0xf4;
3329            SiS_Pr->SiS_RY3COE = 0x10;
3330            SiS_Pr->SiS_RY4COE = 0x38;
3331         }
3332
3333         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3334            SiS_Pr->SiS_HT = NTSCHT;
3335            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3336            SiS_Pr->SiS_VT = NTSCVT;
3337         } else {
3338            SiS_Pr->SiS_HT = PALHT;
3339            SiS_Pr->SiS_VT = PALVT;
3340         }
3341
3342      }
3343
3344   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3345
3346      SiS_Pr->SiS_RVBHCMAX  = 1;
3347      SiS_Pr->SiS_RVBHCFACT = 1;
3348
3349      if(SiS_Pr->UseCustomMode) {
3350
3351         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3352         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3353         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3354         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3355         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3356         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3357
3358      } else {
3359
3360         BOOLEAN gotit = FALSE;
3361
3362         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3363
3364            SiS_Pr->SiS_VGAHT     = SiS_Pr->PanelHT;
3365            SiS_Pr->SiS_VGAVT     = SiS_Pr->PanelVT;
3366            SiS_Pr->SiS_HT        = SiS_Pr->PanelHT;
3367            SiS_Pr->SiS_VT        = SiS_Pr->PanelVT;
3368            gotit = TRUE;
3369
3370         } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3371
3372 #ifdef SIS315H
3373            SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3374            SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3375            SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3376            SiS_Pr->SiS_VGAVT     = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3377            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3378            SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3379            if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3380 #endif
3381
3382         }
3383
3384         if(!gotit) {
3385
3386            SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3387                           &CRT2Index,&ResIndex,HwInfo);
3388
3389            switch(CRT2Index) {
3390               case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3391               case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3392               case Panel_1280x720      :
3393               case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3394               case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3395               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3396               case Panel_1280x768_3    :
3397               case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data;    break;
3398               case Panel_1280x800      :
3399               case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3400               case Panel_1280x960      :
3401               case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3402               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3403               case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3404               case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3405               case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3406               case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3407               case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3408               case Panel_1680x1050     :
3409               case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3410               case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
3411 #ifdef SIS315H
3412               case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3413               case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3414 #endif
3415               default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3416            }
3417
3418 #ifdef TWDEBUG
3419            xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3420 #endif
3421
3422            SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3423            SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3424            SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3425            SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3426            SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3427            SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3428
3429         }
3430
3431         tempax = SiS_Pr->PanelXRes;
3432         tempbx = SiS_Pr->PanelYRes;
3433
3434         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3435            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3436               if(HwInfo->jChipType < SIS_315H) {
3437                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3438                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3439               }
3440            } else {
3441               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3442               else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3443               else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3444               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3445               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3446               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3447            }
3448         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3449            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3450            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3451            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3452         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3453            if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3454            else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3455            else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3456         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3457            if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3458               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3459               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3460            }
3461         }
3462
3463         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3464            tempax = SiS_Pr->SiS_VGAHDE;
3465            tempbx = SiS_Pr->SiS_VGAVDE;
3466         }
3467
3468         SiS_Pr->SiS_HDE = tempax;
3469         SiS_Pr->SiS_VDE = tempbx;
3470      }
3471   }
3472 }
3473
3474 static void
3475 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3476                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3477 {
3478
3479   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3480
3481      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3482         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3483      } else {
3484         if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3485            /* Need LVDS Data for LCD on 301B-DH */
3486            SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3487         } else {
3488            SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3489         }
3490      }
3491
3492   } else {
3493
3494      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3495
3496   }
3497 }
3498
3499 /*********************************************/
3500 /*         GET LVDS DES (SKEW) DATA          */
3501 /*********************************************/
3502
3503 static void
3504 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3505                   USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3506                   USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3507 {
3508   USHORT modeflag;
3509
3510   if(ModeNo <= 0x13) {
3511      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3512      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3513   } else {
3514      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3515      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3516   }
3517
3518   (*ResIndex) &= 0x1F;
3519   (*PanelIndex) = 0;
3520
3521   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3522      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3523         (*PanelIndex) = 50;
3524         if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3525         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3526         /* Nothing special needed for SOverscan    */
3527         /* PALM uses NTSC data, PALN uses PAL data */
3528      }
3529   }
3530
3531   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3532      *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3533      if(HwInfo->jChipType >= SIS_661) {
3534         /* As long as we don's use the BIOS tables, we
3535          * need to convert the TypeInfo as for 315 series
3536          */
3537         (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3538      }
3539      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3540         (*PanelIndex) += 16;
3541         if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3542            (*PanelIndex) = 32;
3543            if(modeflag & HalfDCLK) (*PanelIndex)++;
3544         }
3545      }
3546   }
3547
3548   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3549      if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3550         (*ResIndex) = 7;
3551         if(HwInfo->jChipType < SIS_315H) {
3552            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3553         }
3554      }
3555   }
3556 }
3557
3558 static void
3559 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3560                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3561 {
3562   USHORT modeflag;
3563   USHORT PanelIndex,ResIndex;
3564   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
3565
3566   SiS_Pr->SiS_LCDHDES = 0;
3567   SiS_Pr->SiS_LCDVDES = 0;
3568
3569   if( (SiS_Pr->UseCustomMode)                    ||
3570       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3571       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3572       ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3573        (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3574        (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3575      return;
3576   }
3577
3578   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3579
3580 #ifdef SIS315H
3581      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3582         /* non-pass 1:1 only, see above */
3583         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3584            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3585         }
3586         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3587            SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3588         }
3589      }
3590      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3591         switch(SiS_Pr->SiS_CustomT) {
3592         case CUT_UNIWILL1024:
3593         case CUT_UNIWILL10242:
3594         case CUT_CLEVO1400:
3595            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3596               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3597            }
3598            break;
3599         }
3600         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3601            if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3602               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3603            }
3604         }
3605      }
3606 #endif
3607
3608   } else {
3609
3610      SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3611                        &PanelIndex, &ResIndex, HwInfo);
3612
3613      switch(PanelIndex) {
3614         case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;    break;   /* ---  */
3615         case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;    break;
3616         case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;    break;
3617         case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;    break;
3618         case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;    break;
3619         case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;    break;
3620         case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;    break;
3621         case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;    break;
3622         case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;    break;
3623         case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;    break;
3624         case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;    break;
3625         case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;    break;
3626         case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;    break;
3627         case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;    break;
3628         case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;    break;
3629         case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;    break;
3630         case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;    break;    /* --- */
3631         case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;    break;
3632         case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;    break;
3633         case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;    break;
3634         case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;    break;
3635         case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;    break;
3636         case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;    break;
3637         case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;    break;
3638         case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;    break;
3639         case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;    break;
3640         case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;    break;
3641         case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;    break;
3642         case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;    break;
3643         case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;    break;
3644         case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;    break;
3645         case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;    break;
3646         case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;    break;    /* pass 1:1 */
3647         case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;    break;
3648         case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break;    /* TV */
3649         case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3650         case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;  break;
3651         case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;  break;
3652         default: return;
3653      }
3654
3655      SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3656      SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3657
3658      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3659         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3660         if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3661            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3662         } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3663            if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3664               if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3665                  if(HwInfo->jChipType < SIS_315H) {
3666                     if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3667                  } else {
3668                     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
3669                     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3670                     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3671                     if(!(modeflag & HalfDCLK)) {
3672                        SiS_Pr->SiS_LCDHDES = 320;
3673                        if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3674                        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3675                     }
3676                  }
3677               }
3678            }
3679         }
3680      }
3681   }
3682 }
3683
3684 /*********************************************/
3685 /*           DISABLE VIDEO BRIDGE            */
3686 /*********************************************/
3687
3688 /* NEVER use any variables (VBInfo), this will be called
3689  * from outside the context of modeswitch!
3690  * MUST call getVBType before calling this
3691  */
3692 void
3693 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3694 {
3695 #ifdef SIS315H
3696   USHORT tempah,pushax=0,modenum;
3697 #endif
3698   USHORT temp=0;
3699
3700   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3701
3702      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
3703
3704         if(HwInfo->jChipType < SIS_315H) {
3705
3706 #ifdef SIS300      /* 300 series */
3707
3708            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3709               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3710                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3711               } else {
3712                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3713               }
3714               SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3715            }
3716            if(SiS_Is301B(SiS_Pr)) {
3717               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3718               SiS_ShortDelay(SiS_Pr,1);
3719            }
3720            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3721            SiS_DisplayOff(SiS_Pr);
3722            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3723            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3724            SiS_UnLockCRT2(SiS_Pr,HwInfo);
3725            if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3726               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3727               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3728            }
3729            if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3730                (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3731               SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3732               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3733                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3734               } else {
3735                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3736               }
3737            }
3738
3739 #endif  /* SIS300 */
3740
3741         } else {
3742
3743 #ifdef SIS315H     /* 315 series */
3744
3745            BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3746                               (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3747
3748            modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3749
3750            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3751
3752 #ifdef SET_EMI
3753               if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3754                  if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3755                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3756                  }
3757               }
3758 #endif
3759               if( (modenum <= 0x13)                  ||
3760                   (SiS_IsVAMode(SiS_Pr,HwInfo))      ||
3761                   (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3762                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3763                  if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3764               }
3765
3766               if(!custom1) {
3767                  SiS_DDC2Delay(SiS_Pr,0xff00);
3768                  SiS_DDC2Delay(SiS_Pr,0xe000);
3769                  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3770                  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3771                  if(IS_SIS740) {
3772                     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3773                  }
3774                  SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3775               }
3776
3777            }
3778
3779            if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3780               tempah = 0xef;
3781               if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3782               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3783            }
3784
3785            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3786               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3787            }
3788
3789            tempah = 0x3f;
3790            if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3791               tempah = 0x7f;
3792               if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3793            }
3794            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3795
3796            if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3797               ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3798
3799               SiS_DisplayOff(SiS_Pr);
3800               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3801                  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3802               }
3803               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3804               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3805
3806            }
3807
3808            if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3809               ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3810
3811               if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3812                  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3813                  SiS_DisplayOff(SiS_Pr);
3814               }
3815               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3816
3817               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3818                  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3819               }
3820
3821               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3822               temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3823               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3824               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3825               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3826
3827            }
3828
3829            if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3830               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3831            }
3832
3833            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3834
3835               if(!custom1) {
3836
3837                  if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3838                     if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3839                        if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3840                           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3841                        }
3842                     }
3843                  }
3844
3845                  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3846
3847                  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3848                     if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3849                        SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3850                     }
3851                  }
3852
3853               } else {
3854
3855                  if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3856                     (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3857                     if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3858                        (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3859                        SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3860                        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3861                        SiS_PanelDelay(SiS_Pr, HwInfo, 4);
3862                     }
3863                  }
3864
3865               }
3866            }
3867
3868 #endif /* SIS315H */
3869
3870         }
3871
3872      } else {     /* ============ For 301 ================ */
3873
3874         if(HwInfo->jChipType < SIS_315H) {
3875 #ifdef SIS300
3876            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3877               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3878               SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3879            }
3880 #endif
3881         }
3882
3883         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
3884         SiS_DisplayOff(SiS_Pr);
3885
3886         if(HwInfo->jChipType >= SIS_315H) {
3887            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3888         }
3889
3890         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
3891
3892         if(HwInfo->jChipType >= SIS_315H) {
3893             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3894             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3895             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
3896             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3897         } else {
3898 #ifdef SIS300
3899             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
3900             if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3901                 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3902                 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3903                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3904             }
3905 #endif
3906         }
3907
3908       }
3909
3910   } else {     /* ============ For LVDS =============*/
3911
3912     if(HwInfo->jChipType < SIS_315H) {
3913
3914 #ifdef SIS300   /* 300 series */
3915
3916         if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
3917            SiS_SetCH700x(SiS_Pr,0x090E);
3918         }
3919
3920         if(HwInfo->jChipType == SIS_730) {
3921            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3922               SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3923            }
3924            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3925               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3926               SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3927            }
3928         } else {
3929            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3930               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
3931                  if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3932                     SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3933                     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
3934                        SiS_DisplayOff(SiS_Pr);
3935                     }
3936                     SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3937                     SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3938                  }
3939               }
3940            }
3941         }
3942
3943         SiS_DisplayOff(SiS_Pr);
3944
3945         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3946
3947         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3948         SiS_UnLockCRT2(SiS_Pr,HwInfo);
3949         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3950         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3951
3952         if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3953             (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3954            SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3955            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3956         }
3957
3958 #endif  /* SIS300 */
3959
3960     } else {
3961
3962 #ifdef SIS315H  /* 315 series */
3963
3964         if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3965           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
3966         }
3967
3968         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3969
3970            if(HwInfo->jChipType == SIS_740) {
3971               temp = SiS_GetCH701x(SiS_Pr,0x61);
3972               if(temp < 1) {
3973                  SiS_SetCH701x(SiS_Pr,0xac76);
3974                  SiS_SetCH701x(SiS_Pr,0x0066);
3975               }
3976
3977               if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3978                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3979                  SiS_SetCH701x(SiS_Pr,0x3e49);
3980               }
3981            }
3982
3983            if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3984                (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
3985               SiS_Chrontel701xBLOff(SiS_Pr);
3986               SiS_Chrontel701xOff(SiS_Pr,HwInfo);
3987            }
3988
3989            if(HwInfo->jChipType != SIS_740) {
3990               if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3991                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3992                  SiS_SetCH701x(SiS_Pr,0x0149);
3993               }
3994            }
3995
3996         }
3997
3998         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
3999            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4000            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4001         }
4002
4003         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4004             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4005             (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4006            SiS_DisplayOff(SiS_Pr);
4007         }
4008
4009         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4010             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4011             (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4012            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4013         }
4014
4015         if(HwInfo->jChipType == SIS_740) {
4016            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4017         }
4018
4019         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4020
4021         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4022             (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4023             (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4024            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4025         }
4026
4027         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4028            if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4029               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4030               if(HwInfo->jChipType == SIS_550) {
4031                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4032                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4033               }
4034            }
4035         } else {
4036            if(HwInfo->jChipType == SIS_740) {
4037               if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4038                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4039               }
4040            } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4041               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4042            }
4043         }
4044
4045         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4046            if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4047               /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4048            } else {
4049               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4050            }
4051         }
4052
4053         SiS_UnLockCRT2(SiS_Pr,HwInfo);
4054
4055         if(HwInfo->jChipType == SIS_550) {
4056            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4057            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4058         } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4059                    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4060                    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4061            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4062         }
4063
4064         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4065            if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4066               if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4067                  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4068                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4069               }
4070            }
4071         }
4072
4073 #endif  /* SIS315H */
4074
4075     }  /* 315 series */
4076
4077   }  /* LVDS */
4078
4079 }
4080
4081 /*********************************************/
4082 /*            ENABLE VIDEO BRIDGE            */
4083 /*********************************************/
4084
4085 /* NEVER use any variables (VBInfo), this will be called
4086  * from outside the context of a mode switch!
4087  * MUST call getVBType before calling this
4088  */
4089 void
4090 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4091 {
4092   USHORT temp=0,tempah;
4093 #ifdef SIS315H
4094   USHORT temp1,pushax=0;
4095   BOOLEAN delaylong = FALSE;
4096 #endif
4097
4098   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4099
4100     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
4101
4102       if(HwInfo->jChipType < SIS_315H) {
4103
4104 #ifdef SIS300     /* 300 series */
4105
4106          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4107             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4108                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4109             } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4110                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4111             }
4112             if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4113                if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4114                   SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4115                }
4116             }
4117          }
4118
4119          if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4120             (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4121
4122             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* Enable CRT2 */
4123             SiS_DisplayOn(SiS_Pr);
4124             SiS_UnLockCRT2(SiS_Pr,HwInfo);
4125             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4126             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4127                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4128             } else {
4129                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4130             }
4131             if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4132                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4133                   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4134                      SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4135                   }
4136                   SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4137                   SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4138                }
4139             }
4140
4141          } else {
4142
4143             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4144             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4145                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4146                if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4147             }
4148             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4149             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4150             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4151             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4152             SiS_DisplayOn(SiS_Pr);
4153             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4154                if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4155                   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4156                      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4157                         SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4158                      }
4159                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4160                   }
4161                }
4162             }
4163
4164          }
4165
4166
4167 #endif /* SIS300 */
4168
4169       } else {
4170
4171 #ifdef SIS315H    /* 315 series */
4172
4173 #ifdef SET_EMI
4174          UCHAR   r30=0, r31=0, r32=0, r33=0, cr36=0;
4175          /* USHORT  emidelay=0; */
4176 #endif
4177
4178          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4179             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4180 #ifdef SET_EMI
4181             if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4182                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4183             }
4184 #endif
4185          }
4186
4187          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4188             tempah = 0x10;
4189             if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4190                if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4191                else                              tempah = 0x08;
4192             }
4193             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4194          }
4195
4196          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4197
4198             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4199             SiS_DisplayOff(SiS_Pr);
4200             pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4201             if(IS_SIS740) {
4202                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4203             }
4204
4205             if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4206                if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4207                   SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4208                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4209                   SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4210                   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4211                      SiS_GenericDelay(SiS_Pr, 0x4500);
4212                   }
4213                }
4214             }
4215
4216             if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4217                SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4218                delaylong = TRUE;
4219             }
4220
4221          }
4222
4223          if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4224
4225             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4226             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4227                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4228                if(!(tempah & SetCRT2ToRAMDAC)) {
4229                   if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4230                }
4231             }
4232             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4233
4234             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4235
4236             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4237             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4238
4239             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4240                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4241             }
4242
4243          } else {
4244
4245             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4246
4247          }
4248
4249          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4250          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4251
4252          tempah = 0xc0;
4253          if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4254             tempah = 0x80;
4255             if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4256          }
4257          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4258
4259          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4260
4261             SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4262
4263             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4264             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4265
4266             if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4267 #ifdef SET_EMI
4268                if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4269                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4270                }
4271 #endif
4272                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4273
4274                if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4275 #ifdef SET_EMI
4276                   cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4277
4278                   if(SiS_Pr->SiS_ROMNew) {
4279                      UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
4280                      USHORT romptr   = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4281                      if(romptr) {
4282                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4283                         SiS_Pr->EMI_30 = 0;
4284                         SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
4285                         SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
4286                         SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
4287                         if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4288                         /* emidelay = SISGETROMW((romptr + 0x22)); */
4289                         SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4290                      }
4291                   }
4292
4293                   /*                                              (P4_30|0x40)  */
4294                   /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4295                   /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4296                   /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4297                   /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4298                   /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4299                   /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4300                   /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4301                   /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4302                   /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4303
4304                   if(SiS_Pr->HaveEMI) {
4305                      r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4306                      r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4307                   } else {
4308                      r30 = 0;
4309                   }
4310
4311                   /* EMI_30 is read at driver start; however, the BIOS sets this
4312                    * (if it is used) only if the LCD is in use. In case we caught
4313                    * the machine while on TV output, this bit is not set and we
4314                    * don't know if it should be set - hence our detection is wrong.
4315                    * Work-around this here:
4316                    */
4317
4318                   if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4319                      switch((cr36 & 0x0f)) {
4320                      case 2:
4321                         r30 |= 0x40;
4322                         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4323                         if(!SiS_Pr->HaveEMI) {
4324                            r31 = 0x05; r32 = 0x60; r33 = 0x33;
4325                            if((cr36 & 0xf0) == 0x30) {
4326                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4327                            }
4328                         }
4329                         break;
4330                      case 3:  /* 1280x1024 */
4331                         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4332                         if(!SiS_Pr->HaveEMI) {
4333                            r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4334                            if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4335                               r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4336                            }
4337                         }
4338                         break;
4339                      case 9:  /* 1400x1050 */
4340                         r30 |= 0x40;
4341                         if(!SiS_Pr->HaveEMI) {
4342                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4343                            if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4344                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4345                            }
4346                         }
4347                         break;
4348                      case 11: /* 1600x1200 - unknown */
4349                         r30 |= 0x40;
4350                         if(!SiS_Pr->HaveEMI) {
4351                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4352                         }
4353                      }
4354                   }
4355
4356                   /* BIOS values don't work so well sometimes */
4357                   if(!SiS_Pr->OverruleEMI) {
4358 #ifdef COMPAL_HACK
4359                      if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4360                         if((cr36 & 0x0f) == 0x09) {
4361                            r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4362                         }
4363                      }
4364 #endif
4365 #ifdef COMPAQ_HACK
4366                      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4367                         if((cr36 & 0x0f) == 0x03) {
4368                            r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4369                         }
4370                      }
4371 #endif
4372 #ifdef ASUS_HACK
4373                      if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4374                         if((cr36 & 0x0f) == 0x02) {
4375                            /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4376                            /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4377                            /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4378                            /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4379                         }
4380                      }
4381 #endif
4382                   }
4383
4384                   if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4385                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4386                   }
4387                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4388                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4389                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4390 #endif  /* SET_EMI */
4391
4392                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4393
4394 #ifdef SET_EMI
4395                   if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4396                       (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4397                      if(r30 & 0x40) {
4398                         SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4399                         if(delaylong) {
4400                            SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4401                            delaylong = FALSE;
4402                         }
4403                         SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4404                         if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4405                            SiS_GenericDelay(SiS_Pr, 0x500);
4406                         }
4407                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4408                      }
4409                   }
4410 #endif
4411                }
4412             }
4413
4414             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4415                if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4416                   SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4417                   if(delaylong) {
4418                      SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4419                   }
4420                   SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4421                   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4422                      SiS_GenericDelay(SiS_Pr, 0x500);
4423                   }
4424                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4425                }
4426             }
4427
4428             SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4429             SiS_DisplayOn(SiS_Pr);
4430             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4431
4432          }
4433
4434          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4435             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4436          }
4437
4438 #endif /* SIS315H */
4439
4440       }
4441
4442     } else {    /* ============  For 301 ================ */
4443
4444        if(HwInfo->jChipType < SIS_315H) {
4445           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4446              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4447              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4448           }
4449        }
4450
4451        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4452        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4453           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4454           if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4455        }
4456        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4457
4458        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4459
4460        if(HwInfo->jChipType >= SIS_315H) {
4461           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4462           if(!(temp & 0x80)) {
4463              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4464           }
4465        }
4466
4467        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4468
4469        SiS_VBLongWait(SiS_Pr);
4470        SiS_DisplayOn(SiS_Pr);
4471        if(HwInfo->jChipType >= SIS_315H) {
4472           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4473        }
4474        SiS_VBLongWait(SiS_Pr);
4475
4476        if(HwInfo->jChipType < SIS_315H) {
4477           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4478              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4479              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4480           }
4481        }
4482
4483     }
4484
4485   } else {   /* =================== For LVDS ================== */
4486
4487     if(HwInfo->jChipType < SIS_315H) {
4488
4489 #ifdef SIS300    /* 300 series */
4490
4491        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4492           if(HwInfo->jChipType == SIS_730) {
4493              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4494              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4495              SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4496           }
4497           SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4498           if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4499              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4500           }
4501        }
4502
4503        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4504        SiS_DisplayOn(SiS_Pr);
4505        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4506        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4507        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4508           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4509        } else {
4510           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4511        }
4512
4513        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4514           if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4515              SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4516              SiS_SetCH700x(SiS_Pr,0x0B0E);
4517           }
4518        }
4519
4520        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4521           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4522              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4523                 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4524                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4525                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4526                 }
4527                 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4528                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4529              }
4530           }
4531        }
4532
4533 #endif  /* SIS300 */
4534
4535     } else {
4536
4537 #ifdef SIS315H    /* 315 series */
4538
4539        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4540           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4541        }
4542
4543        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4544           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4545              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4546              SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4547           }
4548        }
4549
4550        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4551        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4552
4553        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4554
4555        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4556           temp = SiS_GetCH701x(SiS_Pr,0x66);
4557           temp &= 0x20;
4558           SiS_Chrontel701xBLOff(SiS_Pr);
4559        }
4560
4561        if(HwInfo->jChipType != SIS_550) {
4562           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4563        }
4564
4565        if(HwInfo->jChipType == SIS_740) {
4566           if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4567              if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4568                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4569              }
4570           }
4571        }
4572
4573        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4574        if(!(temp1 & 0x80)) {
4575           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4576        }
4577
4578        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4579           if(temp) {
4580              SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4581           }
4582        }
4583
4584        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4585           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4586              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4587              if(HwInfo->jChipType == SIS_550) {
4588                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4589                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4590              }
4591           }
4592        } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4593           if(HwInfo->jChipType != SIS_740) {
4594              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4595           }
4596        }
4597
4598        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4599           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4600        }
4601
4602        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4603           if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4604              SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4605           }
4606           if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4607               (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4608              SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4609           }
4610        }
4611
4612        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4613           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4614              if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4615                  (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4616                 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4617                 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4618              }
4619           }
4620        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4621           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4622              if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4623                 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4624                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4625              }
4626           }
4627        }
4628
4629 #endif  /* SIS315H */
4630
4631     } /* 310 series */
4632
4633   }  /* LVDS */
4634
4635 }
4636
4637 /*********************************************/
4638 /*         SET PART 1 REGISTER GROUP         */
4639 /*********************************************/
4640
4641 /* Set CRT2 OFFSET / PITCH */
4642 static void
4643 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4644                   USHORT RRTI, PSIS_HW_INFO HwInfo)
4645 {
4646   USHORT offset;
4647   UCHAR temp;
4648
4649   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4650
4651   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4652
4653   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4654      (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4655      offset >>= 1;
4656   }
4657
4658   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4659   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4660   temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4661   if(offset % 8) temp++;
4662   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4663 }
4664
4665 /* Set CRT2 sync and PanelLink mode */
4666 static void
4667 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4668                 PSIS_HW_INFO HwInfo)
4669 {
4670   USHORT tempah=0,tempbl,infoflag;
4671
4672   tempbl = 0xC0;
4673
4674   if(SiS_Pr->UseCustomMode) {
4675      infoflag = SiS_Pr->CInfoFlag;
4676   } else {
4677      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4678   }
4679
4680   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                    /* LVDS */
4681
4682      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4683         tempah = 0;
4684      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4685         tempah = SiS_Pr->SiS_LCDInfo;
4686      } else tempah = infoflag >> 8;
4687      tempah &= 0xC0;
4688      tempah |= 0x20;
4689      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4690      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4691         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4692            (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4693            tempah |= 0xf0;
4694         }
4695         if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4696             (SiS_Pr->SiS_IF_DEF_DSTN) ||
4697             (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4698             (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4699            tempah |= 0x30;
4700         }
4701      }
4702      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4703         if(HwInfo->jChipType >= SIS_315H) {
4704            tempah >>= 3;
4705            tempah &= 0x18;
4706            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4707            /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4708         } else {
4709            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4710         }
4711      } else {
4712         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4713      }
4714
4715   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4716
4717      if(HwInfo->jChipType < SIS_315H) {
4718
4719 #ifdef SIS300  /* ---- 300 series --- */
4720
4721         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {                   /* 630 - 301B(-DH) */
4722
4723            tempah = infoflag >> 8;
4724            tempbl = 0;
4725            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4726               if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4727                  tempah = SiS_Pr->SiS_LCDInfo;
4728                  tempbl = (tempah >> 6) & 0x03;
4729               }
4730            }
4731            tempah &= 0xC0;
4732            tempah |= 0x20;
4733            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4734            tempah |= 0xc0;
4735            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4736            if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4737               SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4738            }
4739
4740         } else {                                                        /* 630 - 301 */
4741
4742            tempah = infoflag >> 8;
4743            tempah &= 0xC0;
4744            tempah |= 0x20;
4745            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4746            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4747
4748         }
4749
4750 #endif /* SIS300 */
4751
4752      } else {
4753
4754 #ifdef SIS315H  /* ------- 315 series ------ */
4755
4756         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                     /* 315 - LVDS */
4757
4758            tempbl = 0;
4759            if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4760               (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4761               tempah = infoflag >> 8;
4762               if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4763                 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4764               }
4765            } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
4766                      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4767               tempah = infoflag >> 8;
4768               tempbl = 0x03;
4769            } else {
4770               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4771               tempbl = (tempah >> 6) & 0x03;
4772               tempbl |= 0x08;
4773               if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4774            }
4775            tempah &= 0xC0;
4776            tempah |= 0x20;
4777            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4778            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
4779            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4780            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4781               if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4782                  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4783               }
4784            }
4785
4786         } else {                                                        /* 315 - TMDS */
4787
4788            tempah = tempbl = infoflag >> 8;
4789            if(!SiS_Pr->UseCustomMode) {
4790               tempbl = 0;
4791               if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4792                  if(ModeNo <= 0x13) {
4793                     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4794                  }
4795               }
4796               if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4797                  if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4798                     tempah = SiS_Pr->SiS_LCDInfo;
4799                     tempbl = (tempah >> 6) & 0x03;
4800                  }
4801               }
4802            }
4803            tempah &= 0xC0;
4804            tempah |= 0x20;
4805            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4806            if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4807               /* Imitate BIOS bug */
4808               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
4809            }
4810            if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4811               tempah >>= 3;
4812               tempah &= 0x18;
4813               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4814            } else {
4815               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4816               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4817                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4818                     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4819                  }
4820               }
4821            }
4822
4823         }
4824 #endif  /* SIS315H */
4825       }
4826    }
4827 }
4828
4829 /* Set CRT2 FIFO on 300/630/730 */
4830 #ifdef SIS300
4831 static void
4832 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4833                     PSIS_HW_INFO HwInfo)
4834 {
4835   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
4836   USHORT temp,index;
4837   USHORT modeidindex,refreshratetableindex;
4838   USHORT VCLK=0,MCLK,colorth=0,data2=0;
4839   USHORT tempal, tempah, tempbx, tempcl, tempax;
4840   USHORT CRT1ModeNo,CRT2ModeNo;
4841   USHORT SelectRate_backup;
4842   ULONG  data,eax;
4843   const UCHAR  LatencyFactor[] = {
4844         97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
4845         00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
4846         97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
4847         00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
4848         80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
4849         00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
4850         86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
4851         00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
4852   };
4853   const UCHAR  LatencyFactor730[] = {
4854          69, 63, 61,
4855          86, 79, 77,
4856         103, 96, 94,
4857         120,113,111,
4858         137,130,128,    /* <-- last entry, data below */
4859         137,130,128,    /* to avoid using illegal values */
4860         137,130,128,
4861         137,130,128,
4862         137,130,128,
4863         137,130,128,
4864         137,130,128,
4865         137,130,128,
4866         137,130,128,
4867         137,130,128,
4868         137,130,128,
4869         137,130,128,
4870   };
4871   const UCHAR ThLowB[]   = {
4872         81, 4, 72, 6, 88, 8,120,12,
4873         55, 4, 54, 6, 66, 8, 90,12,
4874         42, 4, 45, 6, 55, 8, 75,12
4875   };
4876   const UCHAR ThTiming[] = {
4877         1, 2, 2, 3, 0, 1, 1, 2
4878   };
4879
4880   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
4881
4882   if(!SiS_Pr->CRT1UsesCustomMode) {
4883
4884      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
4885      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
4886      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
4887      SiS_Pr->SiS_SelectCRT2Rate = 0;
4888      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
4889
4890      if(CRT1ModeNo >= 0x13) {
4891         index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
4892         index &= 0x3F;
4893         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK */
4894
4895         colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex);     /* Get colordepth */
4896         colorth >>= 1;
4897         if(!colorth) colorth++;
4898      }
4899
4900   } else {
4901
4902      CRT1ModeNo = 0xfe;
4903      VCLK = SiS_Pr->CSRClock_CRT1;                                      /* Get VCLK */
4904      data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
4905      switch(data2) {                                                    /* Get color depth */
4906         case 0 : colorth = 1; break;
4907         case 1 : colorth = 1; break;
4908         case 2 : colorth = 2; break;
4909         case 3 : colorth = 2; break;
4910         case 4 : colorth = 3; break;
4911         case 5 : colorth = 4; break;
4912         default: colorth = 2;
4913      }
4914
4915   }
4916
4917   if(CRT1ModeNo >= 0x13) {
4918     if(HwInfo->jChipType == SIS_300) {
4919        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
4920     } else {
4921        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
4922     }
4923     index &= 0x07;
4924     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;                         /* Get MCLK */
4925
4926     data2 = (colorth * VCLK) / MCLK;
4927
4928     temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4929     temp = ((temp & 0x00FF) >> 6) << 1;
4930     if(temp == 0) temp = 1;
4931     temp <<= 2;
4932     temp &= 0xff;
4933
4934     data2 = temp - data2;
4935
4936     if((28 * 16) % data2) {
4937         data2 = (28 * 16) / data2;
4938         data2++;
4939     } else {
4940         data2 = (28 * 16) / data2;
4941     }
4942
4943     if(HwInfo->jChipType == SIS_300) {
4944
4945         tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4946         tempah &= 0x62;
4947         tempah >>= 1;
4948         tempal = tempah;
4949         tempah >>= 3;
4950         tempal |= tempah;
4951         tempal &= 0x07;
4952         tempcl = ThTiming[tempal];
4953         tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
4954         tempbx >>= 6;
4955         tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4956         tempah >>= 4;
4957         tempah &= 0x0c;
4958         tempbx |= tempah;
4959         tempbx <<= 1;
4960         tempal = ThLowB[tempbx + 1];
4961         tempal *= tempcl;
4962         tempal += ThLowB[tempbx];
4963         data = tempal;
4964
4965     } else if(HwInfo->jChipType == SIS_730) {
4966
4967 #ifndef LINUX_XF86
4968        SiS_SetRegLong(0xcf8,0x80000050);
4969        eax = SiS_GetRegLong(0xcfc);
4970 #else
4971        eax = pciReadLong(0x00000000, 0x50);
4972 #endif
4973        tempal = (USHORT)(eax >> 8);
4974        tempal &= 0x06;
4975        tempal <<= 5;
4976
4977 #ifndef LINUX_XF86
4978        SiS_SetRegLong(0xcf8,0x800000A0);
4979        eax = SiS_GetRegLong(0xcfc);
4980 #else
4981        eax = pciReadLong(0x00000000, 0xA0);
4982 #endif
4983        temp = (USHORT)(eax >> 28);
4984        temp &= 0x0F;
4985        tempal |= temp;
4986
4987        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
4988        tempbx = 0;        /* -- do it like the BIOS anyway... */
4989        tempax = tempbx;
4990        tempbx &= 0xc0;
4991        tempbx >>= 6;
4992        tempax &= 0x0f;
4993        tempax *= 3;
4994        tempbx += tempax;
4995
4996        data = LatencyFactor730[tempbx];
4997        data += 15;
4998        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4999        if(!(temp & 0x80)) data += 5;
5000
5001     } else {
5002
5003        index = 0;
5004        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5005        if(temp & 0x0080) index += 12;
5006
5007 #ifndef LINUX_XF86
5008        SiS_SetRegLong(0xcf8,0x800000A0);
5009        eax = SiS_GetRegLong(0xcfc);
5010 #else
5011        /* We use pci functions X offers. We use tag 0, because
5012         * we want to read/write to the host bridge (which is always
5013         * 00:00.0 on 630, 730 and 540), not the VGA device.
5014         */
5015        eax = pciReadLong(0x00000000, 0xA0);
5016 #endif
5017        temp = (USHORT)(eax >> 24);
5018        if(!(temp&0x01)) index += 24;
5019
5020 #ifndef LINUX_XF86
5021        SiS_SetRegLong(0xcf8,0x80000050);
5022        eax = SiS_GetRegLong(0xcfc);
5023 #else
5024        eax = pciReadLong(0x00000000, 0x50);
5025 #endif
5026        temp=(USHORT)(eax >> 24);
5027        if(temp & 0x01) index += 6;
5028
5029        temp = (temp & 0x0F) >> 1;
5030        index += temp;
5031
5032        data = LatencyFactor[index];
5033        data += 15;
5034        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5035        if(!(temp & 0x80)) data += 5;
5036     }
5037
5038     data += data2;                              /* CRT1 Request Period */
5039
5040     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5041     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5042
5043     if(!SiS_Pr->UseCustomMode) {
5044
5045        CRT2ModeNo = ModeNo;
5046        SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5047
5048        refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5049
5050        index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5051                                refreshratetableindex,HwInfo);
5052        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                /* Get VCLK  */
5053
5054        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5055           if(SiS_Pr->SiS_UseROM) {
5056              if(ROMAddr[0x220] & 0x01) {
5057                 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5058              }
5059           }
5060        }
5061
5062     } else {
5063
5064        CRT2ModeNo = 0xfe;
5065        VCLK = SiS_Pr->CSRClock;                                 /* Get VCLK */
5066
5067     }
5068
5069     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5070     colorth >>= 1;
5071     if(!colorth) colorth++;
5072
5073     data = data * VCLK * colorth;
5074     if(data % (MCLK << 4)) {
5075         data = data / (MCLK << 4);
5076         data++;
5077     } else {
5078         data = data / (MCLK << 4);
5079     }
5080
5081     if(data <= 6) data = 6;
5082     if(data > 0x14) data = 0x14;
5083
5084     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5085     if(HwInfo->jChipType == SIS_300) {
5086        if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5087        else             temp = (temp & (~0x1F)) | 0x16;
5088        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5089           temp = (temp & (~0x1F)) | 0x13;
5090        }
5091     } else {
5092        if( ( (HwInfo->jChipType == SIS_630) ||
5093              (HwInfo->jChipType == SIS_730) )  &&
5094            (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5095       {
5096           temp = (temp & (~0x1F)) | 0x1b;
5097       } else {
5098           temp = (temp & (~0x1F)) | 0x16;
5099       }
5100     }
5101     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5102
5103     if( (HwInfo->jChipType == SIS_630) &&
5104         (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5105     {
5106         if(data > 0x13) data = 0x13;
5107     }
5108     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5109
5110   } else {  /* If mode <= 0x13, we just restore everything */
5111
5112     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5113     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5114
5115   }
5116 }
5117 #endif
5118
5119 /* Set CRT2 FIFO on 315/330 series */
5120 #ifdef SIS315H
5121 static void
5122 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5123 {
5124   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5125   if( (HwInfo->jChipType == SIS_760)      &&
5126       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5127       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5128       (SiS_Pr->SiS_VGAHDE >= 1280)        &&
5129       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5130      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5131      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5132      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5133      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5134      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5135      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5136   } else {
5137      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5138   }
5139
5140 }
5141 #endif
5142
5143 static USHORT
5144 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5145 {
5146   ULONG tempax,tempbx;
5147
5148   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5149   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5150   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5151   return((USHORT)tempax);
5152 }
5153
5154 /* Set Part 1 / SiS bridge slave mode */
5155 static void
5156 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5157                   PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5158 {
5159   USHORT  push1,push2;
5160   USHORT  tempax,tempbx,tempcx,temp;
5161   USHORT  resinfo,modeflag,xres=0;
5162   unsigned char p1_7, p1_8;
5163
5164   if(ModeNo <= 0x13) {
5165      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5166      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5167   } else if(SiS_Pr->UseCustomMode) {
5168      modeflag = SiS_Pr->CModeFlag;
5169      resinfo = 0;
5170      xres = SiS_Pr->CHDisplay;
5171   } else {
5172      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5173      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5174      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5175   }
5176
5177   /* The following is only done if bridge is in slave mode: */
5178
5179   if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5180      if(xres >= 1600) {
5181         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5182      }
5183   }
5184
5185   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
5186
5187   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
5188
5189   if(modeflag & Charx8Dot) tempcx = 0x08;
5190   else                     tempcx = 0x09;
5191
5192   tempax = SiS_Pr->SiS_VGAHDE;                                  /* 0x04 Horizontal Display End */
5193   if(modeflag & HalfDCLK) tempax >>= 1;
5194   tempax = ((tempax / tempcx) - 1) & 0xff;
5195   tempbx = tempax;
5196
5197   temp = tempax;
5198   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5199
5200   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5201      if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5202         temp += 2;
5203      }
5204   }
5205   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5206      if(resinfo == SIS_RI_800x600) temp -= 2;
5207   }
5208   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
5209
5210   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
5211
5212   tempax = 0xFFFF;
5213   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5214   if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5215   if(modeflag & HalfDCLK)         tempax >>= 1;
5216   tempax = (tempax / tempcx) - 5;
5217   tempcx = tempax;
5218
5219   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5220      temp = tempcx - 1;
5221      if(!(modeflag & HalfDCLK)) {
5222         temp -= 6;
5223         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5224            temp -= 2;
5225            if(ModeNo > 0x13) temp -= 10;
5226         }
5227      }
5228   } else {
5229      tempcx = (tempcx + tempbx) >> 1;
5230      temp = (tempcx & 0x00FF) + 2;
5231      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5232         temp--;
5233         if(!(modeflag & HalfDCLK)) {
5234            if((modeflag & Charx8Dot)) {
5235               temp += 4;
5236               if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5237               if(HwInfo->jChipType >= SIS_315H) {
5238                  if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5239               }
5240            }
5241         }
5242      } else {
5243         if(!(modeflag & HalfDCLK)) {
5244            temp -= 4;
5245            if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5246               (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5247               if(SiS_Pr->SiS_VGAHDE >= 800) {
5248                  temp -= 7;
5249                  if(HwInfo->jChipType < SIS_315H) {
5250                     if(SiS_Pr->SiS_ModeType == ModeEGA) {
5251                        if(SiS_Pr->SiS_VGAVDE == 1024) {
5252                           temp += 15;
5253                           if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5254                              temp += 7;
5255                        }
5256                     }
5257                  }
5258                  if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5259                     if(SiS_Pr->SiS_VGAHDE >= 1280) {
5260                        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5261                     }
5262                  }
5263               }
5264            }
5265         }
5266      }
5267   }
5268
5269   p1_7 = temp;
5270   p1_8 = 0x00;
5271
5272   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5273      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5274         if(ModeNo <= 0x01) {
5275            p1_7 = 0x2a;
5276            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5277            else                                 p1_8 = 0x41;
5278         } else if(SiS_Pr->SiS_ModeType == ModeText) {
5279            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5280            else                                 p1_7 = 0x55;
5281            p1_8 = 0x00;
5282         } else if(ModeNo <= 0x13) {
5283            if(modeflag & HalfDCLK) {
5284               if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5285                  p1_7 = 0x30;
5286                  p1_8 = 0x03;
5287               } else {
5288                  p1_7 = 0x2f;
5289                  p1_8 = 0x02;
5290               }
5291            } else {
5292               p1_7 = 0x5b;
5293               p1_8 = 0x03;
5294            }
5295         } else if( ((HwInfo->jChipType >= SIS_315H) &&
5296                     ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5297                    ((HwInfo->jChipType < SIS_315H) &&
5298                     (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5299            if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5300               p1_7 = 0x30,
5301               p1_8 = 0x03;
5302            } else {
5303               p1_7 = 0x2f;
5304               p1_8 = 0x03;
5305            }
5306         }
5307      }
5308   }
5309
5310   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5311      if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5312         p1_7 = 0x63;
5313         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5314      }
5315      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5316         if(!(modeflag & HalfDCLK)) {
5317            p1_7 = 0xb2;
5318            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5319               p1_7 = 0xab;
5320            }
5321         }
5322      } else {
5323         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5324            if(modeflag & HalfDCLK) p1_7 = 0x30;
5325         }
5326      }
5327   }
5328
5329   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7);                  /* 0x07 Horizontal Retrace Start */
5330   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8);                  /* 0x08 Horizontal Retrace End   */
5331
5332   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                  /* 0x18 SR08 (FIFO Threshold?)   */
5333
5334   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5335
5336   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                  /* 0x09 Set Max VT    */
5337
5338   tempcx = 0x121;
5339   tempbx = SiS_Pr->SiS_VGAVDE;                                  /* 0x0E Vertical Display End */
5340   if     (tempbx == 357) tempbx = 350;
5341   else if(tempbx == 360) tempbx = 350;
5342   else if(tempbx == 375) tempbx = 350;
5343   else if(tempbx == 405) tempbx = 400;
5344   else if(tempbx == 420) tempbx = 400;
5345   else if(tempbx == 525) tempbx = 480;
5346   push2 = tempbx;
5347   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5348      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5349         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5350            if     (tempbx == 350) tempbx += 5;
5351            else if(tempbx == 480) tempbx += 5;
5352         }
5353      }
5354   }
5355   tempbx -= 2;
5356   temp = tempbx & 0x00FF;
5357   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);                  /* 0x10 vertical Blank Start */
5358
5359   tempbx = push2;
5360   tempbx--;
5361   temp = tempbx & 0x00FF;
5362 #if 0
5363   /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5364   if(xxx()) {
5365       if(temp == 0xdf) temp = 0xda;
5366   }
5367 #endif
5368   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5369
5370   temp = 0;
5371   if(modeflag & DoubleScanMode) temp |= 0x80;
5372   if(HwInfo->jChipType >= SIS_661) {
5373      if(tempbx & 0x0200)        temp |= 0x20;
5374      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5375      if(tempbx & 0x0100)  tempcx |= 0x000a;
5376      if(tempbx & 0x0400)  tempcx |= 0x1200;
5377   } else {
5378      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5379      if(tempbx & 0x0100)  tempcx |= 0x0002;
5380      if(tempbx & 0x0400)  tempcx |= 0x0600;
5381   }
5382
5383   if(tempbx & 0x0200)  tempcx |= 0x0040;
5384
5385   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                  /* 0x11 Vertical Blank End */
5386
5387   tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5388
5389   if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5390      if(resinfo != SIS_RI_1280x1024) {
5391         tempbx += (tempax << 1);
5392      }
5393   } else if(HwInfo->jChipType >= SIS_315H) {
5394      if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5395         tempbx += (tempax << 1);
5396      }
5397   }
5398
5399   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5400      tempbx -= 10;
5401   } else {
5402      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5403         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5404            tempbx += 40;
5405            if(HwInfo->jChipType >= SIS_315H) {
5406               if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5407            }
5408         }
5409      }
5410   }
5411   tempax >>= 2;
5412   tempax++;
5413   tempax += tempbx;
5414   push1 = tempax;
5415   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5416      if(tempbx <= 513)  {
5417         if(tempax >= 513) tempbx = 513;
5418      }
5419   }
5420   temp = tempbx & 0x00FF;
5421   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                  /* 0x0C Vertical Retrace Start */
5422
5423   tempbx--;
5424   temp = tempbx & 0x00FF;
5425   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5426
5427   if(tempbx & 0x0100) tempcx |= 0x0008;
5428
5429   if(tempbx & 0x0200) {
5430      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5431   }
5432   tempbx++;
5433
5434   if(tempbx & 0x0100) tempcx |= 0x0004;
5435   if(tempbx & 0x0200) tempcx |= 0x0080;
5436   if(tempbx & 0x0400) {
5437      if(HwInfo->jChipType >= SIS_661)        tempcx |= 0x0800;
5438      else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5439      else                                    tempcx |= 0x0C00;
5440   }
5441
5442   tempbx = push1;
5443   temp = tempbx & 0x000F;
5444   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                  /* 0x0D vertical Retrace End */
5445
5446   if(tempbx & 0x0010) tempcx |= 0x2000;
5447
5448   temp = tempcx & 0x00FF;
5449   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* 0x0A CR07 */
5450
5451   temp = (tempcx & 0xFF00) >> 8;
5452   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                  /* 0x17 SR0A */
5453
5454   tempax = modeflag;
5455   temp = (tempax & 0xFF00) >> 8;
5456   temp = (temp >> 1) & 0x09;
5457   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01;           /* Always 8 dotclock */
5458   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* 0x16 SR01 */
5459
5460   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                  /* 0x0F CR14 */
5461
5462   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                  /* 0x12 CR17 */
5463
5464   temp = 0x00;
5465   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5466      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5467         temp = 0x80;
5468      }
5469   }
5470   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* 0x1A SR0E */
5471
5472   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5473   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5474 }
5475
5476 /* Setup panel link
5477  * This is used for LVDS, LCDA and Chrontel TV output
5478  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5479  */
5480 static void
5481 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5482                    PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5483 {
5484   USHORT modeflag,resinfo;
5485   USHORT push2,tempax,tempbx,tempcx,temp;
5486   ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5487   BOOLEAN islvds = FALSE, issis  = FALSE, chkdclkfirst = FALSE;
5488 #ifdef SIS300
5489   USHORT crt2crtc;
5490 #endif
5491 #ifdef SIS315H
5492   USHORT pushcx;
5493 #endif
5494
5495   if(ModeNo <= 0x13) {
5496      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5497      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5498 #ifdef SIS300
5499      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5500 #endif
5501   } else if(SiS_Pr->UseCustomMode) {
5502      modeflag = SiS_Pr->CModeFlag;
5503      resinfo = 0;
5504 #ifdef SIS300
5505      crt2crtc = 0;
5506 #endif
5507   } else {
5508      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5509      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5510 #ifdef SIS300
5511      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5512 #endif
5513   }
5514
5515   /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
5516   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
5517      ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
5518      islvds = TRUE;
5519   }
5520
5521   /* is really sis if sis bridge, but not 301B-DH */
5522   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5523      issis = TRUE;
5524   }
5525
5526   if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5527      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5528         chkdclkfirst = TRUE;
5529      }
5530   }
5531
5532 #ifdef SIS315H
5533   if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5534      if(IS_SIS330) {
5535         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5536      } else if(IS_SIS740) {
5537         if(islvds) {
5538            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5539            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5540         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5541            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5542         }
5543      } else {
5544         if(islvds) {
5545            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5546            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5547         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5548            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5549            if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5550               if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5551                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5552                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5553               }
5554            }
5555         }
5556      }
5557   }
5558 #endif
5559
5560   /* Horizontal */
5561
5562   tempax = SiS_Pr->SiS_LCDHDES;
5563   if(islvds) {
5564      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5565         if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5566            if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5567               (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5568               tempax -= 8;
5569            }
5570         }
5571      }
5572   }
5573
5574   temp = (tempax & 0x0007);
5575   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* BPLHDESKEW[2:0]   */
5576   temp = (tempax >> 3) & 0x00FF;
5577   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* BPLHDESKEW[10:3]  */
5578
5579   tempbx = SiS_Pr->SiS_HDE;
5580   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5581      if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5582         (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5583         tempbx >>= 1;
5584      }
5585      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5586         tempbx = SiS_Pr->PanelXRes;
5587      }
5588   }
5589
5590   tempax += tempbx;
5591   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5592
5593   temp = tempax;
5594   if(temp & 0x07) temp += 8;
5595   temp >>= 3;
5596   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                  /* BPLHDEE  */
5597
5598   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5599
5600   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5601      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5602         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5603      }
5604   }
5605
5606   tempcx += tempax;
5607   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5608
5609   temp = (tempcx >> 3) & 0x00FF;
5610   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5611      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5612         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5613            switch(ModeNo) {
5614            case 0x04:
5615            case 0x05:
5616            case 0x0d: temp = 0x56; break;
5617            case 0x10: temp = 0x60; break;
5618            case 0x13: temp = 0x5f; break;
5619            case 0x40:
5620            case 0x41:
5621            case 0x4f:
5622            case 0x43:
5623            case 0x44:
5624            case 0x62:
5625            case 0x56:
5626            case 0x53:
5627            case 0x5d:
5628            case 0x5e: temp = 0x54; break;
5629            }
5630         }
5631      }
5632   }
5633   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                  /* BPLHRS */
5634
5635   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5636      temp += 2;
5637      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5638         temp += 8;
5639         if(SiS_Pr->PanelHRE != 999) {
5640            temp = tempcx + SiS_Pr->PanelHRE;
5641            if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5642            temp >>= 3;
5643         }
5644      }
5645   } else {
5646      temp += 10;
5647   }
5648
5649   temp &= 0x1F;
5650   temp |= ((tempcx & 0x07) << 5);
5651 #if 0
5652   if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;                      /* WRONG? BIOS loads cl, not ah */
5653 #endif
5654   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                  /* BPLHRE */
5655
5656   /* Vertical */
5657
5658   tempax = SiS_Pr->SiS_VGAVDE;
5659   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5660      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5661         tempax = SiS_Pr->PanelYRes;
5662      }
5663   }
5664
5665   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5666   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5667
5668   push2 = tempbx;
5669
5670   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5671   if(HwInfo->jChipType < SIS_315H) {
5672      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5673         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5674            tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5675         }
5676      }
5677   }
5678   if(islvds) tempcx >>= 1;
5679   else       tempcx >>= 2;
5680
5681   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5682       (!(SiS_Pr->SiS_LCDInfo & LCDPass11))                  &&
5683       (SiS_Pr->PanelVRS != 999) ) {
5684      tempcx = SiS_Pr->PanelVRS;
5685      tempbx += tempcx;
5686      if(issis) tempbx++;
5687   } else {
5688      tempbx += tempcx;
5689      if(HwInfo->jChipType < SIS_315H) tempbx++;
5690      else if(issis)                   tempbx++;
5691   }
5692
5693   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;        /* BPLVRS  */
5694
5695   temp = tempbx & 0x00FF;
5696   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5697      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5698         if(ModeNo == 0x10) temp = 0xa9;
5699      }
5700   }
5701   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5702
5703   tempcx >>= 3;
5704   tempcx++;
5705
5706   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5707      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5708         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5709      }
5710   }
5711
5712   tempcx += tempbx;
5713   temp = tempcx & 0x000F;
5714   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);        /* BPLVRE  */
5715
5716   temp = ((tempbx >> 8) & 0x07) << 3;
5717   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5718      if(SiS_Pr->SiS_HDE != 640) {
5719         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5720      }
5721   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5722   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5723   tempbx = 0x87;
5724   if((HwInfo->jChipType >= SIS_315H) ||
5725      (HwInfo->jChipRevision >= 0x30)) {
5726      tempbx = 0x07;
5727      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5728         if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5729      }
5730      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5731      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5732         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5733            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5734         } else {
5735            if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5736         }
5737      }
5738   }
5739   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5740
5741   tempbx = push2;                                               /* BPLVDEE */
5742
5743   tempcx = SiS_Pr->SiS_LCDVDES;                                 /* BPLVDES */
5744
5745   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5746      switch(SiS_Pr->SiS_LCDResInfo) {
5747      case Panel_640x480:
5748         tempbx = SiS_Pr->SiS_VGAVDE - 1;
5749         tempcx = SiS_Pr->SiS_VGAVDE;
5750         break;
5751      case Panel_800x600:
5752         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5753            if(resinfo == SIS_RI_800x600) tempcx++;
5754         }
5755         break;
5756      case Panel_1024x600:
5757         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5758            if(resinfo == SIS_RI_1024x600) tempcx++;
5759            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5760               if(resinfo == SIS_RI_800x600) tempcx++;
5761            }
5762         }
5763         break;
5764      case Panel_1024x768:
5765         if(HwInfo->jChipType < SIS_315H) {
5766            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5767               if(resinfo == SIS_RI_1024x768) tempcx++;
5768            }
5769         }
5770         break;
5771      }
5772   }
5773
5774   temp = ((tempbx >> 8) & 0x07) << 3;
5775   temp = temp | ((tempcx >> 8) & 0x07);
5776   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5777   /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++;  */
5778   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5779   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5780
5781   /* Vertical scaling */
5782
5783   if(HwInfo->jChipType < SIS_315H) {
5784
5785 #ifdef SIS300      /* 300 series */
5786      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5787      temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5788      tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5789      if(temp) tempeax++;
5790
5791      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5792
5793      temp = (USHORT)(tempeax & 0x00FF);
5794      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);       /* BPLVCFACT */
5795      tempvcfact = temp;
5796 #endif /* SIS300 */
5797
5798   } else {
5799
5800 #ifdef SIS315H  /* 315 series */
5801      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5802      tempebx = SiS_Pr->SiS_VDE;
5803      temp = (tempeax % tempebx);
5804      tempeax = tempeax / tempebx;
5805      if(temp) tempeax++;
5806      tempvcfact = tempeax;
5807
5808      temp = (USHORT)(tempeax & 0x00FF);
5809      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5810      temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5811      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5812      temp = (USHORT)((tempeax & 0x00030000) >> 16);
5813      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5814      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5815
5816      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5817         temp = (USHORT)(tempeax & 0x00FF);
5818         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5819         temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5820         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5821         temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5822         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5823         temp = 0;
5824         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5825         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5826      }
5827 #endif
5828
5829   }
5830
5831   /* Horizontal scaling */
5832
5833   tempeax = SiS_Pr->SiS_VGAHDE;         /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5834   if(chkdclkfirst) {
5835      if(modeflag & HalfDCLK) tempeax >>= 1;
5836   }
5837   tempebx = tempeax << 16;
5838   if(SiS_Pr->SiS_HDE == tempeax) {
5839      tempecx = 0xFFFF;
5840   } else {
5841      tempecx = tempebx / SiS_Pr->SiS_HDE;
5842      if(HwInfo->jChipType >= SIS_315H) {
5843         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5844      }
5845   }
5846
5847   if(HwInfo->jChipType >= SIS_315H) {
5848      tempeax = (tempebx / tempecx) - 1;
5849   } else {
5850      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5851   }
5852   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5853   temp = (USHORT)(tempecx & 0x00FF);
5854   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5855
5856   if(HwInfo->jChipType >= SIS_315H) {
5857      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5858      tempbx = (USHORT)(tempeax & 0xFFFF);
5859   } else {
5860      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5861      tempbx = tempvcfact & 0x3f;
5862      if(tempbx == 0) tempbx = 64;
5863      tempeax /= tempbx;
5864      tempbx = (USHORT)(tempeax & 0xFFFF);
5865   }
5866   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5867   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5868      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5869      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
5870   }
5871
5872   temp = ((tempbx >> 8) & 0x07) << 3;
5873   temp = temp | ((tempecx >> 8) & 0x07);
5874   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5875   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5876
5877   tempecx >>= 16;                                               /* BPLHCFACT  */
5878   if(!chkdclkfirst) {
5879      if(modeflag & HalfDCLK) tempecx >>= 1;
5880   }
5881   temp = (USHORT)((tempecx & 0xFF00) >> 8);
5882   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5883   temp = (USHORT)(tempecx & 0x00FF);
5884   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5885
5886 #ifdef SIS315H
5887   if(HwInfo->jChipType >= SIS_315H) {
5888      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5889         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
5890            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5891         }
5892      } else {
5893         if(islvds) {
5894            if(HwInfo->jChipType == SIS_740) {
5895               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5896            } else {
5897               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5898            }
5899         }
5900      }
5901   }
5902 #endif
5903
5904 #ifdef SIS300
5905   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5906      int i;
5907      UCHAR TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
5908      UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5909      UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5910
5911      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5912      for(i=0; i<5; i++) {
5913         SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
5914      }
5915      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5916         if(ModeNo == 0x13) {
5917            for(i=0; i<4; i++) {
5918               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5919            }
5920         } else if(ModeNo == 0x10) {
5921            for(i=0; i<4; i++) {
5922               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5923               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5924            }
5925         }
5926      }
5927      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5928   }
5929 #endif
5930
5931 #ifdef SIS315H
5932   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5933      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5934      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5935      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5936      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5937      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5938      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5939      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5940      tempax = SiS_Pr->SiS_HDE;                                  /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5941      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5942         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5943      tempax += 64;
5944      temp = tempax & 0x00FF;
5945      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
5946      temp = ((tempax & 0xFF00) >> 8) << 3;
5947      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5948      tempax += 32;                                              /* Blpe=lBlps+32 */
5949      temp = tempax & 0x00FF;
5950      if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
5951      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
5952      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);               /* Bflml=0 */
5953      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
5954
5955      tempax = SiS_Pr->SiS_VDE;
5956      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5957         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5958      tempax >>= 1;
5959      temp = tempax & 0x00FF;
5960      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
5961      temp = ((tempax & 0xFF00) >> 8) << 3;
5962      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5963
5964      tempeax = SiS_Pr->SiS_HDE;
5965      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5966         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
5967      tempeax <<= 2;                                             /* BDxFIFOSTOP = (HDE*4)/128 */
5968      tempebx = 128;
5969      temp = (USHORT)(tempeax % tempebx);
5970      tempeax = tempeax / tempebx;
5971      if(temp) tempeax++;
5972      temp = (USHORT)(tempeax & 0x003F);
5973      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
5974      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);               /* BDxWadrst0 */
5975      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5976      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5977      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
5978
5979      tempax = SiS_Pr->SiS_HDE;
5980      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5981         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5982      tempax >>= 4;                                              /* BDxWadroff = HDE*4/8/8 */
5983      pushcx = tempax;
5984      temp = tempax & 0x00FF;
5985      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5986      temp = ((tempax & 0xFF00) >> 8) << 3;
5987      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5988
5989      tempax = SiS_Pr->SiS_VDE;                                  /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5990      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5991         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5992      tempeax = (tempax * pushcx);
5993      tempebx = 0x00100000 + tempeax;
5994      temp = (USHORT)tempebx & 0x000000FF;
5995      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5996      temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
5997      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5998      temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
5999      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6000      temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6001      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6002
6003      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6004      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6005      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6006      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6007      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6008
6009      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6010         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6011         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6012         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6013         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6014         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6015         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6016         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6017         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6018         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6019         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6020         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6021         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6022         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6023         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6024         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6025         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6026         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6027         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6028         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6029         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6030      }
6031   }
6032 #endif  /* SIS315H */
6033 }
6034
6035 /* Set Part 1 */
6036 static void
6037 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6038               PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6039 {
6040 #if defined(SIS300) || defined(SIS315H)
6041   UCHAR   *ROMAddr = HwInfo->pjVirtualRomBase;
6042 #endif
6043   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6044   USHORT  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6045 #ifdef SIS315H
6046   USHORT  tempbl=0;
6047 #endif
6048
6049   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6050      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6051      return;
6052   }
6053
6054   if(ModeNo <= 0x13) {
6055      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6056   } else if(SiS_Pr->UseCustomMode) {
6057      modeflag = SiS_Pr->CModeFlag;
6058   } else {
6059      CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6060      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6061      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6062   }
6063
6064   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6065
6066   if( ! ((HwInfo->jChipType >= SIS_315H) &&
6067          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6068          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6069
6070      if(HwInfo->jChipType < SIS_315H ) {
6071 #ifdef SIS300
6072         SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6073 #endif
6074      } else {
6075 #ifdef SIS315H
6076         SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6077 #endif
6078      }
6079
6080      /* 1. Horizontal setup */
6081
6082      if(HwInfo->jChipType < SIS_315H ) {
6083
6084 #ifdef SIS300   /* ------------- 300 series --------------*/
6085
6086         temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
6087         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6088
6089         temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6090         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6091
6092         temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6093         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6094
6095         pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6096         tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6097         tempbx = pushbx + tempcx;
6098         tempcx <<= 1;
6099         tempcx += tempbx;
6100
6101         bridgeadd = 12;
6102
6103 #endif /* SIS300 */
6104
6105      } else {
6106
6107 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
6108
6109         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HT 0x08,0x09 */
6110         if(modeflag & HalfDCLK) {
6111            if(SiS_Pr->SiS_VBType & VB_SISVB) {
6112               tempcx >>= 1;
6113            } else {
6114               tempax = SiS_Pr->SiS_VGAHDE >> 1;
6115               tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6116               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6117                  tempcx = SiS_Pr->SiS_HT - tempax;
6118               }
6119            }
6120         }
6121         tempcx--;
6122         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6123         temp = (tempcx >> 4) & 0xF0;
6124         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6125
6126         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HDEE 0x0A,0x0C */
6127         tempbx = SiS_Pr->SiS_VGAHDE;
6128         tempcx -= tempbx;
6129         tempcx >>= 2;
6130         if(modeflag & HalfDCLK) {
6131            tempbx >>= 1;
6132            tempcx >>= 1;
6133         }
6134         tempbx += 16;
6135
6136         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6137
6138         pushbx = tempbx;
6139         tempcx >>= 1;
6140         tempbx += tempcx;
6141         tempcx += tempbx;
6142
6143         bridgeadd = 16;
6144
6145         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6146            if(HwInfo->jChipType >= SIS_661) {
6147               if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6148                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6149                  if(resinfo == SIS_RI_1280x1024) {
6150                     tempcx = (tempcx & 0xff00) | 0x30;
6151                  } else if(resinfo == SIS_RI_1600x1200) {
6152                     tempcx = (tempcx & 0xff00) | 0xff;
6153                  }
6154               }
6155            }
6156         }
6157
6158 #endif  /* SIS315H */
6159
6160      }  /* 315/330 series */
6161
6162      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6163
6164         if(SiS_Pr->UseCustomMode) {
6165            tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6166            tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6167            tempax = SiS_Pr->SiS_VGAHT;
6168            if(modeflag & HalfDCLK) tempax >>= 1;
6169            tempax--;
6170            if(tempcx > tempax) tempcx = tempax;
6171         }
6172
6173         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6174            unsigned char cr4, cr14, cr5, cr15;
6175            if(SiS_Pr->UseCustomMode) {
6176               cr4  = SiS_Pr->CCRT1CRTC[4];
6177               cr14 = SiS_Pr->CCRT1CRTC[14];
6178               cr5  = SiS_Pr->CCRT1CRTC[5];
6179               cr15 = SiS_Pr->CCRT1CRTC[15];
6180            } else {
6181               cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6182               cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6183               cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6184               cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6185            }
6186            tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                /* (VGAHRS-3)*8 */
6187            tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6188            tempcx &= 0x00FF;
6189            tempcx |= (tempbx & 0xFF00);
6190            tempbx += bridgeadd;
6191            tempcx += bridgeadd;
6192            tempax = SiS_Pr->SiS_VGAHT;
6193            if(modeflag & HalfDCLK) tempax >>= 1;
6194            tempax--;
6195            if(tempcx > tempax) tempcx = tempax;
6196         }
6197
6198         if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6199            tempbx = 1040;
6200            tempcx = 1044;   /* HWCursor bug! */
6201         }
6202
6203      }
6204
6205      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);               /* CRT2 Horizontal Retrace Start */
6206
6207      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6208
6209      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6210      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                 /* Overflow */
6211
6212      /* 2. Vertical setup */
6213
6214      tempcx = SiS_Pr->SiS_VGAVT - 1;
6215      temp = tempcx & 0x00FF;
6216
6217      if(HwInfo->jChipType < SIS_661) {
6218         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6219            if(HwInfo->jChipType < SIS_315H) {
6220               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6221                  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6222                     temp--;
6223                  }
6224               }
6225            } else {
6226               temp--;
6227            }
6228         } else if(HwInfo->jChipType >= SIS_315H) {
6229            temp--;
6230         }
6231      }
6232      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6233
6234      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6235      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6236
6237      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6238      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6239
6240      if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6241         tempbx++;
6242         tempax = tempbx;
6243         tempcx++;
6244         tempcx -= tempax;
6245         tempcx >>= 2;
6246         tempbx += tempcx;
6247         if(tempcx < 4) tempcx = 4;
6248         tempcx >>= 2;
6249         tempcx += tempbx;
6250         tempcx++;
6251      } else {
6252         tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6253         tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6254      }
6255
6256      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6257         if(SiS_Pr->UseCustomMode) {
6258            tempbx = SiS_Pr->CVSyncStart;
6259            tempcx = SiS_Pr->CVSyncEnd;
6260         }
6261         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6262            unsigned char cr8, cr7, cr13;
6263            if(SiS_Pr->UseCustomMode) {
6264               cr8    = SiS_Pr->CCRT1CRTC[8];
6265               cr7    = SiS_Pr->CCRT1CRTC[7];
6266               cr13   = SiS_Pr->CCRT1CRTC[13];
6267               tempcx = SiS_Pr->CCRT1CRTC[9];
6268            } else {
6269               cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6270               cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6271               cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6272               tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6273            }
6274            tempbx = cr8;
6275            if(cr7  & 0x04) tempbx |= 0x0100;
6276            if(cr7  & 0x80) tempbx |= 0x0200;
6277            if(cr13 & 0x08) tempbx |= 0x0400;
6278         }
6279      }
6280      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6281
6282      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6283      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6284
6285      /* 3. Panel delay compensation */
6286
6287      if(HwInfo->jChipType < SIS_315H) {
6288
6289 #ifdef SIS300  /* ---------- 300 series -------------- */
6290
6291         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6292            temp = 0x20;
6293            if(HwInfo->jChipType == SIS_300) {
6294               temp = 0x10;
6295               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6296               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6297            }
6298            if(SiS_Pr->SiS_VBType & VB_SIS301) {
6299               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6300            }
6301            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6302            if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6303            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)             temp = 0x08;
6304            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6305               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
6306               else                                          temp = 0x20;
6307            }
6308            if(SiS_Pr->SiS_UseROM) {
6309               if(ROMAddr[0x220] & 0x80) {
6310                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6311                     temp = ROMAddr[0x221];
6312                  else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6313                     temp = ROMAddr[0x222];
6314                  else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6315                     temp = ROMAddr[0x223];
6316                  else
6317                     temp = ROMAddr[0x224];
6318                  temp &= 0x3c;
6319               }
6320            }
6321            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6322               if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC & 0x3c;
6323            }
6324
6325         } else {
6326            temp = 0x20;
6327            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6328               if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6329            }
6330            if(SiS_Pr->SiS_UseROM) {
6331               if(ROMAddr[0x220] & 0x80) {
6332                  temp = ROMAddr[0x220] & 0x3c;
6333               }
6334            }
6335            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6336               if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6337            }
6338         }
6339
6340         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6341
6342 #endif  /* SIS300 */
6343
6344      } else {
6345
6346 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
6347
6348         if(HwInfo->jChipType < SIS_661) {
6349
6350            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6351
6352               if(HwInfo->jChipType == SIS_740) temp = 0x03;
6353               else                             temp = 0x00;
6354
6355               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6356               tempbl = 0xF0;
6357               if(HwInfo->jChipType == SIS_650) {
6358                  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6359                     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6360                  }
6361               }
6362
6363               if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6364                  temp = 0x08;
6365                  tempbl = 0;
6366                  if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6367                     if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6368                  }
6369               }
6370
6371               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);      /* Panel Link Delay Compensation */
6372            }
6373
6374         } /* < 661 */
6375
6376         tempax = 0;
6377         if(modeflag & DoubleScanMode) tempax |= 0x80;
6378         if(modeflag & HalfDCLK)       tempax |= 0x40;
6379         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6380
6381 #endif  /* SIS315H */
6382
6383      }
6384
6385   }  /* Slavemode */
6386
6387   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6388      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6389         /* For 301BDH with LCD, we set up the Panel Link */
6390         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6391      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6392         SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6393      }
6394   } else {
6395      if(HwInfo->jChipType < SIS_315H) {
6396         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6397      } else {
6398         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6399            if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6400               SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6401            }
6402         } else {
6403            SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6404         }
6405      }
6406   }
6407 }
6408
6409 /*********************************************/
6410 /*         SET PART 2 REGISTER GROUP         */
6411 /*********************************************/
6412
6413 #ifdef SIS315H
6414 static UCHAR *
6415 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6416 {
6417    const UCHAR  *tableptr = NULL;
6418    USHORT       a, b, p = 0;
6419
6420    a = SiS_Pr->SiS_VGAHDE;
6421    b = SiS_Pr->SiS_HDE;
6422    if(tabletype) {
6423       a = SiS_Pr->SiS_VGAVDE;
6424       b = SiS_Pr->SiS_VDE;
6425    }
6426
6427    if(a < b) {
6428       tableptr = SiS_Part2CLVX_1;
6429    } else if(a == b) {
6430       tableptr = SiS_Part2CLVX_2;
6431    } else {
6432       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6433          tableptr = SiS_Part2CLVX_4;
6434       } else {
6435          tableptr = SiS_Part2CLVX_3;
6436       }
6437       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6438          if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)        tableptr = SiS_Part2CLVX_3;
6439          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   tableptr = SiS_Part2CLVX_3;
6440          else                                           tableptr = SiS_Part2CLVX_5;
6441       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6442          tableptr = SiS_Part2CLVX_6;
6443       }
6444       do {
6445          if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6446          p += 0x42;
6447       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6448       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6449    }
6450    p += 2;
6451    return((UCHAR *)&tableptr[p]);
6452 }
6453
6454 static void
6455 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6456                     USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6457 {
6458    UCHAR *tableptr;
6459    int i, j;
6460    UCHAR temp;
6461
6462    if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6463
6464    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6465    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6466       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6467    }
6468    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6469       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6470       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6471          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6472       }
6473    }
6474    temp = 0x10;
6475    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6476    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6477 }
6478
6479 static BOOLEAN
6480 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6481                     USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6482                     USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6483 {
6484
6485   if(HwInfo->jChipType < SIS_315H) return FALSE;
6486
6487   if(ModeNo <= 0x13)
6488      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6489   else
6490      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6491
6492   (*ResIndex) &= 0x3f;
6493   (*CRT2Index) = 0;
6494
6495   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6496      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6497         (*CRT2Index) = 200;
6498      }
6499   }
6500
6501   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6502      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6503         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6504      }
6505   }
6506   return(((*CRT2Index) != 0));
6507 }
6508 #endif
6509
6510 #ifdef SIS300
6511 static void
6512 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6513 {
6514    USHORT tempcx;
6515    const UCHAR atable[] = {
6516        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6517        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6518    };
6519
6520    if(!SiS_Pr->UseCustomMode) {
6521       if( ( ( (HwInfo->jChipType == SIS_630) ||
6522               (HwInfo->jChipType == SIS_730) ) &&
6523             (HwInfo->jChipRevision > 2) )  &&
6524           (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6525           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6526           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6527          if(ModeNo == 0x13) {
6528             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6529             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6530             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6531          } else {
6532             if((crt2crtc & 0x3F) == 4) {
6533                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6534                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6535                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6536                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6537                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6538             }
6539          }
6540       }
6541
6542       if(HwInfo->jChipType < SIS_315H) {
6543          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6544             crt2crtc &= 0x1f;
6545             tempcx = 0;
6546             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6547                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6548                   tempcx += 7;
6549                }
6550             }
6551             tempcx += crt2crtc;
6552             if(crt2crtc >= 4) {
6553                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6554             }
6555
6556             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6557                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6558                   if(crt2crtc == 4) {
6559                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6560                   }
6561                }
6562             }
6563             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6564             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6565          }
6566       }
6567    }
6568 }
6569
6570 /* For ECS A907. Highly preliminary. */
6571 static void
6572 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6573                     USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6574                     USHORT ModeNo)
6575 {
6576   USHORT crt2crtc, resindex;
6577   int    i,j;
6578   const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6579
6580   if(HwInfo->jChipType != SIS_300) return;
6581   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6582   if(SiS_Pr->UseCustomMode) return;
6583
6584   if(ModeNo <= 0x13) {
6585      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6586   } else {
6587      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6588   }
6589
6590   resindex = crt2crtc & 0x3F;
6591   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6592   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6593
6594   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6595   if(ModeNo > 0x13) {
6596      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6597      resindex = 4;
6598   }
6599
6600   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6601   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6602   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6603         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6604   }
6605   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6606         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6607   }
6608   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6609         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6610   }
6611   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6612   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6613 }
6614 #endif
6615
6616 static void
6617 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6618 {
6619   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6620   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6621   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6622
6623   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6624      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6625         const UCHAR specialtv[] = {
6626                 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6627                 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6628                 0x58,0xe4,0x73,0xda,0x13
6629         };
6630         int i, j;
6631         for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6632            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6633         }
6634         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6635         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6636            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6637               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6638               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6639            } else {
6640               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6641               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6642            }
6643         }
6644      }
6645   } else {
6646      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6647         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6648         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6649         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6650      } else {
6651         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6652         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6653      }
6654   }
6655 }
6656
6657 static void
6658 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6659 {
6660   USHORT temp;
6661
6662   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6663      if(SiS_Pr->SiS_VGAVDE == 525) {
6664         temp = 0xc3;
6665         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6666            temp++;
6667            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6668         }
6669         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6670         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6671      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6672         temp = 0x4d;
6673         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6674            temp++;
6675            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6676         }
6677         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6678      }
6679   }
6680
6681   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6682      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6683         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6684            SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6685            /* Not always for LV, see SetGrp2 */
6686         }
6687         temp = 1;
6688         if(ModeNo <= 0x13) temp = 3;
6689         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6690      }
6691 #if 0
6692      /* 651+301C, for 1280x768 - do I really need that? */
6693      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6694         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6695            if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6696               ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6697               SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6698               SiS_SetReg(SiS_Part2Port,0x02,0x13);
6699               SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6700               SiS_SetReg(SiS_Part2Port,0x05,0x08);
6701               SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6702               SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6703               SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6704               SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6705               SiS_SetReg(SiS_Part2Port,0x20,0x00);
6706               SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6707               SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6708               SiS_SetReg(SiS_Part2Port,0x25,0x04);
6709            }
6710         }
6711      }
6712 #endif
6713   }
6714 }
6715
6716 static void
6717 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6718               PSIS_HW_INFO HwInfo)
6719 {
6720   USHORT      i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6721   USHORT      push2, modeflag, crt2crtc, bridgeoffset;
6722   ULONG       longtemp;
6723   const       UCHAR *PhasePoint;
6724   const       UCHAR *TimingPoint;
6725 #ifdef SIS315H
6726   USHORT      resindex, CRT2Index;
6727   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6728
6729   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6730 #endif
6731
6732   if(ModeNo <= 0x13) {
6733      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6734      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6735   } else if(SiS_Pr->UseCustomMode) {
6736      modeflag = SiS_Pr->CModeFlag;
6737      crt2crtc = 0;
6738   } else {
6739      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6740      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6741   }
6742
6743   temp = 0;
6744   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6745   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6746   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6747   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6748
6749   if(!(SiS_Pr->SiS_TVMode & TVSetPAL))        temp |= 0x10;
6750
6751   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6752
6753   PhasePoint  = SiS_Pr->SiS_PALPhase;
6754   TimingPoint = SiS_Pr->SiS_PALTiming;
6755
6756   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6757
6758      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6759      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6760         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6761         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6762            TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6763 #if 0
6764            if(!(modeflag & Charx8Dot))  TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6765 #endif
6766         }
6767      }
6768
6769   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6770
6771      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      TimingPoint = &SiS_YPbPrTable[2][0];
6772      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6773      else                                         TimingPoint = &SiS_YPbPrTable[0][0];
6774
6775      PhasePoint = SiS_Pr->SiS_NTSCPhase;
6776
6777   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6778
6779      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6780          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6781            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6782         PhasePoint = SiS_Pr->SiS_PALPhase2;
6783      }
6784
6785   } else {
6786
6787      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6788      PhasePoint  = SiS_Pr->SiS_NTSCPhase;
6789      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6790         PhasePoint = SiS_Pr->SiS_PALPhase;
6791      }
6792
6793      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6794          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6795            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6796         PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6797         if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6798            PhasePoint = SiS_Pr->SiS_PALPhase2;
6799         }
6800      }
6801
6802   }
6803
6804   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6805      PhasePoint = SiS_Pr->SiS_PALMPhase;
6806      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6807          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6808            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6809         PhasePoint = SiS_Pr->SiS_PALMPhase2;
6810      }
6811   }
6812
6813   if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6814      PhasePoint = SiS_Pr->SiS_PALNPhase;
6815      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6816          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6817            (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6818         PhasePoint = SiS_Pr->SiS_PALNPhase2;
6819      }
6820   }
6821
6822   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6823      PhasePoint = SiS_Pr->SiS_SpecialPhase;
6824      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6825         PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6826      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6827         PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6828      }
6829   }
6830
6831   for(i=0x31, j=0; i<=0x34; i++, j++) {
6832      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6833   }
6834
6835   for(i=0x01, j=0; i<=0x2D; i++, j++) {
6836      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6837   }
6838   for(i=0x39; i<=0x45; i++, j++) {
6839      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6840   }
6841
6842   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6843      if(SiS_Pr->SiS_ModeType != ModeText) {
6844         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6845      }
6846   }
6847
6848   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6849
6850   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6851   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6852   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6853   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6854
6855   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)    tempax = 950;
6856   else if(SiS_Pr->SiS_TVMode & TVSetPAL)        tempax = 520;
6857   else                                          tempax = 440; /* NTSC, YPbPr 525, 750 */
6858
6859   if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
6860       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6861         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6862
6863      tempax -= SiS_Pr->SiS_VDE;
6864      tempax >>= 2;
6865      tempax &= 0x00ff;
6866
6867      temp = tempax + (USHORT)TimingPoint[0];
6868      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6869
6870      temp = tempax + (USHORT)TimingPoint[1];
6871      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6872
6873      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6874         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6875            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 19 */
6876            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 52 */
6877         } else {
6878            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6879            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6880         }
6881      }
6882
6883   }
6884
6885   tempcx = SiS_Pr->SiS_HT;
6886   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6887   tempcx--;
6888   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
6889   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6890   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6891
6892   tempcx = SiS_Pr->SiS_HT >> 1;
6893   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6894   tempcx += 7;
6895   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6896   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6897
6898   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6899   tempbx += tempcx;
6900   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6901   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6902
6903   tempbx += 8;
6904   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6905      tempbx -= 4;
6906      tempcx = tempbx;
6907   }
6908   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6909
6910   j += 2;
6911   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6912   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6913   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6914
6915   tempcx += 8;
6916   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6917   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6918
6919   tempcx = SiS_Pr->SiS_HT >> 1;
6920   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6921   j += 2;
6922   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6923   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6924
6925   tempcx -= 11;
6926   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6927      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6928   }
6929   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6930
6931   tempbx = SiS_Pr->SiS_VDE;
6932   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6933      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6934      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6935      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6936   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6937              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6938      tempbx >>= 1;
6939      if(HwInfo->jChipType >= SIS_315H) {
6940         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6941            if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6942         } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6943            if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6944               if(crt2crtc == 4) tempbx++;
6945            }
6946         }
6947      }
6948      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6949         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6950            if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6951         }
6952         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6953            if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6954         }
6955      }
6956   }
6957   tempbx -= 2;
6958   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6959
6960   temp = (tempcx >> 8) & 0x0F;
6961   temp |= ((tempbx >> 2) & 0xC0);
6962   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6963      temp |= 0x10;
6964      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6965   }
6966   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6967
6968   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6969      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6970   }
6971
6972 #if 0
6973   /* TEST qqqq */
6974   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6975      for(i=0x01, j=0; i<=0x2D; i++, j++) {
6976         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6977      }
6978      for(i=0x39; i<=0x45; i++, j++) {
6979         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6980      }
6981   }
6982 #endif
6983
6984   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6985      tempbx = SiS_Pr->SiS_VDE;
6986      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6987          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6988         tempbx >>= 1;
6989      }
6990      tempbx -= 3;
6991      temp = ((tempbx >> 3) & 0x60) | 0x18;
6992      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6993      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6994
6995      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6996         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6997      }
6998   }
6999
7000   tempbx = 0;
7001   if(!(modeflag & HalfDCLK)) {
7002      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7003         tempax = 0;
7004         tempbx |= 0x20;
7005      }
7006   }
7007
7008   tempch = tempcl = 0x01;
7009   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7010      if(SiS_Pr->SiS_VGAHDE >= 1024) {
7011         if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7012            tempch = 0x19;
7013            tempcl = 0x20;
7014            if(SiS_Pr->SiS_VGAHDE >= 1280) {
7015               tempch = 0x14;
7016               tempbx &= ~0x20;
7017            }
7018         }
7019      }
7020   }
7021
7022   if(!(tempbx & 0x20)) {
7023      if(modeflag & HalfDCLK) tempcl <<= 1;
7024      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7025      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7026      tempax = longtemp / SiS_Pr->SiS_HDE;
7027      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7028      tempbx |= ((tempax >> 8) & 0x1F);
7029      tempcx = tempax >> 13;
7030   }
7031
7032   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7033   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7034
7035   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7036
7037      tempcx &= 0x07;
7038      if(tempbx & 0x20) tempcx = 0;
7039      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7040
7041      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7042         tempbx = 0x0382;
7043         tempcx = 0x007e;
7044      } else {
7045         tempbx = 0x0369;
7046         tempcx = 0x0061;
7047      }
7048      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7049      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7050      temp = (tempcx & 0x0300) >> 6;
7051      temp |= ((tempbx >> 8) & 0x03);
7052      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7053         temp |= 0x10;
7054         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7055         else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7056      }
7057      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7058
7059      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7060      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7061
7062      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7063
7064      if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7065         temp = 0;
7066         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7067         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7068      }
7069
7070   }
7071
7072   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7073      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7074         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7075         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7076      }
7077      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7078   }
7079
7080   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7081      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7082         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7083      }
7084   }
7085
7086   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7087
7088   /* From here: Part2 LCD setup */
7089
7090   tempbx = SiS_Pr->SiS_HDE;
7091   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7092   tempbx--;                                     /* RHACTE = HDE - 1 */
7093   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7094   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7095
7096   temp = 0x01;
7097   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7098      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7099         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7100            temp = 0x02;
7101            if(HwInfo->jChipType >= SIS_315H) {
7102               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7103                  temp = 0x01;
7104               }
7105            }
7106         }
7107      }
7108   }
7109   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7110
7111   tempbx = SiS_Pr->SiS_VDE - 1;
7112   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7113   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7114
7115   tempcx = SiS_Pr->SiS_VT - 1;
7116   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7117   temp = (tempcx >> 3) & 0xE0;
7118   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7119      /* Enable dithering; only do this for 32bpp mode */
7120      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7121         temp |= 0x10;
7122      }
7123   }
7124   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7125
7126   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7127   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7128
7129   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7130   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7131
7132 #ifdef SIS315H
7133   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7134                                                 &CRT2Index, &resindex, HwInfo)) {
7135       switch(CRT2Index) {
7136         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7137         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7138         default:  CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;   break;
7139       }
7140
7141       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7142       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7143       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7144         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7145       }
7146       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7147         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7148       }
7149       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7150         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7151       }
7152       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7153       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7154
7155       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7156
7157
7158   } else {
7159 #endif
7160
7161     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7162     /*             Clevo dual-link 1024x768 */
7163     /*             Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7164     /*             Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7165
7166     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7167        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7168           tempbx = SiS_Pr->SiS_VDE - 1;
7169           tempcx = SiS_Pr->SiS_VT - 1;
7170        } else {
7171           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7172           tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7173        }
7174     } else {
7175        tempbx = SiS_Pr->PanelYRes;
7176        tempcx = SiS_Pr->SiS_VT;
7177        tempax = 1;
7178        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7179           tempax = SiS_Pr->PanelYRes;
7180           /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7181           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7182              tempax = tempcx = 0;
7183           } else {
7184              tempax -= SiS_Pr->SiS_VDE;
7185           }
7186           tempax >>= 1;
7187        }
7188        tempcx -= tempax; /* lcdvdes */
7189        tempbx -= tempax; /* lcdvdee */
7190     }
7191
7192     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7193
7194 #ifdef TWDEBUG
7195     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7196 #endif
7197
7198     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);      /* lcdvdes  */
7199     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);      /* lcdvdee  */
7200
7201     temp = (tempbx >> 5) & 0x38;
7202     temp |= ((tempcx >> 8) & 0x07);
7203     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7204
7205     tempax = SiS_Pr->SiS_VDE;
7206     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7207        tempax = SiS_Pr->PanelYRes;
7208     }
7209     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7210     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7211        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7212           tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7213        }
7214     }
7215
7216     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7217     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7218        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7219           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7220              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7221              if(tempax % 4) { tempax >>= 2; tempax++; }
7222              else           { tempax >>= 2;           }
7223              tempbx -= (tempax - 1);
7224           } else {
7225              tempbx -= 10;
7226              if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7227           }
7228        }
7229     }
7230     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7231        tempbx++;
7232        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7233           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7234              tempbx = 770;
7235              tempcx = 3;
7236           }
7237        }
7238     }
7239
7240     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7241
7242     if(SiS_Pr->UseCustomMode) {
7243        tempbx = SiS_Pr->CVSyncStart;
7244     }
7245
7246 #ifdef TWDEBUG
7247     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7248 #endif
7249
7250     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);          /* lcdvrs */
7251
7252     temp = (tempbx >> 4) & 0xF0;
7253     tempbx += (tempcx + 1);
7254     temp |= (tempbx & 0x0F);
7255
7256     if(SiS_Pr->UseCustomMode) {
7257        temp &= 0xf0;
7258        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7259     }
7260
7261 #ifdef TWDEBUG
7262     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7263 #endif
7264
7265     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7266
7267 #ifdef SIS300
7268     SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7269 #endif
7270
7271     bridgeoffset = 7;
7272     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)          bridgeoffset += 2;
7273     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7274     if(SiS_IsDualLink(SiS_Pr, HwInfo))                   bridgeoffset++;
7275
7276     temp = 0;
7277     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7278        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7279           temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7280           if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7281        }
7282     }
7283     temp += bridgeoffset;
7284     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);             /* lcdhdes */
7285     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7286
7287     tempcx = SiS_Pr->SiS_HT;
7288     tempax = tempbx = SiS_Pr->SiS_HDE;
7289     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7290        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7291           tempax = SiS_Pr->PanelXRes;
7292           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7293        }
7294     }
7295     if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7296        tempcx >>= 1;
7297        tempbx >>= 1;
7298        tempax >>= 1;
7299     }
7300
7301 #ifdef TWDEBUG
7302     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7303 #endif
7304
7305     tempbx += bridgeoffset;
7306
7307     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);          /* lcdhdee */
7308     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7309
7310     tempcx = (tempcx - tempax) >> 2;
7311
7312     tempbx += tempcx;
7313     push2 = tempbx;
7314
7315     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7316        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7317           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7318              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7319           }
7320        }
7321     }
7322
7323     if(SiS_Pr->UseCustomMode) {
7324        tempbx = SiS_Pr->CHSyncStart;
7325        if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7326        tempbx += bridgeoffset;
7327     }
7328
7329 #ifdef TWDEBUG
7330     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7331 #endif
7332
7333     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);          /* lcdhrs */
7334     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7335
7336     tempbx = push2;
7337
7338     tempcx <<= 1;
7339     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7340        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7341     }
7342     tempbx += tempcx;
7343
7344     if(SiS_Pr->UseCustomMode) {
7345        tempbx = SiS_Pr->CHSyncEnd;
7346        if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7347        tempbx += bridgeoffset;
7348     }
7349
7350 #ifdef TWDEBUG
7351     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7352 #endif
7353
7354     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);          /* lcdhre */
7355
7356     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7357
7358 #ifdef SIS300
7359     SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7360 #endif
7361 #ifdef SIS315H
7362   } /* CRT2-LCD from table */
7363 #endif
7364 }
7365
7366 /*********************************************/
7367 /*         SET PART 3 REGISTER GROUP         */
7368 /*********************************************/
7369
7370 static void
7371 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7372               PSIS_HW_INFO HwInfo)
7373 {
7374   USHORT        i;
7375   const UCHAR   *tempdi;
7376
7377   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7378
7379 #ifndef SIS_CP
7380   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7381 #else
7382   SIS_CP_INIT301_CP
7383 #endif
7384
7385   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7386      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7387      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7388   } else {
7389      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7390      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7391   }
7392
7393   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7394      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7395      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7396      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7397   }
7398
7399   tempdi = NULL;
7400   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7401      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7402      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7403         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7404      }
7405   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7406      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7407         tempdi = SiS_HiTVGroup3_1;
7408         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7409      }
7410   }
7411   if(tempdi) {
7412      for(i=0; i<=0x3E; i++) {
7413         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7414      }
7415      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7416         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7417            SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7418         }
7419      }
7420   }
7421
7422 #ifdef SIS_CP
7423   SIS_CP_INIT301_CP2
7424 #endif
7425 }
7426
7427 /*********************************************/
7428 /*         SET PART 4 REGISTER GROUP         */
7429 /*********************************************/
7430
7431 #ifdef SIS315H
7432 static void
7433 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7434 {
7435    USHORT temp, temp1, temp2;
7436
7437    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7438    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7439    temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7440    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7441    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7442    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7443    temp = (USHORT)((int)(temp) + shift);
7444    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7445    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7446    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7447    temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7448    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7449    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7450 }
7451
7452 static void
7453 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7454                     USHORT ModeNo, USHORT ModeIdIndex)
7455 {
7456    USHORT temp, temp1, resinfo = 0;
7457
7458    if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7459    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7460
7461    if(ModeNo > 0x13) {
7462       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7463    }
7464
7465    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7466    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7467    if(!(temp & 0x01)) {
7468       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7469       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7470       if(HwInfo->jChipType < SIS_661) {
7471          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7472       }
7473       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7474       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7475       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7476       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7477       else                                         temp = 0x0402;
7478       if(HwInfo->jChipType >= SIS_661) {
7479          temp1 = 0;
7480          if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7481          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7482          if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7483          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7484       } else {
7485          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7486          if(temp1 == 0x01) temp |= 0x01;
7487          if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7488          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7489       }
7490       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7491
7492       if(HwInfo->jChipType >= SIS_661) {                /* ? */
7493          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7494             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7495                if(resinfo == SIS_RI_1024x768) {
7496                   SiS_ShiftXPos(SiS_Pr, 97);
7497                } else {
7498                   SiS_ShiftXPos(SiS_Pr, 111);
7499                }
7500             } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7501                SiS_ShiftXPos(SiS_Pr, 136);
7502             }
7503          }
7504       }
7505    }
7506 }
7507 #endif
7508
7509 static void
7510 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7511                  USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7512 {
7513   USHORT vclkindex;
7514   USHORT temp, reg1, reg2;
7515
7516   if(SiS_Pr->UseCustomMode) {
7517      reg1 = SiS_Pr->CSR2B;
7518      reg2 = SiS_Pr->CSR2C;
7519   } else {
7520      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7521                                  HwInfo);
7522      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7523      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7524   }
7525
7526   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7527      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7528         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7529         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7530         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7531      } else {
7532         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7533         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7534      }
7535   } else {
7536      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7537      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7538      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7539   }
7540   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7541   temp = 0x08;
7542   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7543   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7544 }
7545
7546 static void
7547 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7548               USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7549 {
7550   USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7551   ULONG tempebx,tempeax,templong;
7552
7553   if(ModeNo <= 0x13) {
7554      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7555      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7556   } else if(SiS_Pr->UseCustomMode) {
7557      modeflag = SiS_Pr->CModeFlag;
7558      resinfo = 0;
7559   } else {
7560      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7561      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7562   }
7563
7564   if(HwInfo->jChipType >= SIS_315H) {
7565      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7566         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7567            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7568         }
7569      }
7570   }
7571
7572   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7573      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7574         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7575      }
7576   }
7577
7578   if(HwInfo->jChipType >= SIS_315H) {
7579      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7580         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7581            if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7582               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7583            }
7584
7585            if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7586               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7587 #ifdef SET_EMI
7588               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7589 #endif
7590               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7591            }
7592         }
7593         return;
7594      }
7595   }
7596
7597   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7598
7599   tempbx = SiS_Pr->SiS_RVBHCMAX;
7600   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7601
7602   temp = (tempbx >> 1) & 0x80;
7603
7604   tempcx = SiS_Pr->SiS_VGAHT - 1;
7605   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7606
7607   temp |= ((tempcx >> 5) & 0x78);
7608
7609   tempcx = SiS_Pr->SiS_VGAVT - 1;
7610   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7611   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7612
7613   temp |= ((tempcx >> 8) & 0x07);
7614   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7615
7616   tempbx = SiS_Pr->SiS_VGAHDE;
7617   if(modeflag & HalfDCLK)            tempbx >>= 1;
7618   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7619
7620   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7621      temp = 0;
7622      if(tempbx > 800)        temp = 0x60;
7623   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7624      temp = 0;
7625      if(tempbx == 1024)      temp = 0xA0;
7626      else if(tempbx > 1024)  temp = 0xC0;
7627   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7628      temp = 0;
7629      if(tempbx >= 1280)      temp = 0x40;
7630      else if(tempbx >= 1024) temp = 0x20;
7631   } else {
7632      temp = 0x80;
7633      if(tempbx >= 1024)      temp = 0xA0;
7634   }
7635
7636   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7637      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7638   }
7639
7640   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7641
7642   tempeax = SiS_Pr->SiS_VGAVDE;
7643   tempebx = SiS_Pr->SiS_VDE;
7644   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7645      if(!(temp & 0xE0)) tempebx >>=1;
7646   }
7647
7648   tempcx = SiS_Pr->SiS_RVBHRS;
7649   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7650   tempcx >>= 8;
7651   tempcx |= 0x40;
7652
7653   if(tempeax <= tempebx) {
7654      tempcx ^= 0x40;
7655   } else {
7656      tempeax -= tempebx;
7657   }
7658
7659   tempeax *= (256 * 1024);
7660   templong = tempeax % tempebx;
7661   tempeax /= tempebx;
7662   if(templong) tempeax++;
7663
7664   temp = (USHORT)(tempeax & 0x000000FF);
7665   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7666   temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7667   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7668   temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7669   temp |= (tempcx & 0x4F);
7670   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7671
7672   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7673
7674      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7675
7676      /* Calc Linebuffer max address and set/clear decimode */
7677      tempbx = 0;
7678      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7679      tempax = SiS_Pr->SiS_VGAHDE;
7680      if(modeflag & HalfDCLK)            tempax >>= 1;
7681      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7682      if(tempax > 800) {
7683         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7684            tempax -= 800;
7685         } else {  /* 651+301C: Only if TVNoHiviNoYPbPr */
7686            tempbx = 0x08;
7687            if(tempax == 1024) tempax *= 25;
7688            else               tempax *= 20;
7689            temp = tempax % 32;
7690            tempax /= 32;
7691            if(temp) tempax++;
7692            tempax++;
7693            if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7694               (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7695               if(resinfo == SIS_RI_1024x768) {
7696                  /* Otherwise white line at right edge */
7697                  tempax = (tempax & 0xff00) | 0x20;
7698               }
7699            }
7700         }
7701      }
7702      tempax--;
7703      temp = ((tempax >> 4) & 0x30) | tempbx;
7704      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7705      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7706
7707      temp = 0x0036; tempbx = 0xD0;
7708      if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7709         temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7710      }
7711      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7712         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7713            temp |= 0x01;
7714            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7715               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7716                  temp &= ~0x01;
7717               }
7718            }
7719         }
7720      }
7721      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7722
7723      tempbx = SiS_Pr->SiS_HT >> 1;
7724      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7725      tempbx -= 2;
7726      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7727      temp = (tempbx >> 5) & 0x38;
7728      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7729
7730      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7731         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7732            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7733            /* LCD-too-dark-error-source, see FinalizeLCD() */
7734         }
7735         if(HwInfo->jChipType >= SIS_315H) {
7736            if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7737               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7738            }
7739         }
7740         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7741            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7742 #ifdef SET_EMI
7743            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7744 #endif
7745            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7746         }
7747      }
7748
7749   }  /* 301B */
7750
7751   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7752 }
7753
7754 /*********************************************/
7755 /*         SET PART 5 REGISTER GROUP         */
7756 /*********************************************/
7757
7758 static void
7759 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7760               PSIS_HW_INFO HwInfo)
7761 {
7762
7763   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7764
7765   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7766      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7767         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7768         SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7769      }
7770   }
7771 }
7772
7773 /*********************************************/
7774 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7775 /*********************************************/
7776
7777 static void
7778 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7779                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7780 {
7781   USHORT tempah,i,modeflag,j;
7782   USHORT ResIndex,DisplayType;
7783   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7784
7785   if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7786   else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7787
7788   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7789      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7790      (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7791      return;
7792
7793   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7794                           &ResIndex, &DisplayType))) {
7795      return;
7796   }
7797
7798   if(HwInfo->jChipType < SIS_315H) {
7799      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7800   }
7801
7802   switch(DisplayType) {
7803     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
7804     case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
7805     case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
7806     case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
7807     case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
7808     case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
7809     case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
7810     case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
7811     case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
7812     case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
7813     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
7814     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
7815     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
7816     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
7817     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
7818     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
7819     case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
7820     case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
7821     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7822     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7823     case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7824     case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7825     case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
7826     case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7827     case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7828     case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7829     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7830     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
7831     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
7832     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
7833     case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
7834     case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
7835     case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
7836     case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
7837     case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
7838     case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1;          break;
7839     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
7840     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
7841     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
7842     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
7843     case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
7844     case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
7845     case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
7846     case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
7847     case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
7848     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
7849     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
7850   }
7851
7852   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7853
7854   tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
7855   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
7856
7857   for(i=0x02,j=1;i<=0x05;i++,j++){
7858     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7859     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7860   }
7861   for(i=0x06,j=5;i<=0x07;i++,j++){
7862     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7863     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7864   }
7865   for(i=0x10,j=7;i<=0x11;i++,j++){
7866     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7867     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7868   }
7869   for(i=0x15,j=9;i<=0x16;i++,j++){
7870     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7871     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7872   }
7873   for(i=0x0A,j=11;i<=0x0C;i++,j++){
7874     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7875     SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7876   }
7877
7878   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7879   tempah &= 0xE0;
7880   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7881
7882   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7883   tempah &= 0x01;
7884   tempah <<= 5;
7885   if(modeflag & DoubleScanMode)  tempah |= 0x080;
7886   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7887 }
7888
7889 /*********************************************/
7890 /*              SET CRT2 ECLK                */
7891 /*********************************************/
7892
7893 static void
7894 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7895            USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7896 {
7897   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
7898   USHORT clkbase, vclkindex=0;
7899   UCHAR  sr2b, sr2c;
7900
7901   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
7902         SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7903         if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
7904            RefreshRateTableIndex--;
7905         }
7906         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7907                                     RefreshRateTableIndex, HwInfo);
7908         SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7909   } else {
7910         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7911                                     RefreshRateTableIndex, HwInfo);
7912   }
7913
7914   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7915   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7916
7917   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7918      if(SiS_Pr->SiS_UseROM) {
7919         if(ROMAddr[0x220] & 0x01) {
7920            sr2b = ROMAddr[0x227];
7921            sr2c = ROMAddr[0x228];
7922         }
7923      }
7924   }
7925
7926   clkbase = 0x02B;
7927   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7928      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7929         clkbase += 3;
7930      }
7931   }
7932
7933   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7934   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7935   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7936   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7937   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7938   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7939   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7940   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7941   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7942 }
7943
7944 /*********************************************/
7945 /*           SET UP CHRONTEL CHIPS           */
7946 /*********************************************/
7947
7948 static void
7949 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7950                USHORT RefreshRateTableIndex)
7951 {
7952 #if defined(SIS300) || defined(SIS315H)
7953   USHORT temp, tempbx;
7954 #endif
7955   USHORT tempcl;
7956   USHORT TVType, resindex;
7957   const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
7958
7959   if(ModeNo <= 0x13)
7960      tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7961   else
7962      tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7963
7964   TVType = 0;
7965   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7966   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7967         TVType += 2;
7968         if(SiS_Pr->SiS_ModeType > ModeVGA) {
7969            if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7970         }
7971         if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7972                 TVType = 4;
7973                 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7974         } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7975                 TVType = 6;
7976                 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7977         }
7978   }
7979   switch(TVType) {
7980      case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7981      case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7982      case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
7983      case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7984      case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7985      case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7986      case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7987      case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7988      case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7989      default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7990   }
7991   resindex = tempcl & 0x3F;
7992
7993   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7994
7995 #ifdef SIS300
7996
7997      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7998
7999      /* We don't support modes >800x600 */
8000      if (resindex > 5) return;
8001
8002      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8003         SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8004         SiS_SetCH700x(SiS_Pr,0x6909);   /* Black level for PAL (105)*/
8005      } else {
8006         SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8007         SiS_SetCH700x(SiS_Pr,0x7109);   /* Black level for NTSC (113)*/
8008      }
8009
8010      temp = CHTVRegData[resindex].Reg[0];
8011      tempbx=((temp&0x00FF)<<8)|0x00;    /* Mode register */
8012      SiS_SetCH700x(SiS_Pr,tempbx);
8013      temp = CHTVRegData[resindex].Reg[1];
8014      tempbx=((temp&0x00FF)<<8)|0x07;    /* Start active video register */
8015      SiS_SetCH700x(SiS_Pr,tempbx);
8016      temp = CHTVRegData[resindex].Reg[2];
8017      tempbx=((temp&0x00FF)<<8)|0x08;    /* Position overflow register */
8018      SiS_SetCH700x(SiS_Pr,tempbx);
8019      temp = CHTVRegData[resindex].Reg[3];
8020      tempbx=((temp&0x00FF)<<8)|0x0A;    /* Horiz Position register */
8021      SiS_SetCH700x(SiS_Pr,tempbx);
8022      temp = CHTVRegData[resindex].Reg[4];
8023      tempbx=((temp&0x00FF)<<8)|0x0B;    /* Vertical Position register */
8024      SiS_SetCH700x(SiS_Pr,tempbx);
8025
8026      /* Set minimum flicker filter for Luma channel (SR1-0=00),
8027                 minimum text enhancement (S3-2=10),
8028                 maximum flicker filter for Chroma channel (S5-4=10)
8029                 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8030       */
8031      SiS_SetCH700x(SiS_Pr,0x2801);
8032
8033      /* Set video bandwidth
8034             High bandwith Luma composite video filter(S0=1)
8035             low bandwith Luma S-video filter (S2-1=00)
8036             disable peak filter in S-video channel (S3=0)
8037             high bandwidth Chroma Filter (S5-4=11)
8038             =00110001=0x31
8039      */
8040      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
8041
8042      /* Register 0x3D does not exist in non-macrovision register map
8043             (Maybe this is a macrovision register?)
8044       */
8045 #ifndef SIS_CP
8046      SiS_SetCH70xx(SiS_Pr,0x003D);
8047 #endif
8048
8049      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8050             all other bits a read-only. Macrovision?
8051       */
8052      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8053
8054      /* Register 0x11 only contains 3 writable bits (S0-S2) for
8055             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8056       */
8057      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8058
8059      /* Clear DSEN
8060       */
8061      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8062
8063      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {             /* ---- NTSC ---- */
8064        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8065          if(resindex == 0x04) {                         /* 640x480 overscan: Mode 16 */
8066            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8067            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
8068          } else if(resindex == 0x05) {                  /* 800x600 overscan: Mode 23 */
8069            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);      /* 0x18-0x1f: FSCI 469,762,048 */
8070            SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8071            SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8072            SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8073            SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8074            SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8075            SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8076            SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8077            SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);       /* Loop filter on for mode 23 */
8078            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
8079          }
8080        } else {
8081          if(resindex == 0x04) {                          /* ----- 640x480 underscan; Mode 17 */
8082            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off */
8083            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8084          } else if(resindex == 0x05) {                   /* ----- 800x600 underscan: Mode 24 */
8085 #if 0
8086            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8087            SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);       /* FSCI for mode 24 is 428,554,851 */
8088            SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);       /* 198b3a63 */
8089            SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8090            SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8091            SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8092            SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8093            SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8094            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off for mode 24 */
8095            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
8096 #endif     /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8097            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off */
8098            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8099          }
8100        }
8101      } else {                                           /* ---- PAL ---- */
8102            /* We don't play around with FSCI in PAL mode */
8103          if(resindex == 0x04) {
8104            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8105            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8106          } else {
8107            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
8108            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8109          }
8110      }
8111      
8112 #endif  /* 300 */
8113
8114   } else {
8115
8116      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8117
8118 #ifdef SIS315H
8119
8120      /* We don't support modes >1024x768 */
8121      if (resindex > 6) return;
8122
8123      temp = CHTVRegData[resindex].Reg[0];
8124      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8125         temp |= 0x10;
8126      }
8127      tempbx=((temp & 0x00FF) << 8) | 0x00;
8128      SiS_SetCH701x(SiS_Pr,tempbx);
8129
8130      temp = CHTVRegData[resindex].Reg[1];
8131      tempbx=((temp & 0x00FF) << 8) | 0x01;
8132      SiS_SetCH701x(SiS_Pr,tempbx);
8133
8134      temp = CHTVRegData[resindex].Reg[2];
8135      tempbx=((temp & 0x00FF) << 8) | 0x02;
8136      SiS_SetCH701x(SiS_Pr,tempbx);
8137
8138      temp = CHTVRegData[resindex].Reg[3];
8139      tempbx=((temp & 0x00FF) << 8) | 0x04;
8140      SiS_SetCH701x(SiS_Pr,tempbx);
8141
8142      temp = CHTVRegData[resindex].Reg[4];
8143      tempbx=((temp & 0x00FF) << 8) | 0x03;
8144      SiS_SetCH701x(SiS_Pr,tempbx);
8145
8146      temp = CHTVRegData[resindex].Reg[5];
8147      tempbx=((temp & 0x00FF) << 8) | 0x05;
8148      SiS_SetCH701x(SiS_Pr,tempbx);
8149
8150      temp = CHTVRegData[resindex].Reg[6];
8151      tempbx=((temp & 0x00FF) << 8) | 0x06;
8152      SiS_SetCH701x(SiS_Pr,tempbx);
8153
8154      temp = CHTVRegData[resindex].Reg[7];
8155      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8156         temp = 0x66;
8157      }
8158      tempbx=((temp & 0x00FF) << 8) | 0x07;
8159      SiS_SetCH701x(SiS_Pr,tempbx);
8160
8161      temp = CHTVRegData[resindex].Reg[8];
8162      tempbx=((temp & 0x00FF) << 8) | 0x08;
8163      SiS_SetCH701x(SiS_Pr,tempbx);
8164
8165      temp = CHTVRegData[resindex].Reg[9];
8166      tempbx=((temp & 0x00FF) << 8) | 0x15;
8167      SiS_SetCH701x(SiS_Pr,tempbx);
8168
8169      temp = CHTVRegData[resindex].Reg[10];
8170      tempbx=((temp & 0x00FF) << 8) | 0x1f;
8171      SiS_SetCH701x(SiS_Pr,tempbx);
8172
8173      temp = CHTVRegData[resindex].Reg[11];
8174      tempbx=((temp & 0x00FF) << 8) | 0x0c;
8175      SiS_SetCH701x(SiS_Pr,tempbx);
8176
8177      temp = CHTVRegData[resindex].Reg[12];
8178      tempbx=((temp & 0x00FF) << 8) | 0x0d;
8179      SiS_SetCH701x(SiS_Pr,tempbx);
8180
8181      temp = CHTVRegData[resindex].Reg[13];
8182      tempbx=((temp & 0x00FF) << 8) | 0x0e;
8183      SiS_SetCH701x(SiS_Pr,tempbx);
8184
8185      temp = CHTVRegData[resindex].Reg[14];
8186      tempbx=((temp & 0x00FF) << 8) | 0x0f;
8187      SiS_SetCH701x(SiS_Pr,tempbx);
8188
8189      temp = CHTVRegData[resindex].Reg[15];
8190      tempbx=((temp & 0x00FF) << 8) | 0x10;
8191      SiS_SetCH701x(SiS_Pr,tempbx);
8192
8193      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8194      /* D1 should be set for PAL, PAL-N and NTSC-J,
8195         but I won't do that for PAL unless somebody
8196         tells me to do so. Since the BIOS uses
8197         non-default CIV values and blacklevels,
8198         this might be compensated anyway.
8199       */
8200      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8201      SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8202
8203 #endif  /* 315 */
8204
8205   }
8206
8207 #ifdef SIS_CP
8208   SIS_CP_INIT301_CP3
8209 #endif
8210
8211 }
8212
8213 void
8214 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8215 {
8216   USHORT temp;
8217
8218   /* Enable Chrontel 7019 LCD panel backlight */
8219   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8220      if(HwInfo->jChipType == SIS_740) {
8221         SiS_SetCH701x(SiS_Pr,0x6566);
8222      } else {
8223         temp = SiS_GetCH701x(SiS_Pr,0x66);
8224         temp |= 0x20;
8225         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8226      }
8227   }
8228 }
8229
8230 void
8231 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8232 {
8233   USHORT temp;
8234
8235   /* Disable Chrontel 7019 LCD panel backlight */
8236   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8237      temp = SiS_GetCH701x(SiS_Pr,0x66);
8238      temp &= 0xDF;
8239      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8240   }
8241 }
8242
8243 #ifdef SIS315H  /* ----------- 315 series only ---------- */
8244
8245 static void
8246 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8247 {
8248   UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8249   UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8250   UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8251   UCHAR asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8252   UCHAR asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8253   UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8254   UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8255   UCHAR *tableptr = NULL;
8256   int i;
8257
8258   /* Set up Power up/down timing */
8259
8260   if(HwInfo->jChipType == SIS_740) {
8261      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8262         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8263         else                                      tableptr = table1024_740;
8264      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8265                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8266                (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8267         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8268         else                                      tableptr = table1400_740;
8269      } else return;
8270   } else {
8271      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8272         tableptr = table1024_650;
8273      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8274                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8275                (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8276         tableptr = table1400_650;
8277      } else return;
8278   }
8279
8280   for(i=0; i<5; i++) {
8281      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8282   }
8283 }
8284
8285 static void
8286 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8287 {
8288   UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8289                             0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8290   UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8291                             0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8292   UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8293                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8294   UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8295                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8296   UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8297                             0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8298   UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8299                             0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8300   UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8301                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8302   UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8303                             0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8304   UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8305                             0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8306   UCHAR *tableptr = NULL;
8307   USHORT tempbh;
8308   int i;
8309
8310   if(HwInfo->jChipType == SIS_740) {
8311      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8312      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8313      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8314      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8315      else return;
8316   } else {
8317      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8318      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8319      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8320      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8321      else return;
8322   }
8323
8324   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8325   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8326      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8327      if(tempbh == 0xc8) {
8328         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8329      } else if(tempbh == 0xdb) {
8330         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8331         if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8332      } else if(tempbh == 0xde) {
8333         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8334      }
8335   }
8336
8337   if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8338   else                             tempbh = 0x0c;
8339
8340   for(i = 0; i < tempbh; i++) {
8341      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8342   }
8343   SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8344   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8345   tempbh |= 0xc0;
8346   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8347
8348   if(HwInfo->jChipType == SIS_740) {
8349      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8350      tempbh &= 0xfb;
8351      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8352      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8353      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8354      tempbh |= 0x40;
8355      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8356      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8357      tempbh &= 0x3f;
8358      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8359   }
8360 }
8361
8362 static void
8363 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8364 {
8365   unsigned char temp, temp1;
8366
8367   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8368   SiS_SetCH701x(SiS_Pr,0x3e49);
8369   temp = SiS_GetCH701x(SiS_Pr,0x47);
8370   temp &= 0x7f; /* Use external VSYNC */
8371   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8372   SiS_LongDelay(SiS_Pr,3);
8373   temp = SiS_GetCH701x(SiS_Pr,0x47);
8374   temp |= 0x80; /* Use internal VSYNC */
8375   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8376   SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8377 }
8378
8379 void
8380 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8381 {
8382   USHORT temp;
8383
8384   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8385      if(HwInfo->jChipType == SIS_740) {
8386         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8387         temp |= 0x04;   /* Invert XCLK phase */
8388         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8389      }
8390      if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8391         temp = SiS_GetCH701x(SiS_Pr,0x01);
8392         temp &= 0x3f;
8393         temp |= 0x80;   /* Enable YPrPb (HDTV) */
8394         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8395      }
8396      if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8397         temp = SiS_GetCH701x(SiS_Pr,0x01);
8398         temp &= 0x3f;
8399         temp |= 0xc0;   /* Enable SCART + CVBS */
8400         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8401      }
8402      if(HwInfo->jChipType == SIS_740) {
8403         SiS_ChrontelResetVSync(SiS_Pr);
8404         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
8405      } else {
8406         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
8407         temp = SiS_GetCH701x(SiS_Pr,0x49);
8408         if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8409            temp = SiS_GetCH701x(SiS_Pr,0x73);
8410            temp |= 0x60;
8411            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8412         }
8413         temp = SiS_GetCH701x(SiS_Pr,0x47);
8414         temp &= 0x7f;
8415         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8416         SiS_LongDelay(SiS_Pr,2);
8417         temp = SiS_GetCH701x(SiS_Pr,0x47);
8418         temp |= 0x80;
8419         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8420      }
8421   }
8422 }
8423
8424 void
8425 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8426 {
8427   USHORT temp;
8428
8429   /* Complete power down of LVDS */
8430   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8431      if(HwInfo->jChipType == SIS_740) {
8432         SiS_LongDelay(SiS_Pr,1);
8433         SiS_GenericDelay(SiS_Pr,0x16ff);
8434         SiS_SetCH701x(SiS_Pr,0xac76);
8435         SiS_SetCH701x(SiS_Pr,0x0066);
8436      } else {
8437         SiS_LongDelay(SiS_Pr,2);
8438         temp = SiS_GetCH701x(SiS_Pr,0x76);
8439         temp &= 0xfc;
8440         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8441         SiS_SetCH701x(SiS_Pr,0x0066);
8442      }
8443   }
8444 }
8445
8446 static void
8447 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8448 {
8449      USHORT temp;
8450
8451      if(HwInfo->jChipType == SIS_740) {
8452
8453         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8454         temp &= 0x01;
8455         if(!temp) {
8456
8457            if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8458               temp = SiS_GetCH701x(SiS_Pr,0x49);
8459               SiS_SetCH701x(SiS_Pr,0x3e49);
8460            }
8461            /* Reset Chrontel 7019 datapath */
8462            SiS_SetCH701x(SiS_Pr,0x1048);
8463            SiS_LongDelay(SiS_Pr,1);
8464            SiS_SetCH701x(SiS_Pr,0x1848);
8465
8466            if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8467               SiS_ChrontelResetVSync(SiS_Pr);
8468               SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8469            }
8470
8471         } else {
8472
8473            /* Clear/set/clear GPIO */
8474            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8475            temp &= 0xef;
8476            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8477            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8478            temp |= 0x10;
8479            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8480            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8481            temp &= 0xef;
8482            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8483            temp = SiS_GetCH701x(SiS_Pr,0x61);
8484            if(!temp) {
8485               SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8486            }
8487         }
8488
8489      } else { /* 650 */
8490         /* Reset Chrontel 7019 datapath */
8491         SiS_SetCH701x(SiS_Pr,0x1048);
8492         SiS_LongDelay(SiS_Pr,1);
8493         SiS_SetCH701x(SiS_Pr,0x1848);
8494      }
8495 }
8496
8497 void
8498 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8499 {
8500      USHORT temp;
8501
8502      if(HwInfo->jChipType == SIS_740) {
8503
8504         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8505            SiS_ChrontelResetVSync(SiS_Pr);
8506         }
8507
8508      } else {
8509
8510         SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
8511         temp = SiS_GetCH701x(SiS_Pr,0x49);
8512         temp &= 1;
8513         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8514            temp = SiS_GetCH701x(SiS_Pr,0x47);
8515            temp &= 0x70;
8516            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
8517            SiS_LongDelay(SiS_Pr,3);
8518            temp = SiS_GetCH701x(SiS_Pr,0x47);
8519            temp |= 0x80;
8520            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
8521         }
8522
8523      }
8524 }
8525
8526 static void
8527 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8528 {
8529      USHORT temp,temp1;
8530
8531      if(HwInfo->jChipType == SIS_740) {
8532
8533         temp = SiS_GetCH701x(SiS_Pr,0x61);
8534         if(temp < 1) {
8535            temp++;
8536            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8537         }
8538         SiS_SetCH701x(SiS_Pr,0x4566);  /* Panel power on */
8539         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on */
8540         SiS_LongDelay(SiS_Pr,1);
8541         SiS_GenericDelay(SiS_Pr,0x16ff);
8542
8543      } else {  /* 650 */
8544
8545         temp1 = 0;
8546         temp = SiS_GetCH701x(SiS_Pr,0x61);
8547         if(temp < 2) {
8548            temp++;
8549            SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8550            temp1 = 1;
8551         }
8552         SiS_SetCH701x(SiS_Pr,0xac76);
8553         temp = SiS_GetCH701x(SiS_Pr,0x66);
8554         temp |= 0x5f;
8555         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8556         if(ModeNo > 0x13) {
8557            if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8558               SiS_GenericDelay(SiS_Pr,0x3ff);
8559            } else {
8560               SiS_GenericDelay(SiS_Pr,0x2ff);
8561            }
8562         } else {
8563            if(!temp1)
8564               SiS_GenericDelay(SiS_Pr,0x2ff);
8565         }
8566         temp = SiS_GetCH701x(SiS_Pr,0x76);
8567         temp |= 0x03;
8568         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8569         temp = SiS_GetCH701x(SiS_Pr,0x66);
8570         temp &= 0x7f;
8571         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8572         SiS_LongDelay(SiS_Pr,1);
8573
8574      }
8575 }
8576
8577 static void
8578 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8579 {
8580      USHORT temp,tempcl,tempch;
8581
8582      SiS_LongDelay(SiS_Pr, 1);
8583      tempcl = 3;
8584      tempch = 0;
8585
8586      do {
8587        temp = SiS_GetCH701x(SiS_Pr,0x66);
8588        temp &= 0x04;  /* PLL stable? -> bail out */
8589        if(temp == 0x04) break;
8590
8591        if(HwInfo->jChipType == SIS_740) {
8592           /* Power down LVDS output, PLL normal operation */
8593           SiS_SetCH701x(SiS_Pr,0xac76);
8594        }
8595
8596        SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8597
8598        if(tempcl == 0) {
8599            if(tempch == 3) break;
8600            SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8601            tempcl = 3;
8602            tempch++;
8603        }
8604        tempcl--;
8605        temp = SiS_GetCH701x(SiS_Pr,0x76);
8606        temp &= 0xfb;  /* Reset PLL */
8607        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8608        SiS_LongDelay(SiS_Pr,2);
8609        temp = SiS_GetCH701x(SiS_Pr,0x76);
8610        temp |= 0x04;  /* PLL normal operation */
8611        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8612        if(HwInfo->jChipType == SIS_740) {
8613           SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8614        } else {
8615           SiS_SetCH701x(SiS_Pr,0x6078);
8616        }
8617        SiS_LongDelay(SiS_Pr,2);
8618     } while(0);
8619
8620     SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
8621 }
8622
8623 void
8624 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8625 {
8626      USHORT temp;
8627
8628      temp = SiS_GetCH701x(SiS_Pr,0x03);
8629      temp |= 0x80;      /* Set datapath 1 to TV   */
8630      temp &= 0xbf;      /* Set datapath 2 to LVDS */
8631      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8632
8633      if(HwInfo->jChipType == SIS_740) {
8634
8635         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8636         temp &= 0xfb;   /* Normal XCLK phase */
8637         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8638
8639         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8640
8641         temp = SiS_GetCH701x(SiS_Pr,0x64);
8642         temp |= 0x40;   /* ? Bit not defined */
8643         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8644
8645         temp = SiS_GetCH701x(SiS_Pr,0x03);
8646         temp &= 0x3f;   /* D1 input to both LVDS and TV */
8647         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8648
8649         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8650            SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8651            SiS_LongDelay(SiS_Pr, 1);
8652            SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8653            SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8654            SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8655            SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8656         } else {
8657            temp = SiS_GetCH701x(SiS_Pr,0x66);
8658            if(temp != 0x45) {
8659               SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8660               SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8661               SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8662            }
8663         }
8664
8665      } else { /* 650 */
8666
8667         SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8668         SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8669         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8670         SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8671         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on, LVDS normal operation */
8672
8673      }
8674
8675 }
8676 #endif  /* 315 series  */
8677
8678 /*********************************************/
8679 /*      MAIN: SET CRT2 REGISTER GROUP        */
8680 /*********************************************/
8681
8682 BOOLEAN
8683 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8684 {
8685 #ifdef SIS300
8686    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
8687 #endif
8688    USHORT ModeIdIndex, RefreshRateTableIndex;
8689 #if 0
8690    USHORT temp;
8691 #endif
8692
8693    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8694
8695    if(!SiS_Pr->UseCustomMode) {
8696       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8697    } else {
8698       ModeIdIndex = 0;
8699    }
8700
8701    /* Used for shifting CR33 */
8702    SiS_Pr->SiS_SelectCRT2Rate = 4;
8703
8704    SiS_UnLockCRT2(SiS_Pr, HwInfo);
8705
8706    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8707
8708    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8709
8710    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8711       SiS_DisableBridge(SiS_Pr,HwInfo);
8712       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8713          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8714       }
8715       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8716    }
8717
8718    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8719       SiS_LockCRT2(SiS_Pr, HwInfo);
8720       SiS_DisplayOn(SiS_Pr);
8721       return TRUE;
8722    }
8723
8724    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8725
8726    /* Set up Panel Link for LVDS and LCDA */
8727    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8728    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8729        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8730        ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8731       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8732    }
8733
8734 #ifdef LINUX_XF86
8735 #ifdef TWDEBUG
8736   xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8737   xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8738   xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8739   xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8740   xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8741 #endif
8742 #endif
8743
8744    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8745       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8746    }
8747
8748    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8749
8750         if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8751
8752            SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8753 #ifdef SIS315H
8754            SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8755 #endif
8756            SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8757            SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8758 #ifdef SIS315H
8759            SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8760 #endif
8761            SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8762
8763            SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8764
8765            /* For 301BDH (Panel link initialization): */
8766            if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8767               if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8768                  if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8769                     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8770                        SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8771                                        RefreshRateTableIndex,HwInfo);
8772                     }
8773                  }
8774               }
8775               SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8776                               RefreshRateTableIndex,HwInfo);
8777            }
8778         }
8779
8780    } else {
8781
8782         SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8783
8784         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8785            SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8786         }
8787
8788         SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8789
8790         if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8791            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8792               if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8793                  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8794 #ifdef SIS315H
8795                     SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8796 #endif
8797                  }
8798               }
8799               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8800                  SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8801               }
8802            }
8803         }
8804
8805    }
8806
8807 #ifdef SIS300
8808    if(HwInfo->jChipType < SIS_315H) {
8809       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8810          if(SiS_Pr->SiS_UseOEM) {
8811             if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8812                if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8813                   SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8814                                     RefreshRateTableIndex);
8815                }
8816             } else {
8817                SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8818                                  RefreshRateTableIndex);
8819             }
8820          }
8821          if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8822             if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8823                (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8824                SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8825             }
8826             if(HwInfo->jChipType == SIS_730) {
8827                SiS_DisplayOn(SiS_Pr);
8828             }
8829          }
8830       }
8831       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8832           if(HwInfo->jChipType != SIS_730) {
8833              SiS_DisplayOn(SiS_Pr);
8834           }
8835       }
8836    }
8837 #endif
8838
8839 #ifdef SIS315H
8840    if(HwInfo->jChipType >= SIS_315H) {
8841       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8842          if(HwInfo->jChipType < SIS_661) {
8843             SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8844             SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8845          } else {
8846             SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8847          }
8848          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8849       }
8850    }
8851 #endif
8852
8853    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8854       SiS_EnableBridge(SiS_Pr, HwInfo);
8855    }
8856
8857    SiS_DisplayOn(SiS_Pr);
8858
8859    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8860       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8861          /* Disable LCD panel when using TV */
8862          SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
8863       } else {
8864          /* Disable TV when using LCD */
8865          SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
8866       }
8867    }
8868
8869    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8870       SiS_LockCRT2(SiS_Pr,HwInfo);
8871    }
8872
8873    return TRUE;
8874 }
8875
8876
8877 /*********************************************/
8878 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8879 /*********************************************/
8880
8881 void
8882 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8883 {
8884   /* Switch on LCD backlight on SiS30xLV */
8885   SiS_DDC2Delay(SiS_Pr,0xff00);
8886   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8887      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8888      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
8889   }
8890   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8891      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8892   }
8893 }
8894
8895 void
8896 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8897 {
8898   /* Switch off LCD backlight on SiS30xLV */
8899   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8900   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
8901   SiS_DDC2Delay(SiS_Pr,0xe000);
8902 }
8903
8904 /*********************************************/
8905 /*          DDC RELATED FUNCTIONS            */
8906 /*********************************************/
8907
8908 static void
8909 SiS_SetupDDCN(SiS_Private *SiS_Pr)
8910 {
8911   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8912   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
8913   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8914      SiS_Pr->SiS_DDC_NData &= 0x0f;
8915      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
8916   }
8917 }
8918
8919 #ifdef SIS300
8920 static UCHAR *
8921 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
8922 {
8923   int i, j, num;
8924   USHORT tempah,temp;
8925   UCHAR *mydataptr;
8926
8927   for(i=0; i<20; i++) {                         /* Do 20 attempts to write */
8928      mydataptr = dataptr;
8929      num = *mydataptr++;
8930      if(!num) return mydataptr;
8931      if(i) {
8932         SiS_SetStop(SiS_Pr);
8933         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
8934      }
8935      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
8936      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8937      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
8938      if(temp) continue;                         /*    (ERROR: no ack) */
8939      tempah = *mydataptr++;
8940      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write register number */
8941      if(temp) continue;                         /*    (ERROR: no ack) */
8942      for(j=0; j<num; j++) {
8943         tempah = *mydataptr++;
8944         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8945         if(temp) break;
8946      }
8947      if(temp) continue;
8948      if(SiS_SetStop(SiS_Pr)) continue;
8949      return mydataptr;
8950   }
8951   return NULL;
8952 }
8953
8954 static BOOLEAN
8955 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
8956 {
8957   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;            /* DAB (Device Address Byte) */
8958   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
8959   SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
8960   SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
8961   SiS_SetupDDCN(SiS_Pr);
8962
8963   SiS_SetSwitchDDC2(SiS_Pr);
8964
8965   while(*dataptr) {
8966      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8967      if(!dataptr) return FALSE;
8968   }
8969 #ifdef TWDEBUG
8970   xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8971 #endif
8972   return TRUE;
8973 }
8974 #endif
8975
8976 /* The Chrontel 700x is connected to the 630/730 via
8977  * the 630/730's DDC/I2C port.
8978  *
8979  * On 630(S)T chipset, the index changed from 0x11 to
8980  * 0x0a, possibly for working around the DDC problems
8981  */
8982
8983 static BOOLEAN
8984 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
8985 {
8986   USHORT tempah,temp,i;
8987
8988   for(i=0; i<20; i++) {                         /* Do 20 attempts to write */
8989      if(i) {
8990         SiS_SetStop(SiS_Pr);
8991         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8992      }
8993      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
8994      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8995      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
8996      if(temp) continue;                         /*    (ERROR: no ack) */
8997      tempah = tempbx & 0x00FF;                  /* Write RAB */
8998      tempah |= myor;                            /* (700x: set bit 7, see datasheet) */
8999      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9000      if(temp) continue;                         /*    (ERROR: no ack) */
9001      tempah = (tempbx & 0xFF00) >> 8;
9002      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write data */
9003      if(temp) continue;                         /*    (ERROR: no ack) */
9004      if(SiS_SetStop(SiS_Pr)) continue;          /* Set stop condition */
9005      SiS_Pr->SiS_ChrontelInit = 1;
9006      return TRUE;
9007   }
9008   return FALSE;
9009 }
9010
9011 #ifdef SIS300
9012 /* Write Trumpion register */
9013 void
9014 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9015 {
9016   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;            /* DAB (Device Address Byte) */
9017   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9018   SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
9019   SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
9020   SiS_SetupDDCN(SiS_Pr);
9021   SiS_SetChReg(SiS_Pr, tempbx, 0);
9022 }
9023 #endif
9024
9025 /* Write to Chrontel 700x */
9026 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9027 void
9028 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9029 {
9030   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9031
9032   if(!(SiS_Pr->SiS_ChrontelInit)) {
9033      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9034      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9035      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9036      SiS_SetupDDCN(SiS_Pr);
9037   }
9038
9039   if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9040       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9041      SiS_Pr->SiS_DDC_Index = 0x0a;              /* Bit 7 = SC;  Bit 6 = SD */
9042      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
9043      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
9044      SiS_SetupDDCN(SiS_Pr);
9045
9046      SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9047   }
9048 }
9049
9050 /* Write to Chrontel 701x */
9051 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9052 void
9053 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9054 {
9055   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9056   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9057   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9058   SiS_SetupDDCN(SiS_Pr);
9059   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9060   SiS_SetChReg(SiS_Pr, tempbx, 0);
9061 }
9062
9063 void
9064 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9065 {
9066   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9067      SiS_SetCH700x(SiS_Pr,tempbx);
9068   else
9069      SiS_SetCH701x(SiS_Pr,tempbx);
9070 }
9071
9072 static USHORT
9073 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9074 {
9075   USHORT tempah,temp,i;
9076
9077   for(i=0; i<20; i++) {                         /* Do 20 attempts to read */
9078      if(i) {
9079         SiS_SetStop(SiS_Pr);
9080         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9081      }
9082      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
9083      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9084      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
9085      if(temp) continue;                         /*        (ERROR: no ack) */
9086      tempah = SiS_Pr->SiS_DDC_ReadAddr | myor;  /* Write RAB (700x: | 0x80) */
9087      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9088      if(temp) continue;                         /*        (ERROR: no ack) */
9089      if (SiS_SetStart(SiS_Pr)) continue;        /* Re-start */
9090      tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9091      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* DAB (S0=1=read) */
9092      if(temp) continue;                         /*        (ERROR: no ack) */
9093      tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);  /* Read byte */
9094      if(SiS_SetStop(SiS_Pr)) continue;          /* Stop condition */
9095      SiS_Pr->SiS_ChrontelInit = 1;
9096      return(tempah);
9097   }
9098   return 0xFFFF;
9099 }
9100
9101 #ifdef SIS300
9102 /* Read from Trumpion */
9103 USHORT
9104 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9105 {
9106   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;    /* DAB */
9107   SiS_Pr->SiS_DDC_Index = 0x11;         /* Bit 0 = SC;  Bit 1 = SD */
9108   SiS_Pr->SiS_DDC_Data  = 0x02;         /* Bitmask in IndexReg for Data */
9109   SiS_Pr->SiS_DDC_Clk   = 0x01;         /* Bitmask in IndexReg for Clk */
9110   SiS_SetupDDCN(SiS_Pr);
9111   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9112   return(SiS_GetChReg(SiS_Pr,0));
9113 }
9114 #endif
9115
9116 /* Read from Chrontel 700x */
9117 /* Parameter is [Register no (S7-S0)] */
9118 USHORT
9119 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9120 {
9121   USHORT result;
9122
9123   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9124
9125   if(!(SiS_Pr->SiS_ChrontelInit)) {
9126      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9127      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9128      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9129      SiS_SetupDDCN(SiS_Pr);
9130   }
9131
9132   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9133
9134   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9135       (!SiS_Pr->SiS_ChrontelInit) ) {
9136
9137      SiS_Pr->SiS_DDC_Index = 0x0a;
9138      SiS_Pr->SiS_DDC_Data  = 0x80;
9139      SiS_Pr->SiS_DDC_Clk   = 0x40;
9140      SiS_SetupDDCN(SiS_Pr);
9141
9142      result = SiS_GetChReg(SiS_Pr,0x80);
9143   }
9144   return(result);
9145 }
9146
9147 /* Read from Chrontel 701x */
9148 /* Parameter is [Register no (S7-S0)] */
9149 USHORT
9150 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9151 {
9152   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9153   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9154   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9155   SiS_SetupDDCN(SiS_Pr);
9156   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9157
9158   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9159
9160   return(SiS_GetChReg(SiS_Pr,0));
9161 }
9162
9163 /* Read from Chrontel 70xx */
9164 /* Parameter is [Register no (S7-S0)] */
9165 USHORT
9166 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9167 {
9168   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9169      return(SiS_GetCH700x(SiS_Pr, tempbx));
9170   else
9171      return(SiS_GetCH701x(SiS_Pr, tempbx));
9172 }
9173
9174 /* Our own DDC functions */
9175 USHORT
9176 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9177                 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9178 {
9179      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9180      unsigned char flag, cr32;
9181      USHORT        temp = 0, myadaptnum = adaptnum;
9182
9183      if(adaptnum != 0) {
9184         if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9185         if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9186      }  
9187      
9188      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9189      
9190      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9191
9192      SiS_Pr->SiS_DDC_SecAddr = 0;
9193      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9194      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9195      SiS_Pr->SiS_DDC_Index = 0x11;
9196      flag = 0xff;
9197
9198      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9199
9200 #if 0
9201      if(VBFlags & VB_SISBRIDGE) {
9202         if(myadaptnum == 0) {
9203            if(!(cr32 & 0x20)) {
9204               myadaptnum = 2;
9205               if(!(cr32 & 0x10)) {
9206                  myadaptnum = 1;
9207                  if(!(cr32 & 0x08)) {
9208                     myadaptnum = 0;
9209                  }
9210               }
9211            }
9212         }
9213      }
9214 #endif
9215
9216      if(VGAEngine == SIS_300_VGA) {             /* 300 series */
9217         
9218         if(myadaptnum != 0) {
9219            flag = 0;
9220            if(VBFlags & VB_SISBRIDGE) {
9221               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9222               SiS_Pr->SiS_DDC_Index = 0x0f;
9223            }
9224         }
9225
9226         if(!(VBFlags & VB_301)) {
9227            if((cr32 & 0x80) && (checkcr32)) {
9228               if(myadaptnum >= 1) {
9229                  if(!(cr32 & 0x08)) {
9230                      myadaptnum = 1;
9231                      if(!(cr32 & 0x10)) return 0xFFFF;
9232                  }
9233               }
9234            }
9235         }
9236
9237         temp = 4 - (myadaptnum * 2);
9238         if(flag) temp = 0;
9239
9240      } else {                                           /* 315/330 series */
9241
9242         /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9243
9244         if(VBFlags & VB_SISBRIDGE) {
9245            if(myadaptnum == 2) {
9246               myadaptnum = 1;
9247            }
9248         }
9249
9250         if(myadaptnum == 1) {
9251            flag = 0;
9252            if(VBFlags & VB_SISBRIDGE) {
9253               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9254               SiS_Pr->SiS_DDC_Index = 0x0f;
9255            }
9256         }
9257
9258         if((cr32 & 0x80) && (checkcr32)) {
9259            if(myadaptnum >= 1) {
9260               if(!(cr32 & 0x08)) {
9261                  myadaptnum = 1;
9262                  if(!(cr32 & 0x10)) return 0xFFFF;
9263               }
9264            }
9265         }
9266
9267         temp = myadaptnum;
9268         if(myadaptnum == 1) {
9269            temp = 0;
9270            if(VBFlags & VB_LVDS) flag = 0xff;
9271         }
9272
9273         if(flag) temp = 0;
9274     }
9275     
9276     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9277     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9278
9279     SiS_SetupDDCN(SiS_Pr);
9280
9281 #ifdef TWDEBUG
9282     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9283                 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9284 #endif
9285     
9286     return 0;
9287 }
9288
9289 USHORT
9290 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9291 {
9292    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9293    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9294         return 0xFFFF;
9295    }
9296    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9297         return 0xFFFF;
9298    }
9299    return(0);
9300 }
9301
9302 USHORT
9303 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9304 {
9305    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9306    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9307         return 0xFFFF;
9308    }
9309    return(0);
9310 }
9311
9312 USHORT
9313 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9314 {
9315    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9316    if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9317    return(0);
9318 }
9319
9320 void
9321 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9322 {
9323    SiS_SetSCLKLow(SiS_Pr);
9324    if(yesno) {
9325       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9326                       SiS_Pr->SiS_DDC_Index,
9327                       SiS_Pr->SiS_DDC_NData,
9328                       SiS_Pr->SiS_DDC_Data);
9329    } else {
9330       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9331                       SiS_Pr->SiS_DDC_Index,
9332                       SiS_Pr->SiS_DDC_NData,
9333                       0);
9334    }
9335    SiS_SetSCLKHigh(SiS_Pr);
9336 }
9337
9338 USHORT
9339 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9340 {
9341     unsigned char mask, value;
9342     USHORT  temp, ret=0;
9343     BOOLEAN failed = FALSE;
9344
9345     SiS_SetSwitchDDC2(SiS_Pr);
9346     if(SiS_PrepareDDC(SiS_Pr)) {
9347          SiS_SetStop(SiS_Pr);
9348 #ifdef TWDEBUG
9349          xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9350 #endif
9351          return(0xFFFF);
9352     }
9353     mask = 0xf0;
9354     value = 0x20;
9355     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9356        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9357        SiS_SendACK(SiS_Pr, 0);
9358        if(temp == 0) {
9359            mask = 0xff;
9360            value = 0xff;
9361        } else {
9362            failed = TRUE;
9363            ret = 0xFFFF;
9364 #ifdef TWDEBUG
9365            xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9366 #endif
9367        }
9368     }
9369     if(failed == FALSE) {
9370        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9371        SiS_SendACK(SiS_Pr, 1);
9372        temp &= mask;
9373        if(temp == value) ret = 0;
9374        else {
9375           ret = 0xFFFF;
9376 #ifdef TWDEBUG
9377           xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9378 #endif
9379           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9380              if(temp == 0x30) ret = 0;
9381           }
9382        }
9383     }
9384     SiS_SetStop(SiS_Pr);
9385     return(ret);
9386 }
9387
9388 USHORT
9389 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9390 {
9391    USHORT flag;
9392
9393    flag = 0x180;
9394    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9395    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9396    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9397    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9398    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9399    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9400    if(!(flag & 0x1a)) flag = 0;
9401    return(flag);
9402 }
9403
9404 USHORT
9405 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9406 {
9407    USHORT flag, length, i;
9408    unsigned char chksum,gotcha;
9409
9410    if(DDCdatatype > 4) return 0xFFFF;  
9411
9412    flag = 0;
9413    SiS_SetSwitchDDC2(SiS_Pr);
9414    if(!(SiS_PrepareDDC(SiS_Pr))) {
9415       length = 127;
9416       if(DDCdatatype != 1) length = 255;
9417       chksum = 0;
9418       gotcha = 0;
9419       for(i=0; i<length; i++) {
9420          buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9421          chksum += buffer[i];
9422          gotcha |= buffer[i];
9423          SiS_SendACK(SiS_Pr, 0);
9424       }
9425       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9426       chksum += buffer[i];
9427       SiS_SendACK(SiS_Pr, 1);
9428       if(gotcha) flag = (USHORT)chksum;
9429       else flag = 0xFFFF;
9430    } else {
9431       flag = 0xFFFF;
9432    }
9433    SiS_SetStop(SiS_Pr);
9434    return(flag);
9435 }
9436
9437 /* Our private DDC functions
9438
9439    It complies somewhat with the corresponding VESA function
9440    in arguments and return values.
9441
9442    Since this is probably called before the mode is changed,
9443    we use our pre-detected pSiS-values instead of SiS_Pr as
9444    regards chipset and video bridge type.
9445
9446    Arguments:
9447        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
9448                  CRT2 DDC is only supported on SiS301, 301B, 302B.
9449        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9450        buffer: ptr to 256 data bytes which will be filled with read data.
9451
9452    Returns 0xFFFF if error, otherwise
9453        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9454        if DDCdatatype = 0:  Returns supported DDC modes
9455
9456  */
9457 USHORT
9458 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9459               USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9460 {
9461    unsigned char sr1f,cr17=1;
9462    USHORT result;
9463
9464    if(adaptnum > 2) return 0xFFFF;
9465    if(DDCdatatype > 4) return 0xFFFF;
9466    if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9467    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9468
9469    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9470    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9471    if(VGAEngine == SIS_300_VGA) {
9472       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9473       if(!cr17) {
9474          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9475          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9476          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9477       }
9478    }
9479    if((sr1f) || (!cr17)) {
9480       SiS_WaitRetrace1(SiS_Pr);
9481       SiS_WaitRetrace1(SiS_Pr);
9482       SiS_WaitRetrace1(SiS_Pr);
9483       SiS_WaitRetrace1(SiS_Pr);
9484    }
9485
9486    if(DDCdatatype == 0) {
9487       result = SiS_ProbeDDC(SiS_Pr);
9488    } else {
9489       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9490    }
9491    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9492    if(VGAEngine == SIS_300_VGA) {
9493       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9494    }
9495    return result;
9496 }
9497
9498 #ifdef LINUX_XF86
9499
9500 static BOOLEAN
9501 checkedid1(unsigned char *buffer)
9502 {
9503    /* Check header */
9504    if((buffer[0] != 0x00) ||
9505       (buffer[1] != 0xff) ||
9506       (buffer[2] != 0xff) ||
9507       (buffer[3] != 0xff) ||
9508       (buffer[4] != 0xff) ||
9509       (buffer[5] != 0xff) ||
9510       (buffer[6] != 0xff) ||
9511       (buffer[7] != 0x00))
9512       return FALSE;
9513
9514    /* Check EDID version and revision */
9515    if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9516
9517    /* Check week of manufacture for sanity */
9518    if(buffer[0x10] > 53) return FALSE;
9519
9520    /* Check year of manufacture for sanity */
9521    if(buffer[0x11] > 40) return FALSE;
9522
9523    return TRUE;
9524 }
9525
9526 static BOOLEAN
9527 checkedid2(unsigned char *buffer)
9528 {
9529    USHORT year = buffer[6] | (buffer[7] << 8);
9530
9531    /* Check EDID version */
9532    if((buffer[0] & 0xf0) != 0x20) return FALSE;
9533
9534    /* Check week of manufacture for sanity */
9535    if(buffer[5] > 53) return FALSE;
9536
9537    /* Check year of manufacture for sanity */
9538    if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9539
9540    return TRUE;
9541 }
9542
9543 /* Sense the LCD parameters (CR36, CR37) via DDC */
9544 /* SiS30x(B) only */
9545 USHORT
9546 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9547 {
9548    USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9549    USHORT index, myindex, lumsize, numcodes;
9550    unsigned char cr37=0, seekcode;
9551    BOOLEAN checkexpand = FALSE;
9552    int retry, i;
9553    unsigned char buffer[256];
9554
9555    for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9556    SiS_Pr->CP_HaveCustomData = FALSE;
9557    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9558    SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9559    SiS_Pr->CP_PreferredIndex = -1;
9560
9561    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9562    if(pSiS->VBFlags & VB_30xBDH) return 0;
9563   
9564    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9565    
9566    SiS_Pr->SiS_DDC_SecAddr = 0x00;
9567    
9568    /* Probe supported DA's */
9569    flag = SiS_ProbeDDC(SiS_Pr);
9570 #ifdef TWDEBUG
9571    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9572         "CRT2 DDC capabilities 0x%x\n", flag);
9573 #endif  
9574    if(flag & 0x10) {
9575       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;        /* EDID V2 (FP) */
9576       DDCdatatype = 4;
9577    } else if(flag & 0x08) {
9578       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;        /* EDID V2 (P&D-D Monitor) */
9579       DDCdatatype = 3;
9580    } else if(flag & 0x02) {
9581       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;        /* EDID V1 */
9582       DDCdatatype = 1;
9583    } else return 0;                             /* no DDC support (or no device attached) */
9584    
9585    /* Read the entire EDID */
9586    retry = 2;
9587    do {
9588       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9589          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9590                 "CRT2: DDC read failed (attempt %d), %s\n",
9591                 (3-retry), (retry == 1) ? "giving up" : "retrying");
9592          retry--;
9593          if(retry == 0) return 0xFFFF;
9594       } else break;
9595    } while(1);
9596
9597 #ifdef TWDEBUG
9598    for(i=0; i<256; i+=16) {
9599        xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9600         "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9601         buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
9602         buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
9603         buffer[i+8],  buffer[i+9], buffer[i+10], buffer[i+11],
9604         buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9605    }
9606 #endif   
9607    
9608    /* Analyze EDID and retrieve LCD panel information */
9609    paneltype = 0;
9610    switch(DDCdatatype) {
9611    case 1:                                                      /* Analyze EDID V1 */
9612       /* Catch a few clear cases: */
9613       if(!(checkedid1(buffer))) {
9614          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9615                 "CRT2: EDID corrupt\n");
9616          return 0;
9617       }
9618
9619       if(!(buffer[0x14] & 0x80)) {
9620          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9621                 "CRT2: Attached display expects analog input (0x%02x)\n",
9622                 buffer[0x14]);
9623          return 0;
9624       }
9625
9626       if((buffer[0x18] & 0x18) != 0x08) {
9627          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9628                 "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
9629                 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9630                   ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9631                      "undefined"),
9632                 buffer[0x18]);
9633          return 0;
9634       }
9635
9636       /* Now analyze the first Detailed Timing Block and see
9637        * if the preferred timing mode is stored there. If so,
9638        * check if this is a standard panel for which we already
9639        * know the timing.
9640        */
9641
9642       paneltype = Panel_Custom;
9643       checkexpand = FALSE;
9644
9645       if(buffer[0x18] & 0x02) {
9646
9647          xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9648          yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9649
9650          SiS_Pr->CP_PreferredX = xres;
9651          SiS_Pr->CP_PreferredY = yres;
9652
9653          switch(xres) {
9654 #if 0       /* Treat as custom */
9655             case 800:
9656                 if(yres == 600) {
9657                    paneltype = Panel_800x600;
9658                    checkexpand = TRUE;
9659                 }
9660                 break;
9661 #endif
9662             case 1024:
9663                 if(yres == 768) {
9664                    paneltype = Panel_1024x768;
9665                    checkexpand = TRUE;
9666                 }
9667                 break;
9668             case 1280:
9669                 if(yres == 1024) {
9670                    paneltype = Panel_1280x1024;
9671                    checkexpand = TRUE;
9672                 } else if(yres == 960) {
9673                    if(pSiS->VGAEngine == SIS_300_VGA) {
9674                       paneltype = Panel300_1280x960;
9675                    } else {
9676                       paneltype = Panel310_1280x960;
9677                    }
9678                 } else if(yres == 768) {
9679                    if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
9680                        ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
9681                        ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
9682                       paneltype = Panel_1280x768;
9683                       checkexpand = FALSE;
9684                       cr37 |= 0x10;
9685                    }
9686                 }
9687                 break;
9688             case 1400:
9689                 if(pSiS->VGAEngine == SIS_315_VGA) {
9690                    if(yres == 1050) {
9691                       paneltype = Panel310_1400x1050;
9692                       checkexpand = TRUE;
9693                    }
9694                 }
9695                 break;
9696 #if 0       /* Treat this as custom, as we have no valid timing data yet */
9697             case 1600:
9698                 if(pSiS->VGAEngine == SIS_315_VGA) {
9699                    if(pSiS->VBFlags & VB_301C) {
9700                       if(yres == 1200) {
9701                          paneltype = Panel310_1600x1200;
9702                          checkexpand = TRUE;
9703                       }
9704                    }
9705                 }
9706                 break;
9707 #endif
9708          }
9709
9710          if(paneltype != Panel_Custom) {
9711             if((buffer[0x47] & 0x18) == 0x18) {
9712                cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9713             } else {
9714                /* What now? There is no digital separate output timing... */
9715                xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9716                    "CRT2: Unable to retrieve Sync polarity information\n");
9717                cr37 |= 0xc0;  /* Default */
9718             }
9719          }
9720
9721       }
9722
9723       /* If we still don't know what panel this is, we take it
9724        * as a custom panel and derive the timing data from the
9725        * detailed timing blocks
9726        */
9727       if(paneltype == Panel_Custom) {
9728
9729          BOOLEAN havesync = FALSE;
9730          int i, temp, base = 0x36;
9731          unsigned long estpack;
9732          unsigned short estx[] = {
9733                 720, 720, 640, 640, 640, 640, 800, 800,
9734                 800, 800, 832,1024,1024,1024,1024,1280,
9735                 1152
9736          };
9737          unsigned short esty[] = {
9738                 400, 400, 480, 480, 480, 480, 600, 600,
9739                 600, 600, 624, 768, 768, 768, 768,1024,
9740                 870
9741          };
9742
9743          paneltype = 0;
9744          SiS_Pr->CP_Supports64048075 = TRUE;
9745
9746          /* Find the maximum resolution */
9747
9748          /* 1. From Established timings */
9749          estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9750          for(i=16; i>=0; i--) {
9751              if(estpack & (1 << i)) {
9752                 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9753                 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9754              }
9755          }
9756
9757          /* 2. From Standard Timings */
9758          for(i=0x26; i < 0x36; i+=2) {
9759             if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9760                temp = (buffer[i] + 31) * 8;
9761                if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9762                switch((buffer[i+1] & 0xc0) >> 6) {
9763                case 0x03: temp = temp * 9 / 16; break;
9764                case 0x02: temp = temp * 4 / 5;  break;
9765                case 0x01: temp = temp * 3 / 4;  break;
9766                }
9767                if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9768             }
9769          }
9770
9771          /* Now extract the Detailed Timings and convert them into modes */
9772
9773          for(i = 0; i < 4; i++, base += 18) {
9774
9775             /* Is this a detailed timing block or a monitor descriptor? */
9776             if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9777
9778                xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9779                yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
9780
9781                SiS_Pr->CP_HDisplay[i] = xres;
9782                SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
9783                SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
9784                SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
9785                SiS_Pr->CP_HBlankStart[i] = xres + 1;
9786                SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
9787
9788                SiS_Pr->CP_VDisplay[i] = yres;
9789                SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
9790                SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
9791                SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
9792                SiS_Pr->CP_VBlankStart[i] = yres + 1;
9793                SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
9794
9795                SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
9796
9797                SiS_Pr->CP_DataValid[i] = TRUE;
9798
9799                /* Sort out invalid timings, interlace and too high clocks */
9800                if((SiS_Pr->CP_HDisplay[i] & 7)                                          ||
9801                   (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])                   ||
9802                   (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])                    ||
9803                   (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])                      ||
9804                   (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i])                  ||
9805                   (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])                     ||
9806                   (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])                       ||
9807                   (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])                   ||
9808                   (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])                    ||
9809                   (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])                      ||
9810                   (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])                   ||
9811                   (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])                     ||
9812                   (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])                       ||
9813                   (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
9814                    ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))    ||
9815                   (buffer[base+17] & 0x80)) {
9816
9817                   SiS_Pr->CP_DataValid[i] = FALSE;
9818
9819                } else {
9820
9821                   paneltype = Panel_Custom;
9822
9823                   SiS_Pr->CP_HaveCustomData = TRUE;
9824
9825                   if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
9826                   if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
9827                   if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
9828
9829                   if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
9830                      SiS_Pr->CP_PreferredIndex = i;
9831                   }
9832
9833                   SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
9834                   SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
9835
9836                   /* By default we drive the LCD at 75Hz in 640x480 mode; if
9837                    * the panel does not provide this mode, use 60hz
9838                    */
9839                   if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9840
9841                   /* We must assume the panel can scale, since we have
9842                    * no scaling data
9843                    */
9844                   checkexpand = FALSE;
9845                   cr37 |= 0x10;
9846
9847                   /* Extract the sync polarisation information. This only works
9848                    * if the Flags indicate a digital separate output.
9849                    */
9850                   if((buffer[base+17] & 0x18) == 0x18) {
9851                      SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
9852                      SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
9853                      SiS_Pr->CP_SyncValid[i] = TRUE;
9854                      if(!havesync) {
9855                         cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
9856                         havesync = TRUE;
9857                      }
9858                   } else {
9859                      SiS_Pr->CP_SyncValid[i] = FALSE;
9860                   }
9861                }
9862             }
9863          }
9864          if(!havesync) {
9865             xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9866                    "CRT2: Unable to retrieve Sync polarity information\n");
9867          }
9868       }
9869
9870       if(paneltype && checkexpand) {
9871          /* If any of the Established low-res modes is supported, the
9872           * panel can scale automatically. For 800x600 panels, we only 
9873           * check the even lower ones.
9874           */
9875          if(paneltype == Panel_800x600) {
9876             if(buffer[0x23] & 0xfc) cr37 |= 0x10;
9877          } else {
9878             if(buffer[0x23])        cr37 |= 0x10;
9879          }
9880       }
9881        
9882       break;
9883       
9884    case 3:                                                      /* Analyze EDID V2 */
9885    case 4:
9886       index = 0;
9887
9888       if(!(checkedid2(buffer))) {
9889          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9890                 "CRT2: EDID corrupt\n");
9891          return 0;
9892       }
9893
9894       if((buffer[0x41] & 0x0f) == 0x03) {
9895          index = 0x42 + 3;
9896          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9897                 "CRT2: Display supports TMDS input on primary interface\n");
9898       } else if((buffer[0x41] & 0xf0) == 0x30) {
9899          index = 0x46 + 3;
9900          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9901                 "CRT2: Display supports TMDS input on secondary interface\n");
9902       } else {
9903          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9904                 "CRT2: Display does not support TMDS video interface (0x%02x)\n", 
9905                 buffer[0x41]);
9906          return 0;
9907       }
9908
9909       paneltype = Panel_Custom;
9910       SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
9911       SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
9912       switch(xres) {
9913 #if 0
9914          case 800:
9915              if(yres == 600) {
9916                 paneltype = Panel_800x600;
9917                 checkexpand = TRUE;
9918              }
9919              break;
9920 #endif
9921          case 1024:
9922              if(yres == 768) {
9923                 paneltype = Panel_1024x768;
9924                 checkexpand = TRUE;
9925              }
9926              break;
9927          case 1280:
9928              if(yres == 960) {
9929                 if(pSiS->VGAEngine == SIS_315_VGA) {
9930                    paneltype = Panel310_1280x960;
9931                 } else {
9932                    paneltype = Panel300_1280x960;
9933                 }
9934              } else if(yres == 1024) {
9935                 paneltype = Panel_1280x1024;
9936                 checkexpand = TRUE;
9937              }
9938              /* 1280x768 treated as custom here */
9939              break;
9940          case 1400:
9941              if(pSiS->VGAEngine == SIS_315_VGA) {
9942                 if(yres == 1050) {
9943                    paneltype = Panel310_1400x1050;
9944                    checkexpand = TRUE;
9945                 }
9946              }
9947              break;
9948 #if 0    /* Treat this one as custom since we have no timing data yet */
9949          case 1600:
9950              if(pSiS->VGAEngine == SIS_315_VGA) {
9951                 if(pSiS->VBFlags & VB_301C) {
9952                    if(yres == 1200) {
9953                       paneltype = Panel310_1600x1200;
9954                       checkexpand = TRUE;
9955                    }
9956                 }
9957              }
9958              break;
9959 #endif
9960       }
9961
9962       /* Determine if RGB18 or RGB24 */
9963       if(index) {
9964          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
9965             cr37 |= 0x01;
9966          }
9967       }
9968
9969       if(checkexpand) {
9970          /* TODO - for now, we let the panel scale */
9971          cr37 |= 0x10;
9972       }
9973
9974       /* Now seek 4-Byte Timing codes and extract sync pol info */
9975       index = 0x80;
9976       if(buffer[0x7e] & 0x20) {                     /* skip Luminance Table (if provided) */
9977          lumsize = buffer[0x80] & 0x1f;
9978          if(buffer[0x80] & 0x80) lumsize *= 3;
9979          lumsize++;  /* luminance header byte */
9980          index += lumsize;
9981       }
9982       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
9983       index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
9984       numcodes = (buffer[0x7f] & 0xf8) >> 3;
9985       if(numcodes) {
9986          myindex = index;
9987          seekcode = (xres - 256) / 16;
9988          for(i=0; i<numcodes; i++) {
9989             if(buffer[myindex] == seekcode) break;
9990             myindex += 4;
9991          }
9992          if(buffer[myindex] == seekcode) {
9993             cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
9994          } else {
9995             xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9996                 "CRT2: Unable to retrieve Sync polarity information\n");
9997          }
9998       } else {
9999          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10000              "CRT2: Unable to retrieve Sync polarity information\n");
10001       }
10002
10003       /* Now seek the detailed timing descriptions for custom panels */
10004       if(paneltype == Panel_Custom) {
10005
10006          SiS_Pr->CP_Supports64048075 = TRUE;
10007
10008          index += (numcodes * 4);
10009          numcodes = buffer[0x7f] & 0x07;
10010          for(i=0; i<numcodes; i++, index += 18) {
10011             xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10012             yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10013
10014             SiS_Pr->CP_HDisplay[i] = xres;
10015             SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10016             SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10017             SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10018             SiS_Pr->CP_HBlankStart[i] = xres + 1;
10019             SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10020
10021             SiS_Pr->CP_VDisplay[i] = yres;
10022             SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10023             SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10024             SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10025             SiS_Pr->CP_VBlankStart[i] = yres + 1;
10026             SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10027
10028             SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10029
10030             SiS_Pr->CP_DataValid[i] = TRUE;
10031
10032             if((SiS_Pr->CP_HDisplay[i] & 7)                                             ||
10033                (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])                      ||
10034                (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])                       ||
10035                (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])                         ||
10036                (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i])                     ||
10037                (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])                        ||
10038                (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])                          ||
10039                (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])                      ||
10040                (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])                       ||
10041                (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])                         ||
10042                (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])                      ||
10043                (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])                        ||
10044                (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])                          ||
10045                (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10046                 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))       ||
10047                (buffer[index + 17] & 0x80)) {
10048
10049                SiS_Pr->CP_DataValid[i] = FALSE;
10050
10051             } else {
10052
10053                SiS_Pr->CP_HaveCustomData = TRUE;
10054
10055                if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10056
10057                if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
10058                   SiS_Pr->CP_PreferredIndex = i;
10059                }
10060
10061                SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10062                SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10063                SiS_Pr->CP_SyncValid[i] = TRUE;
10064
10065                SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10066                SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10067
10068                /* We must assume the panel can scale, since we have
10069                 * no scaling data
10070                 */
10071                cr37 |= 0x10;
10072
10073             }
10074          }
10075
10076       }
10077
10078       break;
10079
10080    }
10081
10082    /* 1280x960 panels are always RGB24, unable to scale and use
10083     * high active sync polarity
10084     */
10085    if(pSiS->VGAEngine == SIS_315_VGA) {
10086       if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10087    } else {
10088       if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10089    }
10090
10091    for(i = 0; i < 7; i++) {
10092       if(SiS_Pr->CP_DataValid[i]) {
10093          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10094             "Non-standard LCD timing data no. %d:\n", i);
10095          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10096             "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10097             SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10098             SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10099          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10100             "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10101             SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10102             SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10103          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10104             "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10105          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10106             "   To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10107             SiS_Pr->CP_HDisplay[i],
10108             SiS_Pr->CP_VDisplay[i]);
10109       }
10110    }
10111
10112    if(paneltype) {
10113        if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10114        if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10115        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10116        SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10117        cr37 &= 0xf1;
10118        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10119        SiS_Pr->PanelSelfDetected = TRUE;
10120 #ifdef TWDEBUG
10121        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
10122            "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10123 #endif  
10124    } else {
10125        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10126        SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10127    }
10128    return 0;
10129 }
10130    
10131 USHORT
10132 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10133 {
10134    USHORT DDCdatatype,flag;
10135    BOOLEAN foundcrt = FALSE;
10136    int retry;
10137    unsigned char buffer[256];
10138
10139    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10140
10141    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10142    
10143    SiS_Pr->SiS_DDC_SecAddr = 0x00;
10144    
10145    /* Probe supported DA's */
10146    flag = SiS_ProbeDDC(SiS_Pr);
10147    if(flag & 0x10) {
10148       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;        /* EDID V2 (FP) */
10149       DDCdatatype = 4;
10150    } else if(flag & 0x08) {
10151       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;        /* EDID V2 (P&D-D Monitor) */
10152       DDCdatatype = 3;
10153    } else if(flag & 0x02) {
10154       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;        /* EDID V1 */
10155       DDCdatatype = 1;
10156    } else {
10157         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10158                 "Do DDC answer\n");
10159         return 0;                               /* no DDC support (or no device attached) */
10160    }
10161
10162    /* Read the entire EDID */
10163    retry = 2;
10164    do {
10165       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10166          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10167                 "CRT2: DDC read failed (attempt %d), %s\n",
10168                 (3-retry), (retry == 1) ? "giving up" : "retrying");
10169          retry--;
10170          if(retry == 0) return 0xFFFF;
10171       } else break;
10172    } while(1);
10173
10174    /* Analyze EDID. We don't have many chances to
10175     * distinguish a flat panel from a CRT...
10176     */
10177    switch(DDCdatatype) {
10178    case 1:
10179       if(!(checkedid1(buffer))) {
10180           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10181                 "CRT2: EDID corrupt\n");
10182           return 0;
10183       }
10184       if(buffer[0x14] & 0x80) {                 /* Display uses digital input */
10185           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10186                 "CRT2: Attached display expects digital input\n");
10187           return 0;
10188       }
10189       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10190       SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10191       foundcrt = TRUE;
10192       break;
10193    case 3:
10194    case 4:
10195       if(!(checkedid2(buffer))) {
10196           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10197                 "CRT2: EDID corrupt\n");
10198           return 0;
10199       }
10200       if( ((buffer[0x41] & 0x0f) != 0x01) &&    /* Display does not support analog input */
10201           ((buffer[0x41] & 0x0f) != 0x02) &&
10202           ((buffer[0x41] & 0xf0) != 0x10) &&
10203           ((buffer[0x41] & 0xf0) != 0x20) ) {
10204           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10205                 "CRT2: Attached display does not support analog input (0x%02x)\n",
10206                 buffer[0x41]);
10207           return 0;
10208       }
10209       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10210       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10211       foundcrt = TRUE;
10212       break;
10213    }
10214
10215    if(foundcrt) {
10216       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10217    }
10218    return(0);
10219 }
10220
10221 #endif
10222
10223 void
10224 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10225 {
10226   USHORT tempbl;
10227
10228   tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10229   tempbl = (((tempbl & tempbh) << 8) | tempax);
10230   SiS_SetCH70xx(SiS_Pr,tempbl);
10231 }
10232
10233 /* Generic I2C functions for Chrontel & DDC --------- */
10234
10235 void
10236 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10237 {
10238   SiS_SetSCLKHigh(SiS_Pr);
10239   SiS_WaitRetrace1(SiS_Pr);
10240
10241   SiS_SetSCLKLow(SiS_Pr);
10242   SiS_WaitRetrace1(SiS_Pr);
10243 }
10244
10245 USHORT
10246 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10247 {
10248    SiS_WaitRetrace1(SiS_Pr);
10249    return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10250 }
10251
10252 /* Set I2C start condition */
10253 /* This is done by a SD high-to-low transition while SC is high */
10254 USHORT
10255 SiS_SetStart(SiS_Private *SiS_Pr)
10256 {
10257   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                                /* (SC->low)  */
10258   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10259                   SiS_Pr->SiS_DDC_Index,
10260                   SiS_Pr->SiS_DDC_NData,
10261                   SiS_Pr->SiS_DDC_Data);                                   /* SD->high */
10262   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* SC->high */
10263   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10264                   SiS_Pr->SiS_DDC_Index,
10265                   SiS_Pr->SiS_DDC_NData,
10266                   0x00);                                                   /* SD->low = start condition */
10267   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* (SC->low) */
10268   return 0;
10269 }
10270
10271 /* Set I2C stop condition */
10272 /* This is done by a SD low-to-high transition while SC is high */
10273 USHORT
10274 SiS_SetStop(SiS_Private *SiS_Pr)
10275 {
10276   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                                /* (SC->low) */
10277   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10278                   SiS_Pr->SiS_DDC_Index,
10279                   SiS_Pr->SiS_DDC_NData,
10280                   0x00);                                                   /* SD->low   */
10281   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* SC->high  */
10282   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10283                   SiS_Pr->SiS_DDC_Index,
10284                   SiS_Pr->SiS_DDC_NData,
10285                   SiS_Pr->SiS_DDC_Data);                                   /* SD->high = stop condition */
10286   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                               /* (SC->high) */
10287   return 0;
10288 }
10289
10290 /* Write 8 bits of data */
10291 USHORT
10292 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10293 {
10294   USHORT i,flag,temp;
10295
10296   flag = 0x80;
10297   for(i=0; i<8; i++) {
10298     SiS_SetSCLKLow(SiS_Pr);                                                   /* SC->low */
10299     if(tempax & flag) {
10300       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10301                       SiS_Pr->SiS_DDC_Index,
10302                       SiS_Pr->SiS_DDC_NData,
10303                       SiS_Pr->SiS_DDC_Data);                                  /* Write bit (1) to SD */
10304     } else {
10305       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10306                       SiS_Pr->SiS_DDC_Index,
10307                       SiS_Pr->SiS_DDC_NData,
10308                       0x00);                                                  /* Write bit (0) to SD */
10309     }
10310     SiS_SetSCLKHigh(SiS_Pr);                                                  /* SC->high */
10311     flag >>= 1;
10312   }
10313   temp = SiS_CheckACK(SiS_Pr);                                                /* Check acknowledge */
10314   return(temp);
10315 }
10316
10317 USHORT
10318 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10319 {
10320   USHORT i,temp,getdata;
10321
10322   getdata=0;
10323   for(i=0; i<8; i++) {
10324     getdata <<= 1;
10325     SiS_SetSCLKLow(SiS_Pr);
10326     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10327                     SiS_Pr->SiS_DDC_Index,
10328                     SiS_Pr->SiS_DDC_NData,
10329                     SiS_Pr->SiS_DDC_Data);
10330     SiS_SetSCLKHigh(SiS_Pr);
10331     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10332     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10333   }
10334   return(getdata);
10335 }
10336
10337 USHORT
10338 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10339 {
10340   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10341                   SiS_Pr->SiS_DDC_Index,
10342                   SiS_Pr->SiS_DDC_NClk,
10343                   0x00);                                        /* SetSCLKLow()  */
10344   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10345   return 0;
10346 }
10347
10348 USHORT
10349 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10350 {
10351   USHORT temp, watchdog=1000;
10352
10353   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10354                   SiS_Pr->SiS_DDC_Index,
10355                   SiS_Pr->SiS_DDC_NClk,
10356                   SiS_Pr->SiS_DDC_Clk);                         /* SetSCLKHigh()  */
10357   do {
10358     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10359   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10360   if (!watchdog) {
10361 #ifdef TWDEBUG
10362         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10363 #endif
10364         return 0xFFFF;
10365   }
10366   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10367   return 0;
10368 }
10369
10370 /* Check I2C acknowledge */
10371 /* Returns 0 if ack ok, non-0 if ack not ok */
10372 USHORT
10373 SiS_CheckACK(SiS_Private *SiS_Pr)
10374 {
10375   USHORT tempah;
10376
10377   SiS_SetSCLKLow(SiS_Pr);                                          /* (SC->low) */
10378   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10379                   SiS_Pr->SiS_DDC_Index,
10380                   SiS_Pr->SiS_DDC_NData,
10381                   SiS_Pr->SiS_DDC_Data);                           /* (SD->high) */
10382   SiS_SetSCLKHigh(SiS_Pr);                                         /* SC->high = clock impulse for ack */
10383   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10384   SiS_SetSCLKLow(SiS_Pr);                                          /* SC->low = end of clock impulse */
10385   if(tempah & SiS_Pr->SiS_DDC_Data) return(1);                     /* Ack OK if bit = 0 */
10386   else return(0);
10387 }
10388
10389 /* End of I2C functions ----------------------- */
10390
10391
10392 /* =============== SiS 315/330 O.E.M. ================= */
10393
10394 #ifdef SIS315H
10395
10396 static USHORT
10397 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10398 {
10399   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10400   USHORT romptr;
10401
10402   if(HwInfo->jChipType < SIS_330) {
10403      romptr = SISGETROMW(0x128);
10404      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10405         romptr = SISGETROMW(0x12a);
10406   } else {
10407      romptr = SISGETROMW(0x1a8);
10408      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10409         romptr = SISGETROMW(0x1aa);
10410   }
10411   return(romptr);
10412 }
10413
10414 static USHORT
10415 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10416 {
10417   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10418   USHORT romptr;
10419
10420   if(HwInfo->jChipType < SIS_330) {
10421      romptr = SISGETROMW(0x120);
10422      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10423         romptr = SISGETROMW(0x122);
10424   } else {
10425      romptr = SISGETROMW(0x1a0);
10426      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10427         romptr = SISGETROMW(0x1a2);
10428   }
10429   return(romptr);
10430 }
10431
10432 static USHORT
10433 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10434 {
10435   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10436   USHORT romptr;
10437
10438   if(HwInfo->jChipType < SIS_330) {
10439      romptr = SISGETROMW(0x114);
10440      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10441         romptr = SISGETROMW(0x11a);
10442   } else {
10443      romptr = SISGETROMW(0x194);
10444      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10445         romptr = SISGETROMW(0x19a);
10446   }
10447   return(romptr);
10448 }
10449
10450 static USHORT
10451 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10452 {
10453   USHORT index;
10454
10455   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10456      if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10457         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10458            index >>= 4;
10459            index *= 3;
10460            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10461            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10462            return index;
10463         }
10464      }
10465   }
10466
10467   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10468   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
10469   else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10470   index--;
10471   index *= 3;
10472   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10473   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10474   return index;
10475 }
10476
10477 static USHORT
10478 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10479 {
10480   USHORT index;
10481
10482   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10483   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
10484   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10485   return index;
10486 }
10487
10488 static USHORT
10489 GetTVPtrIndex(SiS_Private *SiS_Pr)
10490 {
10491   USHORT index;
10492
10493   index = 0;
10494   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10495   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10496
10497   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10498
10499   index <<= 1;
10500
10501   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10502      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10503      index++;
10504   }
10505
10506   return index;
10507 }
10508
10509 static ULONG
10510 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10511 {
10512    USHORT index = 0, temp = 0;
10513
10514    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
10515    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
10516    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
10517    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10518    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10519       index = 4;
10520       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
10521       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10522    }
10523
10524    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10525       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10526          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10527          index += addme;
10528          temp++;
10529       }
10530       temp += 0x0100;
10531    }
10532    return(ULONG)(index | (temp << 16));
10533 }
10534
10535 static ULONG
10536 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10537 {
10538    return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10539 }
10540
10541 #if 0
10542 static ULONG
10543 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10544 {
10545    return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10546 }
10547 #endif
10548
10549 static int
10550 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10551 {
10552    int index = 0;
10553
10554    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
10555    if(SiS_Pr->SiS_ROMNew) {
10556       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10557       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10558       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10559       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
10560    } else {
10561       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
10562       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10563       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10564       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10565    }
10566
10567    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10568
10569    return index;
10570 }
10571
10572 static void
10573 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10574 {
10575   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10576   USHORT delay=0,index,myindex,temp,romptr=0;
10577   BOOLEAN dochiptest = TRUE;
10578
10579   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10580      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10581   } else {
10582      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10583   }
10584
10585   /* Find delay (from ROM, internal tables, PCI subsystem) */
10586
10587   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {                    /* ------------ VGA */
10588      
10589      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10590         romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10591      }
10592      if(romptr) delay = ROMAddr[romptr];
10593      else {
10594         delay = 0x04;
10595         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10596            if(IS_SIS650) {
10597               delay = 0x0a;
10598            } else if(IS_SIS740) {
10599               delay = 0x00;
10600            } else if(HwInfo->jChipType < SIS_330) {
10601               delay = 0x0c;
10602            } else {
10603               delay = 0x0c;
10604            }
10605         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10606            delay = 0x00;
10607         }
10608      }
10609
10610   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ---------- LCD/LCDA */
10611
10612      BOOLEAN gotitfrompci = FALSE;
10613
10614      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10615
10616      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10617         if(SiS_Pr->PDC != -1) {
10618            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10619            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10620            return;
10621         }
10622      } else {
10623         if(SiS_Pr->PDCA != -1) {
10624            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10625            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10626            return;
10627         }
10628      }
10629
10630      /* Custom Panel? */
10631
10632      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10633         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10634            delay = 0x00;
10635            if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10636               delay = 0x20;
10637            }
10638            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10639         } else {
10640            delay = 0x0c;
10641            if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10642            else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10643               if(IS_SIS740) delay = 0x01;
10644               else          delay = 0x03;
10645            }
10646            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10647         }
10648         return;
10649      }
10650
10651      /* This is a piece of typical SiS crap: They code the OEM LCD
10652       * delay into the code, at no defined place in the BIOS.
10653       * We now have to start doing a PCI subsystem check here.
10654       */
10655
10656      switch(SiS_Pr->SiS_CustomT) {
10657      case CUT_COMPAQ1280:
10658      case CUT_COMPAQ12802:
10659         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10660            gotitfrompci = TRUE;
10661            dochiptest = FALSE;
10662            delay = 0x03;
10663         }
10664         break;
10665      case CUT_CLEVO1400:
10666      case CUT_CLEVO14002:
10667         gotitfrompci = TRUE;
10668         dochiptest = FALSE;
10669         delay = 0x02;
10670         break;
10671      case CUT_CLEVO1024:
10672      case CUT_CLEVO10242:
10673         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10674            gotitfrompci = TRUE;
10675            dochiptest = FALSE;
10676            delay = 0x33;
10677            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10678            delay &= 0x0f;
10679         }
10680         break;
10681      }
10682
10683      /* Could we find it through the PCI ID? If no, use ROM or table */
10684
10685      if(!gotitfrompci) {
10686
10687         index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10688         myindex = GetLCDPtrIndex(SiS_Pr);
10689
10690         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10691
10692            if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10693
10694               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10695                  /* Always use the second pointer on 650; some BIOSes */
10696                  /* still carry old 301 data at the first location    */
10697                  /* romptr = SISGETROMW(0x120);                       */
10698                  /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10699                  romptr = SISGETROMW(0x122);
10700                  if(!romptr) return;
10701                  delay = ROMAddr[(romptr + index)];
10702               } else {
10703                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10704               }
10705
10706           } else {
10707
10708              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10709              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10710                 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10711
10712           }
10713
10714         } else if(SiS_Pr->SiS_UseROM                          &&
10715                   (!(SiS_Pr->SiS_ROMNew))                     &&
10716                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10717                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10718                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10719
10720            /* Data for 1280x1024 wrong in 301B BIOS */
10721            romptr = GetLCDromptr(SiS_Pr, HwInfo);
10722            if(!romptr) return;
10723            delay = ROMAddr[(romptr + index)];
10724
10725         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10726
10727            if(IS_SIS740) delay = 0x03;
10728            else          delay = 0x00;
10729
10730         } else {
10731
10732            delay = SiS310_LCDDelayCompensation_301[myindex];
10733            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10734               if(IS_SIS740) delay = 0x01;
10735               else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10736               else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10737            } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10738               if(IS_SIS740) delay = 0x01;  /* ? */
10739               else          delay = 0x03;
10740            } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10741               if(IS_SIS740) delay = 0x01;
10742               else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10743            }
10744
10745         }
10746
10747      }  /* got it from PCI */
10748
10749      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10750         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10751         dochiptest = FALSE;
10752      }
10753      
10754   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /* ------------ TV */
10755
10756      index = GetTVPtrIndex(SiS_Pr);
10757      
10758      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10759
10760         if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
10761
10762            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10763               /* Always use the second pointer on 650; some BIOSes */
10764               /* still carry old 301 data at the first location    */
10765               /* romptr = SISGETROMW(0x114);                       */
10766               /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10767               romptr = SISGETROMW(0x11a);
10768               if(!romptr) return;
10769               delay = ROMAddr[romptr + index];
10770
10771            } else {
10772
10773               delay = SiS310_TVDelayCompensation_301B[index];
10774
10775            }
10776
10777         } else {
10778
10779            switch(SiS_Pr->SiS_CustomT) {
10780            case CUT_COMPAQ1280:
10781            case CUT_COMPAQ12802:
10782            case CUT_CLEVO1400:
10783            case CUT_CLEVO14002:
10784               delay = 0x02;
10785               dochiptest = FALSE;
10786               break;
10787            case CUT_CLEVO1024:
10788            case CUT_CLEVO10242:
10789               delay = 0x03;
10790               dochiptest = FALSE;
10791               break;
10792            default:
10793               delay = SiS310_TVDelayCompensation_651301LV[index];
10794               if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10795                  delay = SiS310_TVDelayCompensation_651302LV[index];
10796               }
10797            }
10798         }
10799
10800      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10801
10802         romptr = GetTVromptr(SiS_Pr, HwInfo);
10803         if(!romptr) return;
10804         delay = ROMAddr[romptr + index];
10805
10806      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10807
10808         delay = SiS310_TVDelayCompensation_LVDS[index];
10809
10810      } else {
10811
10812         delay = SiS310_TVDelayCompensation_301[index];
10813         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10814            if(IS_SIS740) {
10815               delay = SiS310_TVDelayCompensation_740301B[index];
10816               /* LV: use 301 data? BIOS bug? */
10817            } else {
10818               delay = SiS310_TVDelayCompensation_301B[index];
10819               if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10820            }
10821         }
10822
10823      }
10824
10825      if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
10826         delay &= 0x0f;
10827         dochiptest = FALSE;
10828      }
10829     
10830   } else return;
10831
10832   /* Write delay */
10833
10834   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10835
10836      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
10837
10838         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10839         if(temp == 8) {         /* 1400x1050 BIOS (COMPAL) */
10840            delay &= 0x0f;
10841            delay |= 0xb0;
10842         } else if(temp == 6) {
10843            delay &= 0x0f;
10844            delay |= 0xc0;
10845         } else if(temp > 7) {   /* 1280x1024 BIOS (which one?) */
10846            delay = 0x35;
10847         }
10848         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10849
10850      } else {
10851
10852         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10853
10854      }
10855
10856   } else {  /* LVDS */
10857
10858      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10859         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10860      } else {
10861         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10862            delay <<= 4;
10863            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10864         } else {
10865            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10866         }
10867      }
10868
10869   }
10870
10871 }
10872
10873 static void
10874 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10875                USHORT ModeNo,USHORT ModeIdIndex)
10876 {
10877   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10878   USHORT index,temp,temp1,romptr=0;
10879
10880   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10881
10882   if(ModeNo<=0x13)
10883      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10884   else
10885      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10886
10887   temp = GetTVPtrIndex(SiS_Pr);
10888   temp >>= 1;     /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10889   temp1 = temp;
10890
10891   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10892      if(HwInfo->jChipType >= SIS_661) {
10893         temp1 = GetOEMTVPtr661(SiS_Pr);
10894         temp1 >>= 1;
10895         romptr = SISGETROMW(0x260);
10896         if(HwInfo->jChipType >= SIS_760) {
10897            romptr = SISGETROMW(0x360);
10898         }
10899      } else if(HwInfo->jChipType >= SIS_330) {
10900         romptr = SISGETROMW(0x192);
10901      } else {
10902         romptr = SISGETROMW(0x112);
10903      }
10904   }
10905
10906   if(romptr) {
10907      temp1 <<= 1;
10908      temp = ROMAddr[romptr + temp1 + index];
10909   } else {
10910      temp = SiS310_TVAntiFlick1[temp][index];
10911   }
10912   temp <<= 4;
10913
10914   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10915 }
10916
10917 static void
10918 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10919                USHORT ModeNo,USHORT ModeIdIndex)
10920 {
10921   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10922   USHORT index,temp,temp1,romptr=0;
10923
10924   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1;    /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10925
10926   if(ModeNo <= 0x13)
10927      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10928   else
10929      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10930
10931   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10932      if(HwInfo->jChipType >= SIS_661) {
10933         romptr = SISGETROMW(0x26c);
10934         if(HwInfo->jChipType >= SIS_760) {
10935            romptr = SISGETROMW(0x36c);
10936         }
10937         temp1 = GetOEMTVPtr661(SiS_Pr);
10938         temp1 >>= 1;
10939      } else if(HwInfo->jChipType >= SIS_330) {
10940         romptr = SISGETROMW(0x1a4);
10941      } else {
10942         romptr = SISGETROMW(0x124);
10943      }
10944   }
10945
10946   if(romptr) {
10947      temp1 <<= 1;
10948      temp = ROMAddr[romptr + temp1 + index];
10949   } else {
10950      temp = SiS310_TVEdge1[temp][index];
10951   }
10952   temp <<= 5;
10953   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10954 }
10955
10956 static void
10957 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10958            USHORT ModeNo,USHORT ModeIdIndex)
10959 {
10960   USHORT index, temp, i, j;
10961
10962   if(ModeNo <= 0x13) {
10963      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10964   } else {
10965      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10966   }
10967
10968   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10969
10970   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)        temp = 1;  /* NTSC-J uses PAL */
10971   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10972   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10973   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10974
10975   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10976      for(i=0x35, j=0; i<=0x38; i++, j++) {
10977         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10978      }
10979      for(i=0x48; i<=0x4A; i++, j++) {
10980         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10981      }
10982   } else {
10983      for(i=0x35, j=0; i<=0x38; i++, j++) {
10984         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10985      }
10986   }
10987 }
10988
10989 static void
10990 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10991              USHORT ModeNo,USHORT ModeIdIndex)
10992 {
10993   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10994   USHORT index,temp,i,j,resinfo,romptr=0;
10995   ULONG  lindex;
10996
10997   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10998
10999   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11000   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11001
11002   if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11003      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11004      lindex <<= 2;
11005      for(j=0, i=0x31; i<=0x34; i++, j++) {
11006         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11007      }
11008      return;
11009   }
11010
11011   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11012   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11013
11014   if(ModeNo<=0x13) {
11015      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11016   } else {
11017      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11018   }
11019
11020   temp = GetTVPtrIndex(SiS_Pr);
11021   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
11022    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
11023    */
11024   if(SiS_Pr->SiS_UseROM) {
11025      romptr = SISGETROMW(0x116);
11026      if(HwInfo->jChipType >= SIS_330) {
11027         romptr = SISGETROMW(0x196);
11028      }
11029      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11030         romptr = SISGETROMW(0x11c);
11031         if(HwInfo->jChipType >= SIS_330) {
11032            romptr = SISGETROMW(0x19c);
11033         }
11034         if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11035            romptr = SISGETROMW(0x116);
11036            if(HwInfo->jChipType >= SIS_330) {
11037               romptr = SISGETROMW(0x196);
11038            }
11039         }
11040      }
11041   }
11042   if(romptr) {
11043      romptr += (temp << 2);
11044      for(j=0, i=0x31; i<=0x34; i++, j++) {
11045         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11046      }
11047   } else {
11048      index = temp % 2;
11049      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
11050      for(j=0, i=0x31; i<=0x34; i++, j++) {
11051         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11052            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11053         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11054            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11055         else
11056            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11057      }
11058   }
11059
11060   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11061      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11062         if((resinfo == SIS_RI_640x480) ||
11063            (resinfo == SIS_RI_800x600)) {
11064            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11065            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11066            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11067            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11068         } else if(resinfo == SIS_RI_1024x768) {
11069            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11070            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11071            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11072            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11073         }
11074      }
11075   }
11076 }
11077
11078 void
11079 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11080                   USHORT ModeNo,USHORT ModeIdIndex)
11081 {
11082    SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11083
11084    if(SiS_Pr->UseCustomMode) return;
11085
11086    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11087       SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11088       SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11089       SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11090       if(SiS_Pr->SiS_VBType & VB_SIS301) {
11091          SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11092       }
11093    }
11094 }
11095
11096 static void
11097 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11098                 USHORT ModeIdIndex, USHORT RTI)
11099 {
11100    USHORT delay = 0, romptr = 0, index;
11101    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11102
11103    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11104       return;
11105
11106    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11107
11108    if(SiS_Pr->SiS_ROMNew) {
11109       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)                         ||
11110          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11111           (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11112          index = 25;
11113          if(SiS_Pr->UseCustomMode) {
11114             index = SiS_Pr->CSRClock;
11115          } else if(ModeNo > 0x13) {
11116             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11117             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11118          }
11119          if(index < 25) index = 25;
11120          index = ((index / 25) - 1) << 1;
11121          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11122             index++;
11123          }
11124          romptr = SISGETROMW(0x104);  /* 0x4ae */
11125          delay = ROMAddr[romptr + index];
11126          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11127             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11128             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11129          } else {
11130             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11131             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11132          }
11133          return;
11134       }
11135    }
11136
11137    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11138
11139    if(SiS_Pr->UseCustomMode) delay = 0x04;
11140    else if(ModeNo <= 0x13)   delay = 0x04;
11141    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11142    delay |= (delay << 8);
11143
11144    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11145
11146       /* 3. TV */
11147
11148       index = GetOEMTVPtr661(SiS_Pr);
11149       if(SiS_Pr->SiS_ROMNew) {
11150          romptr = SISGETROMW(0x106);  /* 0x4ba */
11151          delay = ROMAddr[romptr + index];
11152       } else {
11153          delay = 0x04;
11154       }
11155
11156    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11157
11158       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11159
11160       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11161           ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11162
11163          /* For LV, the BIOS must know about the correct value */
11164          delay = ROMAddr[romptr + 0x0d];                /* LCD  */
11165          delay |= (ROMAddr[romptr + 0x0c] << 8);        /* LCDA */
11166
11167       } else {
11168
11169          /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
11170          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11171             if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11172                delay = 0x0404;
11173             } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
11174                delay = 0x0404;
11175             } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11176                delay = 0x1004;
11177             } else
11178                delay = 0x0000;
11179          }
11180
11181          /* Override by detected or user-set values */
11182          /* (but only if, for some reason, we can't read value from BIOS) */
11183          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11184             delay = SiS_Pr->PDC & 0x1f;
11185          }
11186          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11187             delay = (SiS_Pr->PDCA & 0x1f) << 8;
11188          }
11189
11190       }
11191
11192    }
11193
11194    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11195       delay >>= 8;
11196       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11197       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11198    } else {
11199       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11200       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11201    }
11202 }
11203
11204 static void
11205 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11206 {
11207    USHORT infoflag;
11208    UCHAR temp;
11209
11210    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11211
11212       if(ModeNo <= 0x13) {
11213          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11214       } else if(SiS_Pr->UseCustomMode) {
11215          infoflag = SiS_Pr->CInfoFlag;
11216       } else {
11217          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11218       }
11219       infoflag &= 0xc0;
11220
11221       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
11222       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
11223          temp &= 0x3f;
11224          temp |= infoflag;
11225       } else {
11226          if(temp & 0x20) infoflag = temp;
11227       }
11228       if(temp & 0x01) infoflag |= 0x01;
11229
11230       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11231          temp = 0x0c;
11232          if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
11233          temp |= (infoflag >> 6);
11234          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11235       } else {
11236          temp = 0;
11237          if(infoflag & 0x01) temp |= 0x80;
11238          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11239          temp = 0x30;
11240          if(infoflag & 0x01) temp = 0x20;
11241          infoflag &= 0xc0;
11242          temp |= infoflag;
11243          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11244       }
11245
11246    }
11247 }
11248
11249 static void
11250 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11251 {
11252    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11253    USHORT romptr, temp1, temp2;
11254
11255    if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11256       if(SiS_Pr->LVDSHL != -1) {
11257          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11258       }
11259    }
11260
11261    if(SiS_Pr->SiS_ROMNew) {
11262
11263       if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11264          if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11265             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11266             temp2 = 0xfc;
11267             if(SiS_Pr->LVDSHL != -1) {
11268               temp1 &= 0xfc;
11269               temp2 = 0xf3;
11270             }
11271             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11272          }
11273          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11274             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11275             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11276          }
11277       }
11278
11279    }
11280 }
11281
11282 void
11283 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11284                   USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11285 {
11286    if(SiS_Pr->SiS_VBType & VB_SISVB) {
11287
11288       SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11289
11290       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11291          SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11292          SetPanelParms661(SiS_Pr,HwInfo);
11293       }
11294
11295       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11296          SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11297          SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11298          SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11299          if(SiS_Pr->SiS_VBType & VB_SIS301) {
11300             SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11301          }
11302       }
11303    }
11304 }
11305
11306 /* FinalizeLCD
11307  * This finalizes some CRT2 registers for the very panel used.
11308  * If we have a backup if these registers, we use it; otherwise
11309  * we set the register according to most BIOSes. However, this
11310  * function looks quite different in every BIOS, so you better
11311  * pray that we have a backup...
11312  */
11313 void
11314 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11315                 PSIS_HW_INFO HwInfo)
11316 {
11317   USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11318   USHORT resinfo,modeflag;
11319
11320   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11321
11322   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11323      if(SiS_Pr->LVDSHL != -1) {
11324         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11325      }
11326   }
11327
11328   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11329   if(SiS_Pr->UseCustomMode) return;
11330
11331   switch(SiS_Pr->SiS_CustomT) {
11332   case CUT_COMPAQ1280:
11333   case CUT_COMPAQ12802:
11334   case CUT_CLEVO1400:
11335   case CUT_CLEVO14002:
11336      return;
11337   }
11338
11339   if(ModeNo <= 0x13) {
11340      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11341      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11342   } else {
11343      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11344      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11345   }
11346
11347   if(IS_SIS650) {
11348      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11349         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11350            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11351         } else {
11352            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11353         }
11354      }
11355   }
11356
11357   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11358      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11359         /* Maybe all panels? */
11360         if(SiS_Pr->LVDSHL == -1) {
11361            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11362         }
11363         return;
11364      }
11365   }
11366
11367   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11368      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11369         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11370            if(SiS_Pr->LVDSHL == -1) {
11371               /* Maybe all panels? */
11372               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11373            }
11374            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11375               tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11376               if(tempch == 3) {
11377                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11378                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11379                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11380                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11381               }
11382            }
11383            return;
11384         }
11385      }
11386   }
11387
11388   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11389      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11390         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11391            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11392 #ifdef SET_EMI
11393            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11394 #endif
11395            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11396         }
11397      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11398         if(SiS_Pr->LVDSHL == -1) {
11399            /* Maybe ACER only? */
11400            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11401         }
11402      }
11403      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11404      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11405         if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11406            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11407         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11408            if(tempch == 0x03) {
11409               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11410               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11411               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11412               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11413            }
11414            if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11415               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11416               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11417               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11418               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11419               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11420               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11421               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11422               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11423               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11424               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11425            } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {  /* 1.10.8w */
11426               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11427               if(ModeNo <= 0x13) {
11428                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11429                  if((resinfo == 0) || (resinfo == 2)) return;
11430                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11431                  if((resinfo == 1) || (resinfo == 3)) return;
11432               }
11433               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11434               if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11435                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
11436 #if 0
11437                  tempbx = 806;  /* 0x326 */                      /* other older BIOSes */
11438                  tempbx--;
11439                  temp = tempbx & 0xff;
11440                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11441                  temp = (tempbx >> 8) & 0x03;
11442                  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11443 #endif
11444               }
11445            } else if(ModeNo <= 0x13) {
11446               if(ModeNo <= 1) {
11447                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11448                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11449                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11450                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11451               }
11452               if(!(modeflag & HalfDCLK)) {
11453                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11454                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11455                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11456                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11457                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11458                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11459                  if(ModeNo == 0x12) {
11460                     switch(tempch) {
11461                        case 0:
11462                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11463                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11464                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11465                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11466                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11467                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11468                           break;
11469                        case 2:
11470                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11471                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11472                           break;
11473                        case 3:
11474                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11475                           break;
11476                     }
11477                  }
11478               }
11479            }
11480         }
11481      } else {
11482         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11483         tempcl &= 0x0f;
11484         tempbh &= 0x70;
11485         tempbh >>= 4;
11486         tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11487         tempbx = (tempbh << 8) | tempbl;
11488         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11489            if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11490               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11491                  tempbx = 770;
11492               } else {
11493                  if(tempbx > 770) tempbx = 770;
11494                  if(SiS_Pr->SiS_VGAVDE < 600) {
11495                     tempax = 768 - SiS_Pr->SiS_VGAVDE;
11496                     tempax >>= 4;                                /* 1.10.7w; 1.10.6s: 3;  */
11497                     if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11498                     tempbx -= tempax;
11499                  }
11500               }
11501            } else return;
11502         }
11503         temp = tempbx & 0xff;
11504         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11505         temp = ((tempbx & 0xff00) >> 4) | tempcl;
11506         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11507      }
11508   }
11509 }
11510
11511 #endif
11512
11513 /*  =================  SiS 300 O.E.M. ================== */
11514
11515 #ifdef SIS300
11516
11517 void
11518 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11519                USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11520 {
11521   USHORT crt2crtc=0, modeflag, myindex=0;
11522   UCHAR  temp;
11523   int i;
11524
11525   if(ModeNo <= 0x13) {
11526      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11527      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11528   } else {
11529      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11530      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11531   }
11532
11533   crt2crtc &= 0x3f;
11534
11535   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11536      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11537   }
11538
11539   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11540      if(modeflag & HalfDCLK) myindex = 1;
11541
11542      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11543         for(i=0; i<7; i++) {
11544            if(barco_p1[myindex][crt2crtc][i][0]) {
11545               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11546                               barco_p1[myindex][crt2crtc][i][0],
11547                               barco_p1[myindex][crt2crtc][i][2],
11548                               barco_p1[myindex][crt2crtc][i][1]);
11549            }
11550         }
11551      }
11552      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11553      if(temp & 0x80) {
11554         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11555         temp++;
11556         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11557      }
11558   }
11559 }
11560
11561 static USHORT
11562 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11563 {
11564   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11565   USHORT tempbx=0,romptr=0;
11566   UCHAR customtable300[] = {
11567         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11568         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11569   };
11570   UCHAR customtable630[] = {
11571         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11572         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11573   };
11574
11575   if(HwInfo->jChipType == SIS_300) {
11576
11577     tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
11578     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11579     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11580        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11581     }
11582     if(SiS_Pr->SiS_UseROM) {
11583        if(ROMAddr[0x235] & 0x80) {
11584           tempbx = SiS_Pr->SiS_LCDTypeInfo;
11585           if(Flag) {
11586              romptr = SISGETROMW(0x255);
11587              if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11588              else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11589              if(tempbx == 0xFF) return 0xFFFF;
11590           }
11591           tempbx <<= 1;
11592           if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11593        }
11594     }
11595
11596   } else {
11597
11598     if(Flag) {
11599        if(SiS_Pr->SiS_UseROM) {
11600           romptr = SISGETROMW(0x255);
11601           if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11602           else       tempbx = 0xff;
11603        } else {
11604           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11605        }
11606        if(tempbx == 0xFF) return 0xFFFF;
11607        tempbx <<= 2;
11608        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11609        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11610        return tempbx;
11611     }
11612     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11613     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11614     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11615   }
11616   return tempbx;
11617 }
11618
11619 static void
11620 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11621                USHORT ModeNo,USHORT ModeIdIndex)
11622 {
11623   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11624   USHORT index,temp,romptr=0;
11625
11626   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11627
11628   if(SiS_Pr->SiS_UseROM) {
11629      if(!(ROMAddr[0x237] & 0x01)) return;
11630      if(!(ROMAddr[0x237] & 0x02)) return;
11631      romptr = SISGETROMW(0x24b);
11632   }
11633
11634   /* The Panel Compensation Delay should be set according to tables
11635    * here. Unfortunately, various BIOS versions don't case about
11636    * a uniform way using eg. ROM byte 0x220, but use different
11637    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11638    * Thus we don't set this if the user select a custom pdc or if
11639    * we otherwise detected a valid pdc.
11640    */
11641   if(SiS_Pr->PDC != -1) return;
11642
11643   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11644
11645   if(SiS_Pr->UseCustomMode)
11646      index = 0;
11647   else
11648      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11649
11650   if(HwInfo->jChipType != SIS_300) {
11651      if(romptr) {
11652         romptr += (temp * 2);
11653         romptr = SISGETROMW(romptr);
11654         romptr += index;
11655         temp = ROMAddr[romptr];
11656      } else {
11657         if(SiS_Pr->SiS_VBType & VB_SISVB) {
11658            temp = SiS300_OEMLCDDelay2[temp][index];
11659         } else {
11660            temp = SiS300_OEMLCDDelay3[temp][index];
11661         }
11662      }
11663   } else {
11664      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11665         if(romptr) {
11666            romptr += (temp * 2);
11667            romptr = SISGETROMW(romptr);
11668            romptr += index;
11669            temp = ROMAddr[romptr];
11670         } else {
11671            temp = SiS300_OEMLCDDelay5[temp][index];
11672         }
11673      } else {
11674         if(SiS_Pr->SiS_UseROM) {
11675            romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11676            if(romptr) {
11677               romptr += (temp * 2);
11678               romptr = SISGETROMW(romptr);
11679               romptr += index;
11680               temp = ROMAddr[romptr];
11681            } else {
11682               temp = SiS300_OEMLCDDelay4[temp][index];
11683            }
11684         } else {
11685            temp = SiS300_OEMLCDDelay4[temp][index];
11686         }
11687      }
11688   }
11689   temp &= 0x3c;
11690   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11691 }
11692
11693 static void
11694 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11695               USHORT ModeNo,USHORT ModeIdIndex)
11696 {
11697 #if 0  /* Unfinished; Data table missing */
11698   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11699   USHORT index,temp;
11700
11701   if((SiS_Pr->SiS_UseROM) {
11702      if(!(ROMAddr[0x237] & 0x01)) return;
11703      if(!(ROMAddr[0x237] & 0x04)) return;
11704      /* No rom pointer in BIOS header! */
11705   }
11706
11707   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
11708   if(temp = 0xFFFF) return;
11709
11710   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11711   for(i=0x14, j=0; i<=0x17; i++, j++) {
11712       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11713   }
11714   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11715
11716   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11717   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11718   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11719   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11720   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11721       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11722   }
11723 #endif
11724 }
11725
11726 static USHORT
11727 GetOEMTVPtr(SiS_Private *SiS_Pr)
11728 {
11729   USHORT index;
11730
11731   index = 0;
11732   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11733   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11734      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11735      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11736      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11737   } else {
11738      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11739      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11740   }
11741   return index;
11742 }
11743
11744 static void
11745 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11746               USHORT ModeNo,USHORT ModeIdIndex)
11747 {
11748   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11749   USHORT index,temp,romptr=0;
11750
11751   if(SiS_Pr->SiS_UseROM) {
11752      if(!(ROMAddr[0x238] & 0x01)) return;
11753      if(!(ROMAddr[0x238] & 0x02)) return;
11754      romptr = SISGETROMW(0x241);
11755   }
11756
11757   temp = GetOEMTVPtr(SiS_Pr);
11758
11759   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11760
11761   if(romptr) {
11762      romptr += (temp * 2);
11763      romptr = SISGETROMW(romptr);
11764      romptr += index;
11765      temp = ROMAddr[romptr];
11766   } else {
11767      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11768         temp = SiS300_OEMTVDelay301[temp][index];
11769      } else {
11770         temp = SiS300_OEMTVDelayLVDS[temp][index];
11771      }
11772   }
11773   temp &= 0x3c;
11774   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11775 }
11776
11777 static void
11778 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11779                   USHORT ModeNo, USHORT ModeIdIndex)
11780 {
11781   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11782   USHORT index,temp,romptr=0;
11783
11784   if(SiS_Pr->SiS_UseROM) {
11785      if(!(ROMAddr[0x238] & 0x01)) return;
11786      if(!(ROMAddr[0x238] & 0x04)) return;
11787      romptr = SISGETROMW(0x243);
11788   }
11789
11790   temp = GetOEMTVPtr(SiS_Pr);
11791
11792   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11793
11794   if(romptr) {
11795      romptr += (temp * 2);
11796      romptr = SISGETROMW(romptr);
11797      romptr += index;
11798      temp = ROMAddr[romptr];
11799   } else {
11800      temp = SiS300_OEMTVFlicker[temp][index];
11801   }
11802   temp &= 0x70;
11803   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11804 }
11805
11806 static void
11807 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11808                 USHORT ModeNo,USHORT ModeIdIndex)
11809 {
11810   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11811   USHORT index,i,j,temp,romptr=0;
11812
11813   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11814
11815   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11816
11817   if(SiS_Pr->SiS_UseROM) {
11818      if(!(ROMAddr[0x238] & 0x01)) return;
11819      if(!(ROMAddr[0x238] & 0x08)) return;
11820      romptr = SISGETROMW(0x245);
11821   }
11822
11823   temp = GetOEMTVPtr(SiS_Pr);
11824
11825   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11826
11827   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11828      for(i=0x31, j=0; i<=0x34; i++, j++) {
11829         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11830      }
11831   } else {
11832      if(romptr) {
11833         romptr += (temp * 2);
11834         romptr = SISGETROMW(romptr);
11835         romptr += (index * 4);
11836         for(i=0x31, j=0; i<=0x34; i++, j++) {
11837            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11838         }
11839      } else {
11840         for(i=0x31, j=0; i<=0x34; i++, j++) {
11841            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11842         }
11843      }
11844   }
11845 }
11846
11847 static void
11848 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11849               USHORT ModeNo,USHORT ModeIdIndex)
11850 {
11851   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11852   USHORT index,temp,i,j,romptr=0;
11853
11854   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11855
11856   if(SiS_Pr->SiS_UseROM) {
11857      if(!(ROMAddr[0x238] & 0x01)) return;
11858      if(!(ROMAddr[0x238] & 0x10)) return;
11859      romptr = SISGETROMW(0x247);
11860   }
11861
11862   temp = GetOEMTVPtr(SiS_Pr);
11863
11864   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11865   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11866   /* NTSCJ uses NTSC filters */
11867
11868   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11869
11870   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11871       for(i=0x35, j=0; i<=0x38; i++, j++) {
11872         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11873       }
11874       for(i=0x48; i<=0x4A; i++, j++) {
11875         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11876       }
11877   } else {
11878       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11879          romptr += (temp * 2);
11880          romptr = SISGETROMW(romptr);
11881          romptr += (index * 4);
11882          for(i=0x35, j=0; i<=0x38; i++, j++) {
11883             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11884          }
11885       } else {
11886          for(i=0x35, j=0; i<=0x38; i++, j++) {
11887             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11888          }
11889       }
11890   }
11891 }
11892
11893 static USHORT
11894 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
11895 {
11896    USHORT ModeIdIndex;
11897    UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
11898
11899    if(*ModeNo <= 5) *ModeNo |= 1;
11900
11901    for(ModeIdIndex=0; ; ModeIdIndex++) {
11902       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11903       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11904    }
11905
11906    if(*ModeNo != 0x07) {
11907       if(*ModeNo > 0x03) return ModeIdIndex;
11908       if(VGAINFO & 0x80) return ModeIdIndex;
11909       ModeIdIndex++;
11910    }
11911
11912    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11913                                        /* else 350 lines */
11914    return ModeIdIndex;
11915 }
11916
11917 void
11918 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11919                   USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
11920 {
11921   USHORT OEMModeIdIndex=0;
11922
11923   if(!SiS_Pr->UseCustomMode) {
11924      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11925      if(!(OEMModeIdIndex)) return;
11926   }
11927
11928   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11929      SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11930      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11931         SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11932      }
11933   }
11934   if(SiS_Pr->UseCustomMode) return;
11935   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11936      SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
11937      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11938         SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11939         SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11940         SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11941      }
11942   }
11943 }
11944 #endif
11945