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
SiS_UnLockCRT2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
SiS_LockCRT2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
SiS_SetRegSR11ANDOR(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DataAND,USHORT DataOR)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 *
GetLCDStructPtr661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
GetLCDStructPtr661_2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
SiS_AdjustCRT2Rate(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * i,PSIS_HW_INFO HwInfo)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
SiS_GetRatePtr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)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
SiS_SaveCRT2Info(SiS_Private * SiS_Pr,USHORT ModeNo)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
SiS_CR36BIOSWord23b(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
SiS_CR36BIOSWord23d(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)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
SiS_DDC2Delay(SiS_Private * SiS_Pr,USHORT delaytime)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 static void
SiS_GenericDelay(SiS_Private * SiS_Pr,USHORT delay)431 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
432 {
433   USHORT temp,flag;
434 
435   flag = SiS_GetRegByte(0x61) & 0x10;
436 
437   while(delay) {
438      temp = SiS_GetRegByte(0x61) & 0x10;
439      if(temp == flag) continue;
440      flag = temp;
441      delay--;
442   }
443 }
444 
445 #ifdef SIS315H
446 static void
SiS_LongDelay(SiS_Private * SiS_Pr,USHORT delay)447 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
448 {
449   while(delay--) {
450      SiS_GenericDelay(SiS_Pr,0x19df);
451   }
452 }
453 #endif
454 
455 static void
SiS_ShortDelay(SiS_Private * SiS_Pr,USHORT delay)456 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
457 {
458   while(delay--) {
459      SiS_GenericDelay(SiS_Pr,0x42);
460   }
461 }
462 
463 static void
SiS_PanelDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DelayTime)464 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
465 {
466   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
467   USHORT PanelID, DelayIndex, Delay=0;
468 
469   if(HwInfo->jChipType < SIS_315H) {
470 
471 #ifdef SIS300
472 
473       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
474       if(SiS_Pr->SiS_VBType & VB_SISVB) {
475          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
476       }
477       DelayIndex = PanelID >> 4;
478       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
479          Delay = 3;
480       } else {
481          if(DelayTime >= 2) DelayTime -= 2;
482          if(!(DelayTime & 0x01)) {
483        	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
484          } else {
485        	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
486          }
487 	 if(SiS_Pr->SiS_UseROM) {
488             if(ROMAddr[0x220] & 0x40) {
489                if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
490                else 	    	       Delay = (USHORT)ROMAddr[0x226];
491             }
492          }
493       }
494       SiS_ShortDelay(SiS_Pr, Delay);
495 
496 #endif  /* SIS300 */
497 
498    } else {
499 
500 #ifdef SIS315H
501 
502       if((HwInfo->jChipType >= SIS_661)    ||
503          (HwInfo->jChipType <= SIS_315PRO) ||
504 	 (HwInfo->jChipType == SIS_330)) {
505 
506          if(!(DelayTime & 0x01)) {
507 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
508          } else {
509 	    SiS_DDC2Delay(SiS_Pr, 0x4000);
510          }
511 
512       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
513          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
514 	 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {			/* 315 series, LVDS; Special */
515 
516          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
517             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
518 	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
519 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
520 	    }
521 	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
522 	       DelayIndex = PanelID & 0x0f;
523 	    } else {
524 	       DelayIndex = PanelID >> 4;
525 	    }
526 	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
527                Delay = 3;
528             } else {
529                if(DelayTime >= 2) DelayTime -= 2;
530                if(!(DelayTime & 0x01)) {
531        		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
532                } else {
533        		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
534                }
535 	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
536                   if(ROMAddr[0x13c] & 0x40) {
537                      if(!(DelayTime & 0x01)) {
538 	    	        Delay = (USHORT)ROMAddr[0x17e];
539                      } else {
540 	    	        Delay = (USHORT)ROMAddr[0x17f];
541                      }
542                   }
543                }
544             }
545 	    SiS_ShortDelay(SiS_Pr, Delay);
546 	 }
547 
548       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
549 
550 	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
551          if(!(DelayTime & 0x01)) {
552        	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
553          } else {
554        	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
555          }
556 	 Delay <<= 8;
557 	 SiS_DDC2Delay(SiS_Pr, Delay);
558 
559       }
560 
561 #endif /* SIS315H */
562 
563    }
564 }
565 
566 #ifdef SIS315H
567 static void
SiS_PanelDelayLoop(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DelayTime,USHORT DelayLoop)568 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
569                       USHORT DelayTime, USHORT DelayLoop)
570 {
571    int i;
572    for(i=0; i<DelayLoop; i++) {
573       SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
574    }
575 }
576 #endif
577 
578 /*********************************************/
579 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
580 /*********************************************/
581 
582 void
SiS_WaitRetrace1(SiS_Private * SiS_Pr)583 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
584 {
585   USHORT watchdog;
586 
587   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
588   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
589 
590   watchdog = 65535;
591   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
592   watchdog = 65535;
593   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
594 }
595 
596 static void
SiS_WaitRetrace2(SiS_Private * SiS_Pr,USHORT reg)597 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
598 {
599   USHORT watchdog;
600 
601   watchdog = 65535;
602   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
603   watchdog = 65535;
604   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
605 }
606 
607 static void
SiS_WaitVBRetrace(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)608 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
609 {
610   if(HwInfo->jChipType < SIS_315H) {
611 #ifdef SIS300
612      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
613         if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
614      }
615      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
616         SiS_WaitRetrace1(SiS_Pr);
617      } else {
618         SiS_WaitRetrace2(SiS_Pr, 0x25);
619      }
620 #endif
621   } else {
622 #ifdef SIS315H
623      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
624         SiS_WaitRetrace1(SiS_Pr);
625      } else {
626         SiS_WaitRetrace2(SiS_Pr, 0x30);
627      }
628 #endif
629   }
630 }
631 
632 static void
SiS_VBWait(SiS_Private * SiS_Pr)633 SiS_VBWait(SiS_Private *SiS_Pr)
634 {
635   USHORT tempal,temp,i,j;
636 
637   temp = 0;
638   for(i=0; i<3; i++) {
639     for(j=0; j<100; j++) {
640        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
641        if(temp & 0x01) {
642           if((tempal & 0x08))  continue;
643           else break;
644        } else {
645           if(!(tempal & 0x08)) continue;
646           else break;
647        }
648     }
649     temp ^= 0x01;
650   }
651 }
652 
653 static void
SiS_VBLongWait(SiS_Private * SiS_Pr)654 SiS_VBLongWait(SiS_Private *SiS_Pr)
655 {
656   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
657      SiS_VBWait(SiS_Pr);
658   } else {
659      SiS_WaitRetrace1(SiS_Pr);
660   }
661 }
662 
663 /*********************************************/
664 /*               HELPER: MISC                */
665 /*********************************************/
666 
667 #ifdef SIS300
668 static BOOLEAN
SiS_Is301B(SiS_Private * SiS_Pr)669 SiS_Is301B(SiS_Private *SiS_Pr)
670 {
671   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
672   return FALSE;
673 }
674 #endif
675 
676 static BOOLEAN
SiS_CRT2IsLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)677 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
678 {
679   USHORT flag;
680 
681   if(HwInfo->jChipType == SIS_730) {
682      flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
683      if(flag & 0x20) return TRUE;
684   }
685   flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
686   if(flag & 0x20) return TRUE;
687   return FALSE;
688 }
689 
690 BOOLEAN
SiS_IsDualEdge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)691 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
692 {
693 #ifdef SIS315H
694   USHORT flag;
695 
696   if(HwInfo->jChipType >= SIS_315H) {
697      if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
698         flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
699         if(flag & EnableDualEdge) return TRUE;
700      }
701   }
702 #endif
703   return FALSE;
704 }
705 
706 BOOLEAN
SiS_IsVAMode(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)707 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
708 {
709 #ifdef SIS315H
710   USHORT flag;
711 
712   if(HwInfo->jChipType >= SIS_315H) {
713      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
714      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
715   }
716 #endif
717   return FALSE;
718 }
719 
720 #ifdef SIS315H
721 static BOOLEAN
SiS_IsVAorLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)722 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
723 {
724   if(SiS_IsVAMode(SiS_Pr,HwInfo))   return TRUE;
725   if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
726   return FALSE;
727 }
728 #endif
729 
730 static BOOLEAN
SiS_IsDualLink(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)731 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
732 {
733 #ifdef SIS315H
734   if(HwInfo->jChipType >= SIS_315H) {
735      if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
736         (SiS_IsVAMode(SiS_Pr, HwInfo))) {
737         if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
738      }
739   }
740 #endif
741   return FALSE;
742 }
743 
744 #ifdef SIS315H
745 static BOOLEAN
SiS_TVEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)746 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
747 {
748   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
749   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
750      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
751   }
752   return FALSE;
753 }
754 #endif
755 
756 #ifdef SIS315H
757 static BOOLEAN
SiS_LCDAEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)758 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
759 {
760   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
761   return FALSE;
762 }
763 #endif
764 
765 #ifdef SIS315H
766 static BOOLEAN
SiS_WeHaveBacklightCtrl(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)767 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
768 {
769   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
770      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
771   }
772   return FALSE;
773 }
774 #endif
775 
776 #ifdef SIS315H
777 static BOOLEAN
SiS_IsNotM650orLater(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)778 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
779 {
780   USHORT flag;
781 
782   if(HwInfo->jChipType == SIS_650) {
783      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
784      flag &= 0xF0;
785      /* Check for revision != A0 only */
786      if((flag == 0xe0) || (flag == 0xc0) ||
787         (flag == 0xb0) || (flag == 0x90)) return FALSE;
788   } else if(HwInfo->jChipType >= SIS_661) return FALSE;
789   return TRUE;
790 }
791 #endif
792 
793 #ifdef SIS315H
794 static BOOLEAN
SiS_IsYPbPr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)795 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
796 {
797   USHORT flag;
798 
799   if(HwInfo->jChipType >= SIS_315H) {
800      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
801      if(flag & EnableCHYPbPr) return TRUE;  /* = YPrPb = 0x08 */
802   }
803   return FALSE;
804 }
805 #endif
806 
807 #ifdef SIS315H
808 static BOOLEAN
SiS_IsChScart(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)809 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
810 {
811   USHORT flag;
812 
813   if(HwInfo->jChipType >= SIS_315H) {
814      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
815      if(flag & EnableCHScart) return TRUE;  /* = Scart = 0x04 */
816   }
817   return FALSE;
818 }
819 #endif
820 
821 #ifdef SIS315H
822 static BOOLEAN
SiS_IsTVOrYPbPrOrScart(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)823 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
824 {
825   USHORT flag;
826 
827   if(HwInfo->jChipType >= SIS_315H) {
828      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
829      if(flag & SetCRT2ToTV)        return TRUE;
830      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
831      if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
832      if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
833   } else {
834      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
835      if(flag & SetCRT2ToTV)        return TRUE;
836   }
837   return FALSE;
838 }
839 #endif
840 
841 #ifdef SIS315H
842 static BOOLEAN
SiS_IsLCDOrLCDA(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)843 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
844 {
845   USHORT flag;
846 
847   if(HwInfo->jChipType >= SIS_315H) {
848      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
849      if(flag & SetCRT2ToLCD) return TRUE;
850      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
851      if(flag & SetToLCDA)    return TRUE;
852   } else {
853      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
854      if(flag & SetCRT2ToLCD) return TRUE;
855   }
856   return FALSE;
857 }
858 #endif
859 
860 static BOOLEAN
SiS_BridgeIsOn(SiS_Private * SiS_Pr)861 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
862 {
863   USHORT flag;
864 
865   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
866      return TRUE;
867   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
868      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
869      if((flag == 1) || (flag == 2)) return TRUE;
870   }
871   return FALSE;
872 }
873 
874 static BOOLEAN
SiS_BridgeIsEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)875 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
876 {
877   USHORT flag;
878 
879   if(SiS_BridgeIsOn(SiS_Pr)) {
880      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
881      if(HwInfo->jChipType < SIS_315H) {
882        flag &= 0xa0;
883        if((flag == 0x80) || (flag == 0x20)) return TRUE;
884      } else {
885        flag &= 0x50;
886        if((flag == 0x40) || (flag == 0x10)) return TRUE;
887      }
888   }
889   return FALSE;
890 }
891 
892 static BOOLEAN
SiS_BridgeInSlavemode(SiS_Private * SiS_Pr)893 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
894 {
895   USHORT flag1;
896 
897   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
898   if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
899   return FALSE;
900 }
901 
902 /*********************************************/
903 /*       GET VIDEO BRIDGE CONFIG INFO        */
904 /*********************************************/
905 
906 /* Setup general purpose IO for Chrontel communication */
907 void
SiS_SetChrontelGPIO(SiS_Private * SiS_Pr,USHORT myvbinfo)908 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
909 {
910    unsigned long  acpibase;
911    unsigned short temp;
912 
913    if(!(SiS_Pr->SiS_ChSW)) return;
914 
915 #ifndef LINUX_XF86
916    SiS_SetRegLong(0xcf8,0x80000874);		       /* get ACPI base */
917    acpibase = SiS_GetRegLong(0xcfc);
918 #else
919    acpibase = pciReadLong(0x00000800, 0x74);
920 #endif
921    acpibase &= 0xFFFF;
922    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
923    temp &= 0xFEFF;
924    SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
925    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
926    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
927    temp &= 0xFEFF;
928    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
929    SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
930    temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
931 }
932 
933 void
SiS_GetVBInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,int checkcrt2mode)934 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
935               PSIS_HW_INFO HwInfo, int checkcrt2mode)
936 {
937   USHORT tempax,tempbx,temp;
938   USHORT modeflag, resinfo=0;
939 
940   if(ModeNo <= 0x13) {
941      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
942   } else if(SiS_Pr->UseCustomMode) {
943      modeflag = SiS_Pr->CModeFlag;
944   } else {
945      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
946      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
947   }
948 
949   SiS_Pr->SiS_SetFlag = 0;
950 
951   SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
952 
953   tempbx = 0;
954   if(SiS_BridgeIsOn(SiS_Pr)) {
955     	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
956 #if 0
957    	if(HwInfo->jChipType < SIS_661) {
958 	   /* NO - YPbPr not set yet ! */
959 	   if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
960 	      temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
961 	      temp |= SetCRT2ToHiVision;   					/* 0x80 */
962    	   }
963 	   if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
964 	      temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
965 	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
966 	   }
967 	}
968 #endif
969     	tempbx |= temp;
970     	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
971         tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
972     	tempbx |= tempax;
973 
974 #ifdef SIS315H
975 	if(HwInfo->jChipType >= SIS_315H) {
976     	   if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
977 	      if(ModeNo == 0x03) {
978 	         /* Mode 0x03 is never in driver mode */
979 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
980 	      }
981 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
982 	         /* Reset LCDA setting if not driver mode */
983 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 	      }
985 	      if(IS_SIS650) {
986 	         if(SiS_Pr->SiS_UseLCDA) {
987 		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
988 		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
989 		          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
990 		       }
991 		    }
992 		 }
993 	      }
994 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
995        	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
996           	 tempbx |= SetCRT2ToLCDA;
997 	      }
998 	   }
999 
1000 	   if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1001 	      tempbx &= ~(SetCRT2ToRAMDAC);
1002 	   }
1003 
1004 	   if(HwInfo->jChipType >= SIS_661) {
1005 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1006 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1007 	      if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1008 	         if(temp & 0x04) {
1009 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1010 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1011 		    else             tempbx |= SetCRT2ToYPbPr525750;
1012 		 }
1013 	      } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
1014 	         if(temp & 0x04) {
1015 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1016 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1017 		 }
1018 	      }
1019   	   }
1020 
1021 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1022 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1023 	      if(temp & SetToLCDA) {
1024 		 tempbx |= SetCRT2ToLCDA;
1025 	      }
1026 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1027 	         if(temp & EnableCHYPbPr) {
1028 		    tempbx |= SetCRT2ToCHYPbPr;
1029 		 }
1030 	      }
1031 	   }
1032 	}
1033 
1034 #endif  /* SIS315H */
1035 
1036     	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1037 	   temp = SetCRT2ToSVIDEO   |
1038 	          SetCRT2ToAVIDEO   |
1039 	          SetCRT2ToSCART    |
1040 	          SetCRT2ToLCDA     |
1041 	          SetCRT2ToLCD      |
1042 	          SetCRT2ToRAMDAC   |
1043                   SetCRT2ToHiVision |
1044 		  SetCRT2ToYPbPr525750;
1045     	} else {
1046            if(HwInfo->jChipType >= SIS_315H) {
1047               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1048         	 temp = SetCRT2ToAVIDEO |
1049 		        SetCRT2ToSVIDEO |
1050 		        SetCRT2ToSCART  |
1051 		        SetCRT2ToLCDA   |
1052 		        SetCRT2ToLCD    |
1053 		        SetCRT2ToCHYPbPr;
1054       	      } else {
1055         	 temp = SetCRT2ToLCDA   |
1056 		        SetCRT2ToLCD;
1057 	      }
1058 	   } else {
1059       	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1060           	 temp = SetCRT2ToTV | SetCRT2ToLCD;
1061               } else {
1062         	 temp = SetCRT2ToLCD;
1063 	      }
1064 	   }
1065     	}
1066 
1067     	if(!(tempbx & temp)) {
1068       	   tempax = DisableCRT2Display;
1069       	   tempbx = 0;
1070     	}
1071 
1072    	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1073 	   USHORT clearmask = ( DriverMode 	   |
1074 				DisableCRT2Display |
1075 				LoadDACFlag 	   |
1076 				SetNotSimuMode 	   |
1077 				SetInSlaveMode 	   |
1078 				SetPALTV 	   |
1079 				SwitchCRT2	   |
1080 				SetSimuScanMode );
1081       	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1082 	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1083 	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1084 	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1085 	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1086 	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1087    	} else {
1088 	   if(HwInfo->jChipType >= SIS_315H) {
1089 	      if(tempbx & SetCRT2ToLCDA) {
1090 	         tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1091 	      }
1092 	   }
1093       	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1094               if(tempbx & SetCRT2ToTV) {
1095           	 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1096 	      }
1097       	   }
1098       	   if(tempbx & SetCRT2ToLCD) {
1099               tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1100 	   }
1101 	   if(HwInfo->jChipType >= SIS_315H) {
1102 	      if(tempbx & SetCRT2ToLCDA) {
1103 	         tempbx |= SetCRT2ToLCD;
1104 	      }
1105 	   }
1106 	}
1107 
1108     	if(tempax & DisableCRT2Display) {
1109       	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1110               tempbx = SetSimuScanMode | DisableCRT2Display;
1111       	   }
1112     	}
1113 
1114     	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1115 
1116 	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1117 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1118 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1119 	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1120 	       modeflag &= (~CRT2Mode);
1121 	   }
1122 	}
1123 
1124     	if(!(tempbx & SetSimuScanMode)) {
1125       	   if(tempbx & SwitchCRT2) {
1126               if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1127 		 if( (HwInfo->jChipType >= SIS_315H) &&
1128 		     (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1129 		    if(resinfo != SIS_RI_1600x1200) {
1130                        tempbx |= SetSimuScanMode;
1131 		    }
1132 		 } else {
1133             	    tempbx |= SetSimuScanMode;
1134 	         }
1135               }
1136       	   } else {
1137               if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1138           	 if(!(tempbx & DriverMode)) {
1139             	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1140 		       tempbx |= SetSimuScanMode;
1141             	    }
1142                  }
1143               }
1144       	   }
1145     	}
1146 
1147     	if(!(tempbx & DisableCRT2Display)) {
1148            if(tempbx & DriverMode) {
1149               if(tempbx & SetSimuScanMode) {
1150           	 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1151 	            if( (HwInfo->jChipType >= SIS_315H) &&
1152 		        (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1153 		       if(resinfo != SIS_RI_1600x1200) {
1154 		          tempbx |= SetInSlaveMode;
1155 		       }
1156 		    } else {
1157             	       tempbx |= SetInSlaveMode;
1158                     }
1159 	         }
1160               }
1161            } else {
1162               tempbx |= SetInSlaveMode;
1163       	   }
1164     	}
1165 
1166   }
1167 
1168   SiS_Pr->SiS_VBInfo = tempbx;
1169 
1170   if(HwInfo->jChipType == SIS_630) {
1171      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1172   }
1173 
1174 #ifdef TWDEBUG
1175 #ifdef LINUX_KERNEL
1176   printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1177       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1178 #endif
1179 #ifdef LINUX_XF86
1180   xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1181       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1182 #endif
1183 #endif
1184 }
1185 
1186 /*********************************************/
1187 /*           DETERMINE YPbPr MODE            */
1188 /*********************************************/
1189 
1190 void
SiS_SetYPbPr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)1191 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1192 {
1193 
1194   UCHAR temp;
1195 
1196   /* Note: This variable is only used on 30xLV systems.
1197    * CR38 has a different meaning on LVDS/CH7019 systems.
1198    * On 661 and later, these bits moved to CR35.
1199    *
1200    * On 301, 301B, only HiVision 1080i is supported.
1201    * On 30xLV, 301C, only YPbPr 1080i is supported.
1202    */
1203 
1204   SiS_Pr->SiS_YPbPr = 0;
1205   if(HwInfo->jChipType >= SIS_661) return;
1206 
1207   if(SiS_Pr->SiS_VBType) {
1208      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1209 	SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1210      }
1211   }
1212 
1213   if(HwInfo->jChipType >= SIS_315H) {
1214      if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1215         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1216 	if(temp & 0x08) {
1217 	   switch((temp >> 4)) {
1218 	   case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1219 	   case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1220 	   case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1221 	   case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1222 	   }
1223 	}
1224      }
1225   }
1226 
1227 }
1228 
1229 /*********************************************/
1230 /*           DETERMINE TVMode flag           */
1231 /*********************************************/
1232 
1233 void
SiS_SetTVMode(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)1234 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1235 {
1236   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1237   USHORT temp, temp1, resinfo = 0, romindex = 0;
1238   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1239 
1240   SiS_Pr->SiS_TVMode = 0;
1241 
1242   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1243   if(SiS_Pr->UseCustomMode) return;
1244 
1245   if(ModeNo > 0x13) {
1246      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1247   }
1248 
1249   if(HwInfo->jChipType < SIS_661) {
1250 
1251      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1252 
1253      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1254         temp = 0;
1255         if((HwInfo->jChipType == SIS_630) ||
1256            (HwInfo->jChipType == SIS_730)) {
1257            temp = 0x35;
1258 	   romindex = 0xfe;
1259         } else if(HwInfo->jChipType >= SIS_315H) {
1260            temp = 0x38;
1261 	   romindex = 0xf3;
1262 	   if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1263         }
1264         if(temp) {
1265            if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1266 	      OutputSelect = ROMAddr[romindex];
1267 	      if(!(OutputSelect & EnablePALMN)) {
1268                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1269 	      }
1270 	   }
1271 	   temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1272 	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1273               if(temp1 & EnablePALM) {		/* 0x40 */
1274                  SiS_Pr->SiS_TVMode |= TVSetPALM;
1275 	         SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1276 	      } else if(temp1 & EnablePALN) {	/* 0x80 */
1277 	         SiS_Pr->SiS_TVMode |= TVSetPALN;
1278               }
1279 	   } else {
1280               if(temp1 & EnableNTSCJ) {		/* 0x40 */
1281 	         SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1282   	      }
1283 	   }
1284         }
1285 	/* Translate HiVision/YPbPr to our new flags */
1286 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1287 	   if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1288 	   else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1289 	   else	if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1290 	   else					       SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1291 	   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1292 	      SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1293 	      SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1294 	   } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1295 	      SiS_Pr->SiS_TVMode |= TVSetPAL;
1296 	   }
1297 	}
1298      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1299         if(SiS_Pr->SiS_CHOverScan) {
1300            if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1301               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1302               if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1303 	         SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1304               }
1305            } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1306       	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1307       	      if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1308 	         SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1309  	      }
1310 	   }
1311            if(SiS_Pr->SiS_CHSOverScan) {
1312               SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1313            }
1314         }
1315         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1316 	   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1317      	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1318               if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1319 	      else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1320            } else {
1321 	      if(temp & EnableNTSCJ) {
1322 	         SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1323   	      }
1324 	   }
1325 	}
1326      }
1327 
1328   } else {  /* 661 and later */
1329 
1330      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1331      if(temp1 & 0x01) {
1332         SiS_Pr->SiS_TVMode |= TVSetPAL;
1333 	if(temp1 & 0x08) {
1334 	   SiS_Pr->SiS_TVMode |= TVSetPALN;
1335 	} else if(temp1 & 0x04) {
1336 	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1337 	      SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1338 	   }
1339 	   SiS_Pr->SiS_TVMode |= TVSetPALM;
1340 	}
1341      } else {
1342         if(temp1 & 0x02) {
1343 	   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1344 	}
1345      }
1346      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1347         if(SiS_Pr->SiS_CHOverScan) {
1348            if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1349 	      SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1350 	   }
1351 	}
1352      }
1353      if(SiS_Pr->SiS_VBType & VB_SISVB) {
1354         if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1355 	   temp1 &= 0xe0;
1356 	   if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1357 	   else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1358 	   else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1359 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1360 	   SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1361 	}
1362 	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1363 	   if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1364 	      SiS_Pr->SiS_TVMode |= TVAspect169;
1365 	   } else {
1366 	      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1367 	      if(temp1 & 0x02) {
1368 		 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1369 		    SiS_Pr->SiS_TVMode |= TVAspect169;
1370 		 } else {
1371 		    SiS_Pr->SiS_TVMode |= TVAspect43LB;
1372 		 }
1373 	      } else {
1374 		 SiS_Pr->SiS_TVMode |= TVAspect43;
1375 	      }
1376 	   }
1377 	}
1378      }
1379   }
1380 
1381   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1382 
1383   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1384 
1385      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1386         SiS_Pr->SiS_TVMode |= TVSetPAL;
1387 	SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1388      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1389         if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1390 	   SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1391 	}
1392      }
1393 
1394      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1395         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1396            SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1397         }
1398      }
1399 
1400      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1401         /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1402         if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1403            if(resinfo == SIS_RI_1024x768) {
1404               SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1405 	   }
1406         }
1407      }
1408 
1409      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1410      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1411         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1412 	SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1413      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1414         SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1415      } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1416         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1417            SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1418         }
1419      }
1420 
1421   }
1422 
1423   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1424 
1425 #ifdef TWDEBUG
1426   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1427 #endif
1428 }
1429 
1430 /*********************************************/
1431 /*               GET LCD INFO                */
1432 /*********************************************/
1433 
1434 static USHORT
SiS_GetBIOSLCDResInfo(SiS_Private * SiS_Pr)1435 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1436 {
1437    USHORT temp = SiS_Pr->SiS_LCDResInfo;
1438    /* Translate my LCDResInfo to BIOS value */
1439    if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
1440    if(temp == Panel_1280x768_3)  temp = Panel_1280x768;
1441    return temp;
1442 }
1443 
1444 static void
SiS_GetLCDInfoBIOS(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)1445 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1446 {
1447 #ifdef SIS315H
1448    UCHAR  *ROMAddr;
1449    USHORT temp;
1450 
1451 #ifdef TWDEBUG
1452    xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1453       	SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1454 	SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1455 	SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1456 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1457 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1458 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1459 #endif
1460 
1461    if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1462       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1463          SiS_Pr->SiS_NeedRomModeData = TRUE;
1464 	 SiS_Pr->PanelHT  = temp;
1465       }
1466       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1467          SiS_Pr->SiS_NeedRomModeData = TRUE;
1468          SiS_Pr->PanelVT  = temp;
1469       }
1470       SiS_Pr->PanelHRS = SISGETROMW(10);
1471       SiS_Pr->PanelHRE = SISGETROMW(12);
1472       SiS_Pr->PanelVRS = SISGETROMW(14);
1473       SiS_Pr->PanelVRE = SISGETROMW(16);
1474       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1475       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1476 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1477       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1478 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1479       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1480 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1481 
1482 #ifdef TWDEBUG
1483       xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1484       	SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1485 	SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1486 	SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1487 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1488 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1489 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1490 #endif
1491 
1492    }
1493 #endif
1494 }
1495 
1496 void
SiS_GetLCDResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)1497 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1498 		  PSIS_HW_INFO HwInfo)
1499 {
1500 #ifdef SIS300
1501   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
1502 #endif
1503 #ifdef SIS315H
1504   UCHAR  *myptr = NULL;
1505 #endif
1506   USHORT temp,modeflag,resinfo=0;
1507   const unsigned char SiS300SeriesLCDRes[] =
1508          { 0,  1,  2,  3,  7,  4,  5,  8,
1509 	   0,  0, 10,  0,  0,  0,  0, 15 };
1510 
1511   SiS_Pr->SiS_LCDResInfo  = 0;
1512   SiS_Pr->SiS_LCDTypeInfo = 0;
1513   SiS_Pr->SiS_LCDInfo     = 0;
1514   SiS_Pr->PanelHRS        = 999; /* HSync start */
1515   SiS_Pr->PanelHRE        = 999; /* HSync end */
1516   SiS_Pr->PanelVRS        = 999; /* VSync start */
1517   SiS_Pr->PanelVRE        = 999; /* VSync end */
1518   SiS_Pr->SiS_NeedRomModeData = FALSE;
1519 
1520   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1521 
1522   if(ModeNo <= 0x13) {
1523      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1524   } else if(SiS_Pr->UseCustomMode) {
1525      modeflag = SiS_Pr->CModeFlag;
1526   } else {
1527      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1528      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1529   }
1530 
1531   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1532   if(!temp) return;
1533 
1534   if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1535      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1536   } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1537      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1538   } else {
1539      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1540   }
1541   temp &= 0x0f;
1542   if(HwInfo->jChipType < SIS_315H) {
1543      /* Translate 300 series LCDRes to 315 series for unified usage */
1544      temp = SiS300SeriesLCDRes[temp];
1545   }
1546 
1547   if(HwInfo->jChipType == SIS_550) {
1548      if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1549      if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1550   }
1551 
1552   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	/* SiS LVDS */
1553      if(temp == Panel310_1280x768) {
1554         temp = Panel_1280x768_2;
1555 #ifdef SIS315H
1556 	if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1557 	   if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
1558 	}
1559 #endif
1560      }
1561   }
1562 
1563   SiS_Pr->SiS_LCDResInfo = temp;
1564 
1565   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1566      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1567         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1568      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1569         SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1570      }
1571   }
1572 
1573   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1574      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1575 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1576   } else {
1577      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1578 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1579   }
1580 
1581   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1582   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1583 
1584   switch(SiS_Pr->SiS_LCDResInfo) {
1585      case Panel_320x480:    SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480;
1586      			    SiS_Pr->PanelHT   =  400; SiS_Pr->PanelVT   =  525;
1587 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1588 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1589 			    break;
1590      case Panel_640x480_2:
1591      case Panel_640x480_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1592      			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1593 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1594 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1595 			    break;
1596      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1597      			    			      SiS_Pr->PanelVRE  =    3;
1598 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1599 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1600 			    break;
1601      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1602      			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1603 			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1604 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1605 			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1606 			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1607 			    break;
1608      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1609      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1610 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1611 			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1612      			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1613 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1614      			    break;
1615      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1616      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1617 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1618 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1619 			    if(HwInfo->jChipType < SIS_315H) {
1620 			       SiS_Pr->PanelHRS = 23;
1621 			       			      SiS_Pr->PanelVRE  =    5;
1622 			    }
1623 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1624 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1625 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1626 			    break;
1627      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
1628      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1629 			    SiS_Pr->PanelHRS  =   24;
1630 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1631 			    if(HwInfo->jChipType < SIS_315H) {
1632 			       SiS_Pr->PanelHRS = 23;
1633 			       			      SiS_Pr->PanelVRE  =    5;
1634 			    }
1635      			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1636 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1637      			    break;
1638      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
1639      			    break;
1640      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
1641      			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
1642 			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
1643 			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
1644 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1645 			    /* Data above for TMDS (projector); get from BIOS for LVDS */
1646 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1647 			    break;
1648      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1649      			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
1650 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
1651 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1652 			    SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1653 			    SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1654 			    break;
1655      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1656      			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
1657 			    SiS_Pr->PanelHRS  =   16; SiS_Pr->PanelHRE  =   64;
1658 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1659 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1660 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1661 			    break;
1662      case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1663      			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  798;
1664 			    SiS_Pr->PanelHRS   =  64; SiS_Pr->PanelHRE  =  128;
1665 			    SiS_Pr->PanelVRS   =   3; SiS_Pr->PanelVRE  =    7;
1666 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
1667 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1668 			    break;
1669      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1670      			    SiS_Pr->PanelHT   = 1656; SiS_Pr->PanelVT   =  841;  /* 1408, 816 */
1671 			    SiS_Pr->PanelHRS   =  32; SiS_Pr->PanelHRE  =  312;  /*   16,  64 */
1672 			    SiS_Pr->PanelVRS   =  16; SiS_Pr->PanelVRE  =    8;  /*    4,   3 */
1673 			    SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
1674 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1675 			    break;
1676      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
1677      			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
1678 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1679 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1680 		 	    if(resinfo == SIS_RI_1280x1024) {
1681 			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1682 			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1683 			    }
1684 			    break;
1685      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1686      			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1687 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1688 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1689 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1690 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1691 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1692 			    break;
1693      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1694      			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1695 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112; /* HRE OK for LVDS, not for LCDA */
1696 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1697 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1698 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1699 			    break;
1700      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1701      			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
1702 			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
1703 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1704 			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1705 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1706 			    break;
1707      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1708      			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
1709 			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
1710 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1711 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1712 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1713 			    break;
1714      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1715     			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1716 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
1717 			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
1718 			    if(SiS_Pr->CP_PreferredIndex != -1) {
1719 			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1720     			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1721 			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1722 			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1723 			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1724 			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1725 			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1726 			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1727 			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1728 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1729 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1730 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1731 			    }
1732 			    break;
1733      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1734      			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1735      			    break;
1736      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
1737      			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1738      			    break;
1739      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1740      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1741 			    break;
1742   }
1743 
1744   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1745   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1746 
1747   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1748   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1749 
1750 #ifdef SIS315H
1751   if(HwInfo->jChipType >= SIS_661) {
1752      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1753         if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1754      }
1755      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1756         if(SiS_Pr->SiS_ROMNew) {
1757 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1758 	} else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1759            if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1760 	}
1761      }
1762   } else if(HwInfo->jChipType >= SIS_315H) {
1763      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1764         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1765      }
1766      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1767         SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1768 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1769         if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1770 	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1771 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1772 	}
1773      }
1774   }
1775 #endif
1776 
1777   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1778      /* Always center screen on LVDS (if scaling is disabled) */
1779      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1780   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1781      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1782         /* Always center screen on SiS LVDS (if scaling is disabled) */
1783         SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1784      } else {
1785         /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
1786         SiS_Pr->SiS_LCDInfo |= LCDPass11;
1787         if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1788      }
1789   }
1790 
1791   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1792      if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1793         SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
1794      }
1795   }
1796 
1797   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1798      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
1799         if(modeflag & NoSupportLCDScale) {
1800 	   /* No scaling for this mode on any panel */
1801 	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1802 	}
1803         switch(SiS_Pr->SiS_LCDResInfo) {
1804         case Panel_Custom:
1805 		/* For non-standard LCD resolution, we let the panel scale */
1806            	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1807 		break;
1808 	case Panel_1280x720:
1809 	      	if(SiS_Pr->PanelHT == 1650) {
1810 		   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1811 		}
1812 	case Panel_1280x768:	/* TMDS only */
1813 		/* No idea about the timing and zoom factors */
1814            	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1815 		break;
1816 	case Panel_1280x960:
1817 	 	SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1818 		break;
1819 	case Panel_1280x1024:
1820 	        if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1821 		   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1822 		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1823 		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
1824 	      	      /* We do not scale to 1280x720/800/960 (B/C bridges only) */
1825                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1826 	           }
1827 	           if(((HwInfo->jChipType >= SIS_315H) &&
1828 		       (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
1829 	              ((HwInfo->jChipType < SIS_315H)  &&
1830 		       (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
1831 	              /* We do not scale to 1280x768 (B/C bridges only) */
1832                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1833 	           }
1834 		}
1835 		break;
1836 	case Panel_1400x1050:
1837 	 	if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1838 	  	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1839 		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1840 		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
1841 		      ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
1842 	      	      /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
1843                       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1844 	           }
1845 		}
1846 		if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1847 		   if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
1848 		      if(SiS_Pr->UsePanelScaler == -1) {
1849 		         /* Do not scale to 1280x720 by default (LVDS bridges) */
1850 	      	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1851 		      }
1852 		   }
1853 		}
1854 		if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
1855 	      	   /* Do not scale to 1280x1024 (all bridges) */
1856 	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1857 	   	}
1858 		break;
1859 	case Panel_1600x1200:
1860 		if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1861 	      	   /* No idea about the timing and zoom factors (C bridge only) */
1862 	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1863 	   	}
1864 		break;
1865 	}
1866      }
1867   }
1868 
1869 #ifdef SIS300
1870   if(HwInfo->jChipType < SIS_315H) {
1871      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1872         if(SiS_Pr->SiS_UseROM) {
1873 	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
1874               if(!(ROMAddr[0x235] & 0x02)) {
1875 	         SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1876  	      }
1877 	   }
1878         }
1879      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1880 	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
1881            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1882 	}
1883      }
1884   }
1885 #endif
1886 
1887   /* Special cases */
1888   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
1889      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1890   }
1891 
1892   if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1893      SiS_Pr->SiS_LCDInfo |= LCDPass11;
1894   }
1895 
1896   if(SiS_Pr->UseCustomMode) {
1897      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1898   }
1899 
1900   /* (In)validate LCDPass11 flag */
1901   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1902      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1903   }
1904 
1905   /* Special cases */
1906   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
1907       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
1908       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1909       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1910       (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1911      SiS_Pr->PanelHRS = 999;
1912      SiS_Pr->PanelHRE = 999;
1913   }
1914 
1915   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1916       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1917       (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1918      SiS_Pr->PanelVRS = 999;
1919      SiS_Pr->PanelVRE = 999;
1920   }
1921 
1922 #ifdef SIS315H
1923   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
1924      if(!(SiS_Pr->SiS_ROMNew)) {
1925         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1926 	   /* Enable 302LV/302ELV dual link mode.
1927 	    * For 661, this is done above.
1928 	    */
1929            if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1930 	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1931 	      /* (Sets this in SenseLCD; new paneltypes) */
1932 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1933 	   }
1934            if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1935 	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1936               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1937 	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1938 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1939 	   }
1940         }
1941      }
1942   }
1943 #endif
1944 
1945   if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
1946 
1947      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1948 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
1949 	   if(ModeNo == 0x12) {
1950 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
1951 	         SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1952 	      }
1953 	   } else if(ModeNo > 0x13) {
1954 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
1955 	         if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1956 	            if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
1957                        SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1958 		    }
1959 		 }
1960 	      }
1961 	   }
1962 	}
1963      }
1964 
1965      if(modeflag & HalfDCLK) {
1966         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
1967 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1968         } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1969 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1970 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1971 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1972 	} else if(ModeNo > 0x13) {
1973            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
1974               if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1975            } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
1976               if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1977            }
1978 	}
1979      }
1980 
1981   }
1982 
1983   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1984      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
1985      	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1986      }
1987   } else {
1988      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1989   }
1990 
1991 #ifdef LINUX_KERNEL
1992 #ifdef TWDEBUG
1993   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
1994 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
1995 #endif
1996 #endif
1997 #ifdef LINUX_XF86
1998   xf86DrvMsgVerb(0, X_PROBED, 4,
1999   	"(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2000 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2001 #endif
2002 }
2003 
2004 /*********************************************/
2005 /*                 GET VCLK                  */
2006 /*********************************************/
2007 
2008 USHORT
SiS_GetVCLK2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)2009 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2010                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2011 {
2012   USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2013   USHORT modeflag,resinfo,tempbx;
2014   const UCHAR *CHTVVCLKPtr = NULL;
2015 
2016   if(ModeNo <= 0x13) {
2017      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2018      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2019      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2020      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2021   } else {
2022      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2023      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2024      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2025      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2026      if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2027   }
2028 
2029   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2030 
2031      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2032 
2033         CRT2Index >>= 6;
2034         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2035 
2036            if(HwInfo->jChipType < SIS_315H) {
2037 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2038 	   } else {
2039 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2040 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2041 	         VCLKIndex = VCLKIndexGEN;
2042 		 switch(resinfo) {
2043 		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
2044 		 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
2045 		                          if(SiS_Pr->PanelHT == 1344) {
2046 					     VCLKIndex = VCLK_1280x720_2;
2047 					  }
2048 				       }
2049 		 		       break;
2050 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2051 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2052 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2053 		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2054 		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2055 		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2056 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2057 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2058 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2059 		 }
2060 
2061 		 if(ModeNo <= 0x13) {
2062 		    if(HwInfo->jChipType <= SIS_315PRO) {
2063 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2064 	            } else {
2065 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2066 		    }
2067 		 }
2068 		 if(HwInfo->jChipType <= SIS_315PRO) {
2069 		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2070 		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2071 		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2072 		 }
2073 	      }
2074 	   }
2075 
2076         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2077 
2078 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2079               if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 		VCLKIndex = HiTVVCLKDIV2;
2080      	      else                                  		VCLKIndex = HiTVVCLK;
2081               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2082             	 if(modeflag & Charx8Dot) 	    		VCLKIndex = HiTVSimuVCLK;
2083             	 else 			  	    		VCLKIndex = HiTVTextVCLK;
2084               }
2085            } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) 	VCLKIndex = YPbPr750pVCLK;
2086 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   	VCLKIndex = TVVCLKDIV2;
2087 	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)     	VCLKIndex = TVVCLKDIV2;
2088            else         		            	  	VCLKIndex = TVVCLK;
2089 
2090 	   if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2091   	   else 	                    VCLKIndex += TVCLKBASE_315;
2092 
2093         } else {         						/* VGA2 */
2094 
2095 	   VCLKIndex = VCLKIndexGEN;
2096 	   if(HwInfo->jChipType < SIS_315H) {
2097               if(ModeNo > 0x13) {
2098 		 if( (HwInfo->jChipType == SIS_630) &&
2099 		     (HwInfo->jChipRevision >= 0x30)) {
2100 		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2101 		 }
2102 		 /* Better VGA2 clock for 1280x1024@75 */
2103 		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2104 	      }
2105            }
2106         }
2107 
2108      } else {   /* If not programming CRT2 */
2109 
2110         VCLKIndex = VCLKIndexGEN;
2111 	if(HwInfo->jChipType < SIS_315H) {
2112            if(ModeNo > 0x13) {
2113 	      if( (HwInfo->jChipType != SIS_630) &&
2114 		  (HwInfo->jChipType != SIS_300) ) {
2115 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2116 	      }
2117 	   }
2118         }
2119      }
2120 
2121   } else {       /*   LVDS  */
2122 
2123      VCLKIndex = CRT2Index;
2124 
2125      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2126 
2127         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2128 
2129 	   VCLKIndex &= 0x1f;
2130            tempbx = 0;
2131 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2132            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2133 	      tempbx += 2;
2134 	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2135 		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2136 	      }
2137 	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2138 		 tempbx = 4;
2139 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2140 	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2141 		 tempbx = 6;
2142 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2143 	      }
2144 	   }
2145        	   switch(tempbx) {
2146              case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2147              case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2148              case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2149              case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2150 	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2151              case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2152              case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2153              case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2154 	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2155 	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2156            }
2157            VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2158 
2159         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2160 
2161 	   if(HwInfo->jChipType < SIS_315H) {
2162 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2163 	   } else {
2164 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2165 	   }
2166 
2167 	   /* Special Timing: Barco iQ Pro R series */
2168 	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2169 
2170 	   /* Special Timing: 848x480 parallel lvds */
2171 	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2172 	      if(HwInfo->jChipType < SIS_315H) {
2173 		 VCLKIndex = VCLK34_300;
2174 	         /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2175 	      } else {
2176 		 VCLKIndex = VCLK34_315;
2177 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2178 	      }
2179 	   }
2180 
2181         } else {
2182 
2183 	   VCLKIndex = VCLKIndexGEN;
2184 	   if(HwInfo->jChipType < SIS_315H) {
2185               if(ModeNo > 0x13) {
2186 		 if( (HwInfo->jChipType == SIS_630) &&
2187                      (HwInfo->jChipRevision >= 0x30) ) {
2188 		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2189 	         }
2190               }
2191 	   }
2192         }
2193 
2194      } else {  /* if not programming CRT2 */
2195 
2196         VCLKIndex = VCLKIndexGEN;
2197 	if(HwInfo->jChipType < SIS_315H) {
2198            if(ModeNo > 0x13) {
2199 	      if( (HwInfo->jChipType != SIS_630) &&
2200 	          (HwInfo->jChipType != SIS_300) ) {
2201 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2202 	      }
2203 #if 0
2204 	      if(HwInfo->jChipType == SIS_730) {
2205 		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2206 		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2207 	      }
2208 #endif
2209 	   }
2210         }
2211 
2212      }
2213 
2214   }
2215 
2216 #ifdef TWDEBUG
2217   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2218 #endif
2219 
2220   return(VCLKIndex);
2221 }
2222 
2223 /*********************************************/
2224 /*        SET CRT2 MODE TYPE REGISTERS       */
2225 /*********************************************/
2226 
2227 static void
SiS_SetCRT2ModeRegs(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)2228 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2229                     PSIS_HW_INFO HwInfo)
2230 {
2231   USHORT i,j,modeflag;
2232   USHORT tempbl,tempcl,tempah=0;
2233 #ifdef SIS315H
2234   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
2235   USHORT tempah2, tempbl2;
2236 #endif
2237 
2238   if(ModeNo <= 0x13) {
2239      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2240   } else if(SiS_Pr->UseCustomMode) {
2241      modeflag = SiS_Pr->CModeFlag;
2242   } else {
2243      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2244   }
2245 
2246   /* BIOS does not do this (neither 301 nor LVDS) */
2247   /* (But it's harmless; see SetCRT2Offset) */
2248   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
2249 
2250   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2251 
2252      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2253      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2254 
2255   } else {
2256 
2257      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2258      if(HwInfo->jChipType >= SIS_315H) {
2259         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2260      }
2261 
2262      tempcl = SiS_Pr->SiS_ModeType;
2263 
2264      if(HwInfo->jChipType < SIS_315H) {
2265 
2266 #ifdef SIS300    /* ---- 300 series ---- */
2267 
2268         /* For 301BDH: (with LCD via LVDS) */
2269         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2270 	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2271 	   tempbl &= 0xef;
2272 	   tempbl |= 0x02;
2273 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2274 	      tempbl |= 0x10;
2275 	      tempbl &= 0xfd;
2276 	   }
2277 	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2278         }
2279 
2280         if(ModeNo > 0x13) {
2281            tempcl -= ModeVGA;
2282            if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
2283               tempah = ((0x10 >> tempcl) | 0x80);
2284            }
2285         } else tempah = 0x80;
2286 
2287         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2288 
2289 #endif  /* SIS300 */
2290 
2291      } else {
2292 
2293 #ifdef SIS315H    /* ------- 315/330 series ------ */
2294 
2295         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2296            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2297 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2298            }
2299         }
2300 
2301         if(ModeNo > 0x13) {
2302            tempcl -= ModeVGA;
2303            if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
2304               tempah = (0x08 >> tempcl);
2305               if (tempah == 0) tempah = 1;
2306               tempah |= 0x40;
2307            }
2308         } else tempah = 0x40;
2309 
2310         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2311 
2312 #endif  /* SIS315H */
2313 
2314      }
2315 
2316      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2317 
2318      if(HwInfo->jChipType < SIS_315H) {
2319         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2320      } else {
2321         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2322            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2323         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2324            if(IS_SIS740) {
2325 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2326 	   } else {
2327               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2328 	   }
2329         }
2330      }
2331 
2332      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2333 
2334         tempah = 0x01;
2335         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2336       	   tempah |= 0x02;
2337         }
2338         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2339       	   tempah ^= 0x05;
2340       	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2341               tempah ^= 0x01;
2342       	   }
2343         }
2344 
2345         if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2346 
2347         if(HwInfo->jChipType < SIS_315H) {
2348 
2349       	   tempah = (tempah << 5) & 0xFF;
2350       	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2351       	   tempah = (tempah >> 5) & 0xFF;
2352 
2353         } else {
2354 
2355       	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2356 
2357         }
2358 
2359         if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2360       	   tempah |= 0x10;
2361         }
2362 
2363         if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2364 	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2365 	      (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
2366 	      tempah |= 0x80;
2367 	   }
2368         } else {
2369 	   tempah |= 0x80;
2370         }
2371 
2372         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2373 	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2374       	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2375                  tempah |= 0x20;
2376 	      }
2377       	   }
2378         }
2379 
2380         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2381 
2382         tempah = 0;
2383 
2384 	if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2385 
2386         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2387 	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2388               tempah |= 0x40;
2389        	   }
2390         }
2391 
2392 	if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2393 	   (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)  ||
2394 	   ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
2395 	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2396 	   tempah |= 0x80;
2397         }
2398 
2399         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2400 
2401      } else {  /* LVDS */
2402 
2403         if(HwInfo->jChipType >= SIS_315H) {
2404 
2405 	   /* LVDS can only be slave in 8bpp modes */
2406 	   tempah = 0x80;
2407 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2408 	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2409 	         tempah |= 0x02;
2410 	      }
2411 	   }
2412 
2413 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2414               tempah |= 0x02;
2415     	   }
2416 
2417 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2418 	      tempah ^= 0x01;
2419 	   }
2420 
2421 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2422 	      tempah = 1;
2423 	   }
2424 
2425     	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2426 
2427         } else {
2428 
2429 	   tempah = 0;
2430 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2431               tempah |= 0x02;
2432     	   }
2433 	   tempah <<= 5;
2434 
2435 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2436 
2437 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2438 
2439         }
2440 
2441      }
2442 
2443   }  /* LCDA */
2444 
2445   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2446 
2447      if(HwInfo->jChipType >= SIS_315H) {
2448 
2449 #ifdef SIS315H
2450 
2451         unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2452 
2453 	/* The following is nearly unpreditable and varies from machine
2454 	 * to machine. Especially the 301DH seems to be a real trouble
2455 	 * maker. Some BIOSes simply set the registers (like in the
2456 	 * NoLCD-if-statements here), some set them according to the
2457 	 * LCDA stuff. It is very likely that some machines are not
2458 	 * treated correctly in the following, very case-orientated
2459 	 * code. What do I do then...?
2460 	 */
2461 
2462 	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2463 
2464         if(!(IS_SIS740)) {
2465            tempah = 0x04;						   /* For all bridges */
2466            tempbl = 0xfb;
2467            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2468               tempah = 0x00;
2469 	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2470 	         tempbl = 0xff;
2471 	      }
2472            }
2473            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2474 	}
2475 
2476 	/* The following two are responsible for eventually wrong colors
2477 	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2478 	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2479 	 * in a 650 box (Jake). What is the criteria?
2480 	 */
2481 
2482 	if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2483 	   tempah = 0x30;
2484 	   tempbl = 0xc0;
2485 	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2486 	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2487 	      tempah = 0x00;
2488 	      tempbl = 0x00;
2489 	   }
2490 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2491 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2492 	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2493 	   /* Fixes "TV-blue-bug" on 315+301 */
2494 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);     /* For 301   */
2495 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2496 	} else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2497 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xLV */
2498 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2499 	} else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2500 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xB-DH rev b0 (or "DH on 651"?) */
2501 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2502 	} else {
2503 	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB (and 301BDH rev b1) */
2504 	   tempbl = 0xcf; tempbl2 = 0x3f;
2505 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2506 	      tempah = tempah2 = 0x00;
2507 	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2508 		 tempbl = tempbl2 = 0xff;
2509 	      }
2510 	   }
2511 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2512 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2513 	}
2514 
2515 	if(IS_SIS740) {
2516 	   tempah = 0x80;
2517 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2518 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2519 	} else {
2520 	   tempah = 0x00;
2521            tempbl = 0x7f;
2522            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2523               tempbl = 0xff;
2524 	      if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2525            }
2526            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2527 	}
2528 
2529 #if 0
2530 	if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2531 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
2532 	}
2533 #endif
2534 
2535 #endif /* SIS315H */
2536 
2537      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2538 
2539         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2540 
2541         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2542            (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2543 	       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2544 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2545 	} else {
2546 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2547 	}
2548 
2549      }
2550 
2551   } else {  /* LVDS */
2552 
2553 #ifdef SIS315H
2554      if(HwInfo->jChipType >= SIS_315H) {
2555 
2556         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2557 
2558            tempah = 0x04;
2559 	   tempbl = 0xfb;
2560            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2561               tempah = 0x00;
2562 	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2563            }
2564 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2565 
2566 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2567 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2568 	   }
2569 
2570 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2571 
2572 	} else if(HwInfo->jChipType == SIS_550) {
2573 
2574 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2575 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2576 
2577 	}
2578 
2579      }
2580 #endif
2581 
2582   }
2583 
2584 }
2585 
2586 /*********************************************/
2587 /*            GET RESOLUTION DATA            */
2588 /*********************************************/
2589 
2590 USHORT
SiS_GetResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)2591 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2592 {
2593   if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2594   else               return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2595 }
2596 
2597 static void
SiS_GetCRT2ResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)2598 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2599                    PSIS_HW_INFO HwInfo)
2600 {
2601   USHORT xres,yres,modeflag=0,resindex;
2602 
2603   if(SiS_Pr->UseCustomMode) {
2604      xres = SiS_Pr->CHDisplay;
2605      if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2606      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2607      yres = SiS_Pr->CVDisplay;
2608      if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2609      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2610      return;
2611   }
2612 
2613   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2614 
2615   if(ModeNo <= 0x13) {
2616      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2617      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2618   } else {
2619      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2620      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2621      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2622   }
2623 
2624   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2625 
2626      if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2627         if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2628            if(yres == 350) yres = 400;
2629         }
2630         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2631  	   if(ModeNo == 0x12) yres = 400;
2632         }
2633      }
2634 
2635      if(modeflag & HalfDCLK)       xres *= 2;
2636      if(modeflag & DoubleScanMode) yres *= 2;
2637 
2638   }
2639 
2640   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2641 
2642 #if 0
2643         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2644            if(xres == 720) xres = 640;
2645 	}
2646 #endif
2647 
2648 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2649 	   switch(SiS_Pr->SiS_LCDResInfo) {
2650 	   case Panel_1024x768:
2651 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2652                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2653           	    if(yres == 350) yres = 357;
2654           	    if(yres == 400) yres = 420;
2655             	    if(yres == 480) yres = 525;
2656         	 }
2657       	      }
2658 	      break;
2659 	   case Panel_1280x1024:
2660 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2661 		 /* BIOS bug - does this regardless of scaling */
2662       		 if(yres == 400) yres = 405;
2663 	      }
2664       	      if(yres == 350) yres = 360;
2665       	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2666                  if(yres == 360) yres = 375;
2667       	      }
2668 	      break;
2669 	   case Panel_1600x1200:
2670 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2671         	 if(yres == 1024) yres = 1056;
2672       	      }
2673 	      break;
2674 	   }
2675 	}
2676 
2677   } else {
2678 
2679      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2680         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2681            if(xres == 720) xres = 640;
2682 	}
2683      } else if(xres == 720) xres = 640;
2684 
2685      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2686 	yres = 400;
2687         if(HwInfo->jChipType >= SIS_315H) {
2688            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2689         } else {
2690            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2691         }
2692         if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN)  yres = 480;
2693      }
2694 
2695   }
2696   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2697   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2698 }
2699 
2700 /*********************************************/
2701 /*           GET CRT2 TIMING DATA            */
2702 /*********************************************/
2703 
2704 static BOOLEAN
SiS_GetLVDSCRT1Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * ResIndex,USHORT * DisplayType)2705 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2706 		   USHORT RefreshRateTableIndex, USHORT *ResIndex,
2707 		   USHORT *DisplayType)
2708  {
2709   USHORT modeflag=0;
2710 
2711   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2712      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2713         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2714      }
2715   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2716      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))    return FALSE;
2717   } else
2718      return FALSE;
2719 
2720   if(ModeNo <= 0x13) {
2721      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2722      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2723   } else {
2724      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2725      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2726   }
2727 
2728   (*ResIndex) &= 0x3F;
2729 
2730   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2731      (*DisplayType) = 18;
2732      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2733      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2734       	(*DisplayType) += 2;
2735 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
2736 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2737 	}
2738 	if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2739 	   (*DisplayType) = 18;  /* PALM uses NTSC data */
2740 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2741 	} else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2742 	   (*DisplayType) = 20;  /* PALN uses PAL data  */
2743 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2744 	}
2745      }
2746   } else {
2747      switch(SiS_Pr->SiS_LCDResInfo) {
2748      case Panel_640x480:   (*DisplayType) = 50; break;
2749      case Panel_640x480_2: (*DisplayType) = 52; break;
2750      case Panel_640x480_3: (*DisplayType) = 54; break;
2751      case Panel_800x600:   (*DisplayType) =  0; break;
2752      case Panel_1024x600:  (*DisplayType) = 23; break;
2753      case Panel_1024x768:  (*DisplayType) =  4; break;
2754      case Panel_1152x768:  (*DisplayType) = 27; break;
2755      case Panel_1280x768:  (*DisplayType) = 40; break;
2756      case Panel_1280x1024: (*DisplayType) =  8; break;
2757      case Panel_1400x1050: (*DisplayType) = 14; break;
2758      case Panel_1600x1200: (*DisplayType) = 36; break;
2759      default: return FALSE;
2760      }
2761 
2762      if(modeflag & HalfDCLK) (*DisplayType)++;
2763 
2764      switch(SiS_Pr->SiS_LCDResInfo) {
2765      case Panel_640x480:
2766      case Panel_640x480_2:
2767      case Panel_640x480_3:
2768         break;
2769      default:
2770         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2771      }
2772 
2773      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2774         (*DisplayType) = 12;
2775 	if(modeflag & HalfDCLK) (*DisplayType)++;
2776      }
2777   }
2778 
2779 #if 0
2780   if(SiS_Pr->SiS_IF_DEF_FSTN) {
2781      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2782         (*DisplayType) = 22;
2783      }
2784   }
2785 #endif
2786 
2787   return TRUE;
2788 }
2789 
2790 static void
SiS_GetCRT2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * CRT2Index,USHORT * ResIndex,PSIS_HW_INFO HwInfo)2791 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2792 	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2793 	       PSIS_HW_INFO HwInfo)
2794 {
2795   USHORT tempbx=0,tempal=0,resinfo=0;
2796 
2797   if(ModeNo <= 0x13) {
2798      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2799   } else {
2800      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2801      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2802   }
2803 
2804   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2805 
2806      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2807 
2808         tempbx = SiS_Pr->SiS_LCDResInfo;
2809 	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2810 
2811 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2812 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
2813 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2814 	}
2815 
2816   	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {  /* Pass 1:1 only (center-screen handled outside) */
2817 	   tempbx = 100;
2818 	   if(ModeNo >= 0x13) {
2819 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2820 	      if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
2821 	         (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
2822 	         /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
2823 	         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        tempal = 0x08;
2824 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
2825 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
2826 	      }
2827 	   }
2828 	}
2829 
2830 #ifdef SIS315H
2831 	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2832 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2833 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2834 	         tempbx = 200;
2835 	         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2836 	      }
2837 	   }
2838 	}
2839 #endif
2840 
2841      } else {						  	/* TV */
2842 
2843      	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2844            /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2845            tempbx = 2;
2846            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2847 	      tempbx = 13;
2848               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2849            }
2850 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2851 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
2852 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2853 	   else 					tempbx = 5;
2854 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
2855        	} else {
2856            if(SiS_Pr->SiS_TVMode & TVSetPAL) 		tempbx = 3;
2857            else 					tempbx = 4;
2858            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) 	tempbx += 5;
2859        	}
2860 
2861      }
2862 
2863      tempal &= 0x3F;
2864 
2865      if(ModeNo > 0x13) {
2866         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2867       	   if(tempal == 6) tempal = 7;
2868            if((resinfo == SIS_RI_720x480) ||
2869 	      (resinfo == SIS_RI_720x576) ||
2870 	      (resinfo == SIS_RI_768x576)) {
2871 	      tempal = 6;
2872 	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
2873 	         if(resinfo == SIS_RI_720x480) tempal = 9;
2874 	      }
2875 	   }
2876 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2877               if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
2878 	         if(resinfo == SIS_RI_1024x768) tempal = 8;
2879 	      }
2880 	      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
2881 		 if((resinfo == SIS_RI_720x576) ||
2882 	            (resinfo == SIS_RI_768x576)) {
2883 	            tempal = 8;
2884 	         }
2885 		 if(resinfo == SIS_RI_1280x720) tempal = 9;
2886 	      }
2887 	   }
2888 	}
2889      }
2890 
2891      *CRT2Index = tempbx;
2892      *ResIndex = tempal;
2893 
2894   } else {   /* LVDS, 301B-DH (if running on LCD) */
2895 
2896      tempbx = 0;
2897      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2898         tempbx = 10;
2899 	if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2900         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2901 	   tempbx += 2;
2902 	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
2903 	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2904 	   }
2905 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2906 	      tempbx = 90;
2907 	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2908 	   } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2909 	      tempbx = 92;
2910 	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2911 	   }
2912         }
2913      } else {
2914         switch(SiS_Pr->SiS_LCDResInfo) {
2915 	case Panel_640x480:   tempbx = 6;  break;
2916 	case Panel_640x480_2: tempbx = 30; break;
2917 	case Panel_640x480_3: tempbx = 30; break;
2918 	case Panel_800x600:   tempbx = 0;  break;
2919 	case Panel_1024x600:  tempbx = 15; break;
2920 	case Panel_1024x768:  tempbx = 2;  break;
2921 	case Panel_1152x768:  tempbx = 17; break;
2922 	case Panel_1280x768:  tempbx = 18; break;
2923 	case Panel_1280x1024: tempbx = 4;  break;
2924 	case Panel_1400x1050: tempbx = 8;  break;
2925 	case Panel_1600x1200: tempbx = 21; break;
2926 	case Panel_Barco1366: tempbx = 80; break;
2927 	}
2928 
2929 	switch(SiS_Pr->SiS_LCDResInfo) {
2930 	case Panel_640x480:
2931 	case Panel_640x480_2:
2932 	case Panel_640x480_3:
2933 	   break;
2934 	default:
2935 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2936 	}
2937 
2938 	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
2939 
2940 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2941 	   tempbx = 82;
2942 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2943 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2944 	   tempbx = 84;
2945 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
2946 	}
2947 
2948      }
2949 
2950      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2951         if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
2952   	if(HwInfo->jChipType < SIS_315H) {
2953 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2954 	}
2955      }
2956 
2957      (*CRT2Index) = tempbx;
2958      (*ResIndex) = tempal & 0x1F;
2959   }
2960 }
2961 
2962 static void
SiS_GetRAMDAC2DATA(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)2963 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2964                    USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
2965 {
2966   USHORT tempax=0,tempbx=0;
2967   USHORT temp1=0,modeflag=0,tempcx=0;
2968   USHORT index;
2969 
2970   SiS_Pr->SiS_RVBHCMAX  = 1;
2971   SiS_Pr->SiS_RVBHCFACT = 1;
2972 
2973   if(ModeNo <= 0x13) {
2974 
2975      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2976      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
2977 
2978      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
2979      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
2980      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
2981 
2982   } else {
2983 
2984      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2985      index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2986 
2987      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
2988      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
2989      tempax &= 0x03FF;
2990      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
2991      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
2992      tempcx &= 0x0100;
2993      tempcx <<= 2;
2994      tempbx |= tempcx;
2995      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
2996 
2997   }
2998 
2999   if(temp1 & 0x01) tempbx |= 0x0100;
3000   if(temp1 & 0x20) tempbx |= 0x0200;
3001 
3002   tempax += 5;
3003 
3004   /* Charx8Dot is no more used (and assumed), so we set it */
3005   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3006      modeflag |= Charx8Dot;
3007   }
3008 
3009   if(modeflag & Charx8Dot) tempax *= 8;
3010   else                     tempax *= 9;
3011 
3012   if(modeflag & HalfDCLK)  tempax <<= 1;
3013 
3014   tempbx++;
3015 
3016   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3017   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3018 }
3019 
3020 static void
SiS_GetCRT2DataLVDS(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3021 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3022                     USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3023 {
3024    USHORT CRT2Index, ResIndex;
3025    const SiS_LVDSDataStruct *LVDSData = NULL;
3026 
3027    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3028 
3029    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3030       SiS_Pr->SiS_RVBHCMAX  = 1;
3031       SiS_Pr->SiS_RVBHCFACT = 1;
3032       SiS_Pr->SiS_NewFlickerMode = 0;
3033       SiS_Pr->SiS_RVBHRS = 50;
3034       SiS_Pr->SiS_RY1COE = 0;
3035       SiS_Pr->SiS_RY2COE = 0;
3036       SiS_Pr->SiS_RY3COE = 0;
3037       SiS_Pr->SiS_RY4COE = 0;
3038    }
3039 
3040    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3041 
3042 #ifdef SIS315H
3043       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3044          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3045 	    if(SiS_Pr->UseCustomMode) {
3046 	       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3047 	       SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3048 	    } else {
3049 	       if(ModeNo < 0x13) {
3050 	          ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3051 	       } else {
3052 	          ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3053 		  /* Special for our 3 types, others custom (works with default) */
3054 		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3055 	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
3056 	             if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        ResIndex = 0x08;
3057 		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
3058 		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
3059 	          }
3060 		  /* Special for 1280x720 TMDS <> LVDS */
3061 		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3062 	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  720)) {
3063 		     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
3064 		        if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
3065 		     }
3066 	          }
3067 	       }
3068 	       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3069                SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3070                SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3071                SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3072 	    }
3073 	 } else {
3074      	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3075             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3076 	 }
3077       } else {
3078 	 /* This handles custom modes and custom panels */
3079 	 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3080          SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3081          SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3082          SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3083 	 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3084 	 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3085       }
3086 
3087       SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3088 
3089 #endif
3090 
3091    } else {
3092 
3093       /* 301BDH needs LVDS Data */
3094       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3095 	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3096       }
3097 
3098       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3099                      		&CRT2Index, &ResIndex, HwInfo);
3100 
3101       /* 301BDH needs LVDS Data */
3102       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3103          SiS_Pr->SiS_IF_DEF_LVDS = 0;
3104       }
3105 
3106       switch (CRT2Index) {
3107       	 case  0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3108 	 case  1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
3109       	 case  2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3110 	 case  3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
3111       	 case  4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
3112       	 case  5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
3113 	 case  6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3114          case  7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
3115 	 case  8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
3116 	 case  9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
3117       	 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3118       	 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3119       	 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3120       	 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3121       	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
3122 	 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3123 	 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
3124 	 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
3125 	 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
3126 	 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
3127 	 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
3128 	 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
3129 	 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
3130 	 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
3131 	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3132 	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3133 	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3134 	 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
3135 	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3136 	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3137 	 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3138       	 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3139       	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3140       	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3141 	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* Super Overscan */
3142 	 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3143       }
3144 
3145       SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3146       SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3147       SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3148       SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3149 
3150       if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3151          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3152             if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3153 	       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3154                SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3155 	       if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3156 		  if(ResIndex < 0x08) {
3157 		     SiS_Pr->SiS_HDE = 1280;
3158                      SiS_Pr->SiS_VDE = 1024;
3159                   }
3160                }
3161             }
3162          }
3163       }
3164    }
3165 }
3166 
3167 static void
SiS_GetCRT2Data301(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3168 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3169                    USHORT RefreshRateTableIndex,
3170 		   PSIS_HW_INFO HwInfo)
3171 {
3172   UCHAR  *ROMAddr = NULL;
3173   USHORT tempax,tempbx,modeflag,romptr=0;
3174   USHORT resinfo,CRT2Index,ResIndex;
3175   const SiS_LCDDataStruct *LCDPtr = NULL;
3176   const SiS_TVDataStruct  *TVPtr  = NULL;
3177 #ifdef SIS315H
3178   SHORT  resinfo661;
3179 #endif
3180 
3181   if(ModeNo <= 0x13) {
3182      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3183      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3184   } else if(SiS_Pr->UseCustomMode) {
3185      modeflag = SiS_Pr->CModeFlag;
3186      resinfo = 0;
3187   } else {
3188      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3189      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3190 #ifdef SIS315H
3191      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3192      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3193          (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3194          (resinfo661 >= 0)                     &&
3195 	 (SiS_Pr->SiS_NeedRomModeData) ) {
3196         if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3197 	   if((romptr = (SISGETROMW(21)))) {
3198               romptr += (resinfo661 * 10);
3199 	      ROMAddr = HwInfo->pjVirtualRomBase;
3200 	   }
3201 	}
3202      }
3203 #endif
3204   }
3205 
3206   SiS_Pr->SiS_NewFlickerMode = 0;
3207   SiS_Pr->SiS_RVBHRS = 50;
3208   SiS_Pr->SiS_RY1COE = 0;
3209   SiS_Pr->SiS_RY2COE = 0;
3210   SiS_Pr->SiS_RY3COE = 0;
3211   SiS_Pr->SiS_RY4COE = 0;
3212 
3213   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3214 
3215   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3216 
3217      if(SiS_Pr->UseCustomMode) {
3218 
3219         SiS_Pr->SiS_RVBHCMAX  = 1;
3220         SiS_Pr->SiS_RVBHCFACT = 1;
3221         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3222         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3223         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3224         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3225 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3226         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3227 
3228      } else {
3229 
3230         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3231 
3232      }
3233 
3234   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3235 
3236      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3237                     &CRT2Index,&ResIndex,HwInfo);
3238 
3239      switch(CRT2Index) {
3240         case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3241         case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3242         case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3243         case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3244         case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3245         case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3246         case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3247         case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3248         case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3249         case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3250         case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3251         case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3252         case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3253         default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3254      }
3255 
3256      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3257      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3258      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3259      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3260      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3261      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3262      SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3263      SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3264      if(modeflag & HalfDCLK) {
3265         SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3266      }
3267 
3268      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3269 
3270         if((resinfo == SIS_RI_1024x768)  ||
3271            (resinfo == SIS_RI_1280x1024) ||
3272            (resinfo == SIS_RI_1280x720)) {
3273 	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3274 	}
3275 
3276         if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3277 
3278         SiS_Pr->SiS_HT = ExtHiTVHT;
3279         SiS_Pr->SiS_VT = ExtHiTVVT;
3280         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3281            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3282               SiS_Pr->SiS_HT = StHiTVHT;
3283               SiS_Pr->SiS_VT = StHiTVVT;
3284 #if 0
3285               if(!(modeflag & Charx8Dot)) {
3286                  SiS_Pr->SiS_HT = StHiTextTVHT;
3287                  SiS_Pr->SiS_VT = StHiTextTVVT;
3288               }
3289 #endif
3290            }
3291         }
3292 
3293      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3294 
3295         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3296            SiS_Pr->SiS_HT = 1650;
3297            SiS_Pr->SiS_VT = 750;
3298 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3299 	   SiS_Pr->SiS_HT = NTSCHT;
3300 	   SiS_Pr->SiS_VT = NTSCVT;
3301         } else {
3302            SiS_Pr->SiS_HT = NTSCHT;
3303 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3304            SiS_Pr->SiS_VT = NTSCVT;
3305         }
3306 
3307      } else {
3308 
3309         SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3310         SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3311         SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3312         SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3313 
3314         if(modeflag & HalfDCLK) {
3315            SiS_Pr->SiS_RY1COE = 0x00;
3316            SiS_Pr->SiS_RY2COE = 0xf4;
3317            SiS_Pr->SiS_RY3COE = 0x10;
3318            SiS_Pr->SiS_RY4COE = 0x38;
3319         }
3320 
3321         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3322            SiS_Pr->SiS_HT = NTSCHT;
3323 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3324            SiS_Pr->SiS_VT = NTSCVT;
3325         } else {
3326            SiS_Pr->SiS_HT = PALHT;
3327            SiS_Pr->SiS_VT = PALVT;
3328         }
3329 
3330      }
3331 
3332   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3333 
3334      SiS_Pr->SiS_RVBHCMAX  = 1;
3335      SiS_Pr->SiS_RVBHCFACT = 1;
3336 
3337      if(SiS_Pr->UseCustomMode) {
3338 
3339         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
3340         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
3341         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
3342         SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
3343 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3344         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3345 
3346      } else {
3347 
3348         BOOLEAN gotit = FALSE;
3349 
3350         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3351 
3352            SiS_Pr->SiS_VGAHT     = SiS_Pr->PanelHT;
3353            SiS_Pr->SiS_VGAVT     = SiS_Pr->PanelVT;
3354            SiS_Pr->SiS_HT        = SiS_Pr->PanelHT;
3355            SiS_Pr->SiS_VT        = SiS_Pr->PanelVT;
3356 	   gotit = TRUE;
3357 
3358 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3359 
3360 #ifdef SIS315H
3361 	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3362            SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3363            SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3364            SiS_Pr->SiS_VGAVT     = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3365            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3366            SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3367 	   if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3368 #endif
3369 
3370 	}
3371 
3372 	if(!gotit) {
3373 
3374            SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3375                           &CRT2Index,&ResIndex,HwInfo);
3376 
3377            switch(CRT2Index) {
3378 	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3379 	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3380 	      case Panel_1280x720      :
3381 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3382 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3383               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3384 	      case Panel_1280x768_3    :
3385 	      case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data;    break;
3386 	      case Panel_1280x800      :
3387 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3388 	      case Panel_1280x960      :
3389 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3390               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3391               case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3392               case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3393               case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3394               case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3395               case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3396 	      case Panel_1680x1050     :
3397 	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3398 	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3399 #ifdef SIS315H
3400 	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3401 	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3402 #endif
3403               default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3404            }
3405 
3406 #ifdef TWDEBUG
3407            xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3408 #endif
3409 
3410            SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3411            SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3412            SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3413            SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3414            SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3415            SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3416 
3417         }
3418 
3419 	tempax = SiS_Pr->PanelXRes;
3420         tempbx = SiS_Pr->PanelYRes;
3421 
3422 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3423            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3424               if(HwInfo->jChipType < SIS_315H) {
3425                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3426                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3427               }
3428            } else {
3429               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3430               else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3431               else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3432               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3433               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3434               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3435            }
3436 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3437            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3438            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3439            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3440 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3441            if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3442            else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3443            else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3444         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3445 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3446               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3447               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3448            }
3449         }
3450 
3451         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3452            tempax = SiS_Pr->SiS_VGAHDE;
3453            tempbx = SiS_Pr->SiS_VGAVDE;
3454         }
3455 
3456         SiS_Pr->SiS_HDE = tempax;
3457         SiS_Pr->SiS_VDE = tempbx;
3458      }
3459   }
3460 }
3461 
3462 static void
SiS_GetCRT2Data(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3463 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3464                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3465 {
3466 
3467   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3468 
3469      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3470         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3471      } else {
3472 	if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3473 	   /* Need LVDS Data for LCD on 301B-DH */
3474 	   SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3475 	} else {
3476 	   SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3477         }
3478      }
3479 
3480   } else {
3481 
3482      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3483 
3484   }
3485 }
3486 
3487 /*********************************************/
3488 /*         GET LVDS DES (SKEW) DATA          */
3489 /*********************************************/
3490 
3491 static void
SiS_GetLVDSDesPtr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * PanelIndex,USHORT * ResIndex,PSIS_HW_INFO HwInfo)3492 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3493                   USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3494 		  USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3495 {
3496   USHORT modeflag;
3497 
3498   if(ModeNo <= 0x13) {
3499      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3500      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3501   } else {
3502      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3503      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3504   }
3505 
3506   (*ResIndex) &= 0x1F;
3507   (*PanelIndex) = 0;
3508 
3509   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3510      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3511         (*PanelIndex) = 50;
3512         if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3513         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3514         /* Nothing special needed for SOverscan    */
3515         /* PALM uses NTSC data, PALN uses PAL data */
3516      }
3517   }
3518 
3519   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3520      *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3521      if(HwInfo->jChipType >= SIS_661) {
3522         /* As long as we don's use the BIOS tables, we
3523 	 * need to convert the TypeInfo as for 315 series
3524 	 */
3525         (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3526      }
3527      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3528         (*PanelIndex) += 16;
3529         if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3530            (*PanelIndex) = 32;
3531            if(modeflag & HalfDCLK) (*PanelIndex)++;
3532 	}
3533      }
3534   }
3535 
3536   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3537      if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3538         (*ResIndex) = 7;
3539         if(HwInfo->jChipType < SIS_315H) {
3540            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3541         }
3542      }
3543   }
3544 }
3545 
3546 static void
SiS_GetLVDSDesData(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3547 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3548                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3549 {
3550   USHORT modeflag;
3551   USHORT PanelIndex,ResIndex;
3552   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
3553 
3554   SiS_Pr->SiS_LCDHDES = 0;
3555   SiS_Pr->SiS_LCDVDES = 0;
3556 
3557   if( (SiS_Pr->UseCustomMode) 		         ||
3558       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3559       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3560       ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3561        (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3562        (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3563      return;
3564   }
3565 
3566   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3567 
3568 #ifdef SIS315H
3569      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3570         /* non-pass 1:1 only, see above */
3571         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3572            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3573 	}
3574 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3575 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3576 	}
3577      }
3578      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3579         switch(SiS_Pr->SiS_CustomT) {
3580         case CUT_UNIWILL1024:
3581         case CUT_UNIWILL10242:
3582         case CUT_CLEVO1400:
3583 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3584 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3585 	   }
3586 	   break;
3587 	}
3588 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3589 	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3590 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3591 	   }
3592 	}
3593      }
3594 #endif
3595 
3596   } else {
3597 
3598      SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3599                        &PanelIndex, &ResIndex, HwInfo);
3600 
3601      switch(PanelIndex) {
3602      	case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;    break;   /* ---  */
3603      	case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;    break;
3604      	case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;    break;
3605      	case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;    break;
3606      	case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;    break;
3607      	case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;    break;
3608      	case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;    break;
3609      	case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;    break;
3610      	case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;    break;
3611      	case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;    break;
3612      	case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;    break;
3613      	case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;    break;
3614      	case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;    break;
3615      	case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;    break;
3616      	case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;    break;
3617      	case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;    break;
3618      	case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;    break;    /* --- */
3619      	case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;    break;
3620      	case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;    break;
3621      	case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;    break;
3622      	case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;    break;
3623      	case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;    break;
3624      	case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;    break;
3625      	case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;    break;
3626      	case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;    break;
3627      	case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;    break;
3628      	case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;    break;
3629      	case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;    break;
3630      	case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;    break;
3631      	case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;    break;
3632      	case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;    break;
3633      	case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;    break;
3634 	case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;    break;    /* pass 1:1 */
3635 	case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;    break;
3636      	case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break;    /* TV */
3637      	case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3638      	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;  break;
3639      	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;  break;
3640 	default: return;
3641      }
3642 
3643      SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3644      SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3645 
3646      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3647         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3648         if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3649 	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3650         } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3651            if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3652               if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3653 	         if(HwInfo->jChipType < SIS_315H) {
3654 	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3655 	         } else {
3656 	            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
3657                     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3658 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3659                     if(!(modeflag & HalfDCLK)) {
3660                        SiS_Pr->SiS_LCDHDES = 320;
3661 	               if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3662 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3663                     }
3664                  }
3665               }
3666            }
3667         }
3668      }
3669   }
3670 }
3671 
3672 /*********************************************/
3673 /*           DISABLE VIDEO BRIDGE            */
3674 /*********************************************/
3675 
3676 /* NEVER use any variables (VBInfo), this will be called
3677  * from outside the context of modeswitch!
3678  * MUST call getVBType before calling this
3679  */
3680 void
SiS_DisableBridge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)3681 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3682 {
3683 #ifdef SIS315H
3684   USHORT tempah,pushax=0,modenum;
3685 #endif
3686   USHORT temp=0;
3687 
3688   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3689 
3690      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
3691 
3692         if(HwInfo->jChipType < SIS_315H) {
3693 
3694 #ifdef SIS300	   /* 300 series */
3695 
3696 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3697 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3698 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3699 	      } else {
3700 		 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3701 	      }
3702 	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3703 	   }
3704 	   if(SiS_Is301B(SiS_Pr)) {
3705 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3706 	      SiS_ShortDelay(SiS_Pr,1);
3707            }
3708 	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3709 	   SiS_DisplayOff(SiS_Pr);
3710 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3711 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3712 	   SiS_UnLockCRT2(SiS_Pr,HwInfo);
3713 	   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3714 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3715 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3716 	   }
3717 	   if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3718 	       (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3719 	      SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3720 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3721                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3722 	      } else {
3723 		 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3724 	      }
3725 	   }
3726 
3727 #endif  /* SIS300 */
3728 
3729         } else {
3730 
3731 #ifdef SIS315H	   /* 315 series */
3732 
3733 	   BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3734 	                      (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3735 
3736 	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3737 
3738            if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3739 
3740 #ifdef SET_EMI
3741 	      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3742 		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3743 	            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3744 		 }
3745 	      }
3746 #endif
3747 	      if( (modenum <= 0x13)                  ||
3748 		  (SiS_IsVAMode(SiS_Pr,HwInfo))      ||
3749 		  (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3750 	     	 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3751 		 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3752 	      }
3753 
3754 	      if(!custom1) {
3755 		 SiS_DDC2Delay(SiS_Pr,0xff00);
3756 		 SiS_DDC2Delay(SiS_Pr,0xe000);
3757 	         SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3758                  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3759 		 if(IS_SIS740) {
3760 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3761 		 }
3762 	         SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3763 	      }
3764 
3765            }
3766 
3767 	   if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3768 	      tempah = 0xef;
3769 	      if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3770 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3771 	   }
3772 
3773 	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3774 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3775 	   }
3776 
3777 	   tempah = 0x3f;
3778 	   if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3779 	      tempah = 0x7f;
3780 	      if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3781 	   }
3782 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3783 
3784            if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3785 	      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3786 
3787 	      SiS_DisplayOff(SiS_Pr);
3788 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3789 		 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3790 	      }
3791 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3792 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3793 
3794 	   }
3795 
3796 	   if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3797 	      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3798 
3799 	      if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3800 		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3801 		 SiS_DisplayOff(SiS_Pr);
3802 	      }
3803 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3804 
3805 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3806 		 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3807 	      }
3808 
3809 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3810 	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3811               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3812 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3813 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3814 
3815 	   }
3816 
3817 	   if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3818 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3819 	   }
3820 
3821 	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3822 
3823 	      if(!custom1) {
3824 
3825 	         if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3826 	            if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3827 	               if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3828 		          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3829                        }
3830                     }
3831 	         }
3832 
3833 	         SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3834 
3835 		 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3836 	            if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3837 		       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3838 		    }
3839 	         }
3840 
3841 	      } else {
3842 
3843 		 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3844 		    (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3845 		    if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3846 		       (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3847 		       SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3848 	     	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3849 		       SiS_PanelDelay(SiS_Pr, HwInfo, 4);
3850 		    }
3851 		 }
3852 
3853 	      }
3854            }
3855 
3856 #endif /* SIS315H */
3857 
3858 	}
3859 
3860      } else {     /* ============ For 301 ================ */
3861 
3862         if(HwInfo->jChipType < SIS_315H) {
3863 #ifdef SIS300
3864            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3865 	      SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3866 	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3867 	   }
3868 #endif
3869 	}
3870 
3871         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
3872         SiS_DisplayOff(SiS_Pr);
3873 
3874         if(HwInfo->jChipType >= SIS_315H) {
3875            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3876 	}
3877 
3878         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
3879 
3880 	if(HwInfo->jChipType >= SIS_315H) {
3881             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3882             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3883 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
3884 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3885 	} else {
3886 #ifdef SIS300
3887             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
3888 	    if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3889 	        (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3890 		SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3891 		SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3892 	    }
3893 #endif
3894 	}
3895 
3896       }
3897 
3898   } else {     /* ============ For LVDS =============*/
3899 
3900     if(HwInfo->jChipType < SIS_315H) {
3901 
3902 #ifdef SIS300	/* 300 series */
3903 
3904 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
3905 	   SiS_SetCH700x(SiS_Pr,0x090E);
3906 	}
3907 
3908 	if(HwInfo->jChipType == SIS_730) {
3909 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3910 	      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3911 	   }
3912 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3913 	      SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3914 	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3915 	   }
3916 	} else {
3917 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3918 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
3919   	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3920                     SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3921 		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
3922 		       SiS_DisplayOff(SiS_Pr);
3923 	            }
3924 	            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3925 	            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3926                  }
3927               }
3928 	   }
3929 	}
3930 
3931 	SiS_DisplayOff(SiS_Pr);
3932 
3933 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3934 
3935 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3936 	SiS_UnLockCRT2(SiS_Pr,HwInfo);
3937 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3938 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3939 
3940 	if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3941 	    (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3942 	   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3943 	   SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3944 	}
3945 
3946 #endif  /* SIS300 */
3947 
3948     } else {
3949 
3950 #ifdef SIS315H	/* 315 series */
3951 
3952         if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3953           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
3954         }
3955 
3956 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3957 
3958 	   if(HwInfo->jChipType == SIS_740) {
3959 	      temp = SiS_GetCH701x(SiS_Pr,0x61);
3960 	      if(temp < 1) {
3961 	         SiS_SetCH701x(SiS_Pr,0xac76);
3962 	         SiS_SetCH701x(SiS_Pr,0x0066);
3963 	      }
3964 
3965 	      if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3966 	          (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3967 	  	 SiS_SetCH701x(SiS_Pr,0x3e49);
3968 	      }
3969 	   }
3970 
3971 	   if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3972 	       (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
3973 	      SiS_Chrontel701xBLOff(SiS_Pr);
3974 	      SiS_Chrontel701xOff(SiS_Pr,HwInfo);
3975 	   }
3976 
3977 	   if(HwInfo->jChipType != SIS_740) {
3978 	      if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3979 	          (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3980 	   	 SiS_SetCH701x(SiS_Pr,0x0149);
3981   	      }
3982 	   }
3983 
3984 	}
3985 
3986 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
3987 	   SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3988 	   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3989 	}
3990 
3991 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
3992 	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3993 	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
3994 	   SiS_DisplayOff(SiS_Pr);
3995 	}
3996 
3997 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
3998 	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3999 	    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4000 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4001 	}
4002 
4003 	if(HwInfo->jChipType == SIS_740) {
4004 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4005 	}
4006 
4007 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4008 
4009 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4010 	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4011 	    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4012 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4013 	}
4014 
4015 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4016 	   if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4017 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4018 	      if(HwInfo->jChipType == SIS_550) {
4019 	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4020 	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4021 	      }
4022 	   }
4023 	} else {
4024 	   if(HwInfo->jChipType == SIS_740) {
4025 	      if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4026 	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4027 	      }
4028 	   } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4029 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4030 	   }
4031 	}
4032 
4033 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4034 	   if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4035 	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4036 	   } else {
4037 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4038 	   }
4039 	}
4040 
4041 	SiS_UnLockCRT2(SiS_Pr,HwInfo);
4042 
4043 	if(HwInfo->jChipType == SIS_550) {
4044 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4045 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4046 	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4047 	           (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4048 		   (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4049 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4050 	}
4051 
4052         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4053 	   if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4054 	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4055 	 	 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4056 		 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4057 	      }
4058 	   }
4059         }
4060 
4061 #endif  /* SIS315H */
4062 
4063     }  /* 315 series */
4064 
4065   }  /* LVDS */
4066 
4067 }
4068 
4069 /*********************************************/
4070 /*            ENABLE VIDEO BRIDGE            */
4071 /*********************************************/
4072 
4073 /* NEVER use any variables (VBInfo), this will be called
4074  * from outside the context of a mode switch!
4075  * MUST call getVBType before calling this
4076  */
4077 void
SiS_EnableBridge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)4078 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4079 {
4080   USHORT temp=0,tempah;
4081 #ifdef SIS315H
4082   USHORT temp1,pushax=0;
4083   BOOLEAN delaylong = FALSE;
4084 #endif
4085 
4086   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4087 
4088     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
4089 
4090       if(HwInfo->jChipType < SIS_315H) {
4091 
4092 #ifdef SIS300     /* 300 series */
4093 
4094 	 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4095 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4096 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4097 	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4098 	       SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4099 	    }
4100 	    if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4101 	       if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4102 	          SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4103 	       }
4104 	    }
4105 	 }
4106 
4107 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4108 	    (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4109 
4110 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4111             SiS_DisplayOn(SiS_Pr);
4112 	    SiS_UnLockCRT2(SiS_Pr,HwInfo);
4113 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4114 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4115       	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4116       	    } else {
4117       	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4118             }
4119 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4120 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4121 		  if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4122 		     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4123                   }
4124 		  SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4125                   SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4126                }
4127 	    }
4128 
4129 	 } else {
4130 
4131 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4132             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4133                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4134                if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4135             }
4136             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4137 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4138 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4139 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4140 	    SiS_DisplayOn(SiS_Pr);
4141 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4142 	       if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4143 	          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4144 		     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4145 		        SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4146                      }
4147 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4148 	 	  }
4149 	       }
4150 	    }
4151 
4152 	 }
4153 
4154 
4155 #endif /* SIS300 */
4156 
4157       } else {
4158 
4159 #ifdef SIS315H    /* 315 series */
4160 
4161 	 UCHAR   r30=0, r31=0, r32=0, r33=0, cr36=0;
4162 	 /* USHORT  emidelay=0; */
4163 
4164 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4165 	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4166 #ifdef SET_EMI
4167 	    if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4168 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4169 	    }
4170 #endif
4171 	 }
4172 
4173          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4174 	    tempah = 0x10;
4175 	    if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4176 	       if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4177 	       else 			         tempah = 0x08;
4178 	    }
4179 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4180 	 }
4181 
4182 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4183 
4184 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4185 	    SiS_DisplayOff(SiS_Pr);
4186 	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4187 	    if(IS_SIS740) {
4188 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4189 	    }
4190 
4191 	    if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4192                if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4193 		  SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4194 		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4195 		  SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4196 		  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4197 		     SiS_GenericDelay(SiS_Pr, 0x4500);
4198 		  }
4199 	       }
4200 	    }
4201 
4202 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4203                SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4204 	       delaylong = TRUE;
4205 	    }
4206 
4207 	 }
4208 
4209 	 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4210 
4211             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4212 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4213                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4214                if(!(tempah & SetCRT2ToRAMDAC)) {
4215 		  if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4216 	       }
4217             }
4218             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4219 
4220 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4221 
4222 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4223 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4224 
4225 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4226 	       SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4227 	    }
4228 
4229 	 } else {
4230 
4231 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4232 
4233 	 }
4234 
4235 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4236 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4237 
4238 	 tempah = 0xc0;
4239 	 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4240 	    tempah = 0x80;
4241 	    if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4242 	 }
4243          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4244 
4245 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4246 
4247 	    SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4248 
4249 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4250 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4251 
4252 	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4253 #ifdef SET_EMI
4254 	       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4255 	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4256 	       }
4257 #endif
4258 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4259 #ifdef SET_EMI
4260 	       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4261 
4262 		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4263 
4264 		  if(SiS_Pr->SiS_ROMNew) {
4265 		     UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
4266 		     USHORT romptr   = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4267 		     if(romptr) {
4268 		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4269 			SiS_Pr->EMI_30 = 0;
4270 			SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
4271 			SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
4272 			SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
4273 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4274 			/* emidelay = SISGETROMW((romptr + 0x22)); */
4275 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4276 		     }
4277 		  }
4278 
4279 		  /*                                              (P4_30|0x40)  */
4280 		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4281 		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4282 		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4283 		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4284 		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4285 		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4286 		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4287 		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4288 		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4289 
4290 		  if(SiS_Pr->HaveEMI) {
4291 		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4292 		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4293 		  } else {
4294 		     r30 = 0;
4295 		  }
4296 
4297 		  /* EMI_30 is read at driver start; however, the BIOS sets this
4298 		   * (if it is used) only if the LCD is in use. In case we caught
4299 		   * the machine while on TV output, this bit is not set and we
4300 		   * don't know if it should be set - hence our detection is wrong.
4301 		   * Work-around this here:
4302 		   */
4303 
4304 		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4305 		     switch((cr36 & 0x0f)) {
4306 		     case 2:
4307 			r30 |= 0x40;
4308 			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4309 			if(!SiS_Pr->HaveEMI) {
4310 			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4311 			   if((cr36 & 0xf0) == 0x30) {
4312 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4313 			   }
4314 			}
4315 			break;
4316 		     case 3:  /* 1280x1024 */
4317 			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4318 			if(!SiS_Pr->HaveEMI) {
4319 			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4320 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4321 			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4322 			   }
4323 			}
4324 			break;
4325 		     case 9:  /* 1400x1050 */
4326 			r30 |= 0x40;
4327 			if(!SiS_Pr->HaveEMI) {
4328 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4329 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4330 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4331 			   }
4332 			}
4333 			break;
4334 		     case 11: /* 1600x1200 - unknown */
4335 			r30 |= 0x40;
4336 			if(!SiS_Pr->HaveEMI) {
4337 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4338 			}
4339 		     }
4340                   }
4341 
4342 		  /* BIOS values don't work so well sometimes */
4343 		  if(!SiS_Pr->OverruleEMI) {
4344 #ifdef COMPAL_HACK
4345 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4346 		        if((cr36 & 0x0f) == 0x09) {
4347 			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4348 			}
4349  		     }
4350 #endif
4351 #ifdef COMPAQ_HACK
4352 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4353 		        if((cr36 & 0x0f) == 0x03) {
4354 			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4355 			}
4356 		     }
4357 #endif
4358 #ifdef ASUS_HACK
4359 		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4360 		        if((cr36 & 0x0f) == 0x02) {
4361 			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4362 			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4363 			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4364 			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4365 			}
4366 		     }
4367 #endif
4368  		  }
4369 
4370 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4371 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4372 		  }
4373 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4374 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4375 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4376 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4377 		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4378 		  } else {
4379 		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
4380 		  }
4381 
4382 		  if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4383 	              (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4384 	             if(r30 & 0x40) {
4385 		        SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4386 			if(delaylong) {
4387 			   SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4388 			   delaylong = FALSE;
4389 			}
4390 			SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4391 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4392 			   SiS_GenericDelay(SiS_Pr, 0x500);
4393 			}
4394 	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4395 	             }
4396 		  }
4397 	       }
4398 #endif
4399 	    }
4400 
4401 	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4402 	       if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4403 		  SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4404 		  if(delaylong) {
4405 		     SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4406 		  }
4407                   SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4408 		  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4409 	 	     SiS_GenericDelay(SiS_Pr, 0x500);
4410 		  }
4411 		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4412 	       }
4413 	    }
4414 
4415 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4416 	    SiS_DisplayOn(SiS_Pr);
4417 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4418 
4419 	 }
4420 
4421 	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4422 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4423 	 }
4424 
4425 #endif /* SIS315H */
4426 
4427       }
4428 
4429     } else {	/* ============  For 301 ================ */
4430 
4431        if(HwInfo->jChipType < SIS_315H) {
4432           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4433              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4434 	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4435 	  }
4436        }
4437 
4438        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4439        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4440           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4441           if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4442        }
4443        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4444 
4445        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4446 
4447        if(HwInfo->jChipType >= SIS_315H) {
4448           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4449           if(!(temp & 0x80)) {
4450              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4451 	  }
4452        }
4453 
4454        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4455 
4456        SiS_VBLongWait(SiS_Pr);
4457        SiS_DisplayOn(SiS_Pr);
4458        if(HwInfo->jChipType >= SIS_315H) {
4459           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4460        }
4461        SiS_VBLongWait(SiS_Pr);
4462 
4463        if(HwInfo->jChipType < SIS_315H) {
4464           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4465 	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4466              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4467 	  }
4468        }
4469 
4470     }
4471 
4472   } else {   /* =================== For LVDS ================== */
4473 
4474     if(HwInfo->jChipType < SIS_315H) {
4475 
4476 #ifdef SIS300    /* 300 series */
4477 
4478        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4479           if(HwInfo->jChipType == SIS_730) {
4480 	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4481 	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4482 	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4483 	  }
4484           SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4485 	  if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4486 	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4487 	  }
4488        }
4489 
4490        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4491        SiS_DisplayOn(SiS_Pr);
4492        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4493        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4494        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4495       	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4496        } else {
4497       	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4498        }
4499 
4500        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4501           if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4502 	     SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4503 	     SiS_SetCH700x(SiS_Pr,0x0B0E);
4504           }
4505        }
4506 
4507        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4508           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4509              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4510 	        if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4511 	 	   SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4512         	   SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4513 	        }
4514 	        SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4515                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4516              }
4517 	  }
4518        }
4519 
4520 #endif  /* SIS300 */
4521 
4522     } else {
4523 
4524 #ifdef SIS315H    /* 315 series */
4525 
4526        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4527           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4528        }
4529 
4530        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4531 	  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4532 	     SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4533 	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4534           }
4535        }
4536 
4537        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4538        SiS_UnLockCRT2(SiS_Pr,HwInfo);
4539 
4540        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4541 
4542        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4543           temp = SiS_GetCH701x(SiS_Pr,0x66);
4544 	  temp &= 0x20;
4545 	  SiS_Chrontel701xBLOff(SiS_Pr);
4546        }
4547 
4548        if(HwInfo->jChipType != SIS_550) {
4549           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4550        }
4551 
4552        if(HwInfo->jChipType == SIS_740) {
4553           if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4554              if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4555 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4556 	     }
4557 	  }
4558        }
4559 
4560        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4561        if(!(temp1 & 0x80)) {
4562           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4563        }
4564 
4565        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4566           if(temp) {
4567 	     SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4568 	  }
4569        }
4570 
4571        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4572           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4573 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4574 	     if(HwInfo->jChipType == SIS_550) {
4575 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4576 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4577 	     }
4578 	  }
4579        } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4580           if(HwInfo->jChipType != SIS_740) {
4581              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4582 	  }
4583        }
4584 
4585        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4586           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4587        }
4588 
4589        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4590        	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4591              SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4592           }
4593           if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4594 	      (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4595              SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4596           }
4597        }
4598 
4599        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4600        	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4601  	     if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4602 	         (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4603 	     	SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4604 	     	SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4605              }
4606        	  }
4607        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4608        	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4609 	     if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4610 		SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4611 		SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4612 	     }
4613 	  }
4614        }
4615 
4616 #endif  /* SIS315H */
4617 
4618     } /* 310 series */
4619 
4620   }  /* LVDS */
4621 
4622 }
4623 
4624 /*********************************************/
4625 /*         SET PART 1 REGISTER GROUP         */
4626 /*********************************************/
4627 
4628 /* Set CRT2 OFFSET / PITCH */
4629 static void
SiS_SetCRT2Offset(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI,PSIS_HW_INFO HwInfo)4630 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4631 	          USHORT RRTI, PSIS_HW_INFO HwInfo)
4632 {
4633   USHORT offset;
4634   UCHAR temp;
4635 
4636   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4637 
4638   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4639 
4640   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4641      (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4642      offset >>= 1;
4643   }
4644 
4645   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4646   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4647   temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4648   if(offset % 8) temp++;
4649   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4650 }
4651 
4652 /* Set CRT2 sync and PanelLink mode */
4653 static void
SiS_SetCRT2Sync(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)4654 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4655                 PSIS_HW_INFO HwInfo)
4656 {
4657   USHORT tempah=0,tempbl,infoflag;
4658 
4659   tempbl = 0xC0;
4660 
4661   if(SiS_Pr->UseCustomMode) {
4662      infoflag = SiS_Pr->CInfoFlag;
4663   } else {
4664      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4665   }
4666 
4667   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
4668 
4669      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4670         tempah = 0;
4671      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4672         tempah = SiS_Pr->SiS_LCDInfo;
4673      } else tempah = infoflag >> 8;
4674      tempah &= 0xC0;
4675      tempah |= 0x20;
4676      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4677      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4678         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4679            (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4680 	   tempah |= 0xf0;
4681         }
4682 	if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4683             (SiS_Pr->SiS_IF_DEF_DSTN) ||
4684             (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4685             (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4686            tempah |= 0x30;
4687         }
4688      }
4689      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4690         if(HwInfo->jChipType >= SIS_315H) {
4691            tempah >>= 3;
4692 	   tempah &= 0x18;
4693            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4694 	   /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4695         } else {
4696            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4697         }
4698      } else {
4699         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4700      }
4701 
4702   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4703 
4704      if(HwInfo->jChipType < SIS_315H) {
4705 
4706 #ifdef SIS300  /* ---- 300 series --- */
4707 
4708         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
4709 
4710 	   tempah = infoflag >> 8;
4711 	   tempbl = 0;
4712            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4713 	      if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4714 	         tempah = SiS_Pr->SiS_LCDInfo;
4715 		 tempbl = (tempah >> 6) & 0x03;
4716               }
4717            }
4718            tempah &= 0xC0;
4719            tempah |= 0x20;
4720            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4721   	   tempah |= 0xc0;
4722            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4723 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4724 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4725 	   }
4726 
4727         } else {							/* 630 - 301 */
4728 
4729            tempah = infoflag >> 8;
4730            tempah &= 0xC0;
4731            tempah |= 0x20;
4732 	   if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4733            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4734 
4735         }
4736 
4737 #endif /* SIS300 */
4738 
4739      } else {
4740 
4741 #ifdef SIS315H  /* ------- 315 series ------ */
4742 
4743         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - LVDS */
4744 
4745 	   tempbl = 0;
4746 	   if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4747 	      (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4748 	      tempah = infoflag >> 8;
4749 	      if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4750 	        tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4751 	      }
4752 	   } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
4753 	             (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4754        	      tempah = infoflag >> 8;
4755 	      tempbl = 0x03;
4756 	   } else {
4757               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4758 	      tempbl = (tempah >> 6) & 0x03;
4759 	      tempbl |= 0x08;
4760 	      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4761 	   }
4762 	   tempah &= 0xC0;
4763            tempah |= 0x20;
4764            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4765 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
4766            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4767 	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4768 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4769 	         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4770 	      }
4771 	   }
4772 
4773         } else {							/* 315 - TMDS */
4774 
4775            tempah = tempbl = infoflag >> 8;
4776 	   if(!SiS_Pr->UseCustomMode) {
4777 	      tempbl = 0;
4778 	      if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4779 	         if(ModeNo <= 0x13) {
4780 	            tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4781   	         }
4782 	      }
4783 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4784 	         if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4785 	            tempah = SiS_Pr->SiS_LCDInfo;
4786 		    tempbl = (tempah >> 6) & 0x03;
4787 	         }
4788 	      }
4789 	   }
4790 	   tempah &= 0xC0;
4791            tempah |= 0x20;
4792            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4793 	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4794 	      /* Imitate BIOS bug */
4795 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
4796 	   }
4797 	   if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4798 	      tempah >>= 3;
4799 	      tempah &= 0x18;
4800 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4801 	   } else {
4802               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4803 	      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4804 	         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4805 	            SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4806 		 }
4807 	      }
4808 	   }
4809 
4810         }
4811 #endif  /* SIS315H */
4812       }
4813    }
4814 }
4815 
4816 /* Set CRT2 FIFO on 300/630/730 */
4817 #ifdef SIS300
4818 static void
SiS_SetCRT2FIFO_300(SiS_Private * SiS_Pr,USHORT ModeNo,PSIS_HW_INFO HwInfo)4819 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4820                     PSIS_HW_INFO HwInfo)
4821 {
4822   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
4823   USHORT temp,index;
4824   USHORT modeidindex,refreshratetableindex;
4825   USHORT VCLK=0,MCLK,colorth=0,data2=0;
4826   USHORT tempal, tempah, tempbx, tempcl, tempax;
4827   USHORT CRT1ModeNo,CRT2ModeNo;
4828   USHORT SelectRate_backup;
4829   ULONG  data,eax;
4830   const UCHAR  LatencyFactor[] = {
4831   	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
4832         00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
4833         97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
4834         00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
4835         80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
4836         00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
4837         86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
4838         00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
4839   };
4840   const UCHAR  LatencyFactor730[] = {
4841          69, 63, 61,
4842 	 86, 79, 77,
4843 	103, 96, 94,
4844 	120,113,111,
4845 	137,130,128,    /* <-- last entry, data below */
4846 	137,130,128,	/* to avoid using illegal values */
4847 	137,130,128,
4848 	137,130,128,
4849 	137,130,128,
4850 	137,130,128,
4851 	137,130,128,
4852 	137,130,128,
4853 	137,130,128,
4854 	137,130,128,
4855 	137,130,128,
4856 	137,130,128,
4857   };
4858   const UCHAR ThLowB[]   = {
4859   	81, 4, 72, 6, 88, 8,120,12,
4860         55, 4, 54, 6, 66, 8, 90,12,
4861         42, 4, 45, 6, 55, 8, 75,12
4862   };
4863   const UCHAR ThTiming[] = {
4864   	1, 2, 2, 3, 0, 1, 1, 2
4865   };
4866 
4867   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
4868 
4869   if(!SiS_Pr->CRT1UsesCustomMode) {
4870 
4871      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
4872      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
4873      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
4874      SiS_Pr->SiS_SelectCRT2Rate = 0;
4875      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
4876 
4877      if(CRT1ModeNo >= 0x13) {
4878         index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
4879         index &= 0x3F;
4880         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
4881 
4882 	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
4883         colorth >>= 1;
4884         if(!colorth) colorth++;
4885      }
4886 
4887   } else {
4888 
4889      CRT1ModeNo = 0xfe;
4890      VCLK = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
4891      data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
4892      switch(data2) {							/* Get color depth */
4893         case 0 : colorth = 1; break;
4894         case 1 : colorth = 1; break;
4895         case 2 : colorth = 2; break;
4896         case 3 : colorth = 2; break;
4897         case 4 : colorth = 3; break;
4898         case 5 : colorth = 4; break;
4899         default: colorth = 2;
4900      }
4901 
4902   }
4903 
4904   if(CRT1ModeNo >= 0x13) {
4905     if(HwInfo->jChipType == SIS_300) {
4906        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
4907     } else {
4908        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
4909     }
4910     index &= 0x07;
4911     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
4912 
4913     data2 = (colorth * VCLK) / MCLK;
4914 
4915     temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4916     temp = ((temp & 0x00FF) >> 6) << 1;
4917     if(temp == 0) temp = 1;
4918     temp <<= 2;
4919     temp &= 0xff;
4920 
4921     data2 = temp - data2;
4922 
4923     if((28 * 16) % data2) {
4924       	data2 = (28 * 16) / data2;
4925       	data2++;
4926     } else {
4927       	data2 = (28 * 16) / data2;
4928     }
4929 
4930     if(HwInfo->jChipType == SIS_300) {
4931 
4932 	tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4933 	tempah &= 0x62;
4934 	tempah >>= 1;
4935 	tempal = tempah;
4936 	tempah >>= 3;
4937 	tempal |= tempah;
4938 	tempal &= 0x07;
4939 	tempcl = ThTiming[tempal];
4940 	tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
4941 	tempbx >>= 6;
4942 	tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4943 	tempah >>= 4;
4944 	tempah &= 0x0c;
4945 	tempbx |= tempah;
4946 	tempbx <<= 1;
4947 	tempal = ThLowB[tempbx + 1];
4948 	tempal *= tempcl;
4949 	tempal += ThLowB[tempbx];
4950 	data = tempal;
4951 
4952     } else if(HwInfo->jChipType == SIS_730) {
4953 
4954 #ifndef LINUX_XF86
4955        SiS_SetRegLong(0xcf8,0x80000050);
4956        eax = SiS_GetRegLong(0xcfc);
4957 #else
4958        eax = pciReadLong(0x00000000, 0x50);
4959 #endif
4960        tempal = (USHORT)(eax >> 8);
4961        tempal &= 0x06;
4962        tempal <<= 5;
4963 
4964 #ifndef LINUX_XF86
4965        SiS_SetRegLong(0xcf8,0x800000A0);
4966        eax = SiS_GetRegLong(0xcfc);
4967 #else
4968        eax = pciReadLong(0x00000000, 0xA0);
4969 #endif
4970        temp = (USHORT)(eax >> 28);
4971        temp &= 0x0F;
4972        tempal |= temp;
4973 
4974        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
4975        tempbx = 0;        /* -- do it like the BIOS anyway... */
4976        tempax = tempbx;
4977        tempbx &= 0xc0;
4978        tempbx >>= 6;
4979        tempax &= 0x0f;
4980        tempax *= 3;
4981        tempbx += tempax;
4982 
4983        data = LatencyFactor730[tempbx];
4984        data += 15;
4985        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4986        if(!(temp & 0x80)) data += 5;
4987 
4988     } else {
4989 
4990        index = 0;
4991        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4992        if(temp & 0x0080) index += 12;
4993 
4994 #ifndef LINUX_XF86
4995        SiS_SetRegLong(0xcf8,0x800000A0);
4996        eax = SiS_GetRegLong(0xcfc);
4997 #else
4998        /* We use pci functions X offers. We use tag 0, because
4999         * we want to read/write to the host bridge (which is always
5000         * 00:00.0 on 630, 730 and 540), not the VGA device.
5001         */
5002        eax = pciReadLong(0x00000000, 0xA0);
5003 #endif
5004        temp = (USHORT)(eax >> 24);
5005        if(!(temp&0x01)) index += 24;
5006 
5007 #ifndef LINUX_XF86
5008        SiS_SetRegLong(0xcf8,0x80000050);
5009        eax = SiS_GetRegLong(0xcfc);
5010 #else
5011        eax = pciReadLong(0x00000000, 0x50);
5012 #endif
5013        temp=(USHORT)(eax >> 24);
5014        if(temp & 0x01) index += 6;
5015 
5016        temp = (temp & 0x0F) >> 1;
5017        index += temp;
5018 
5019        data = LatencyFactor[index];
5020        data += 15;
5021        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5022        if(!(temp & 0x80)) data += 5;
5023     }
5024 
5025     data += data2;				/* CRT1 Request Period */
5026 
5027     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5028     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5029 
5030     if(!SiS_Pr->UseCustomMode) {
5031 
5032        CRT2ModeNo = ModeNo;
5033        SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5034 
5035        refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5036 
5037        index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5038                                refreshratetableindex,HwInfo);
5039        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                /* Get VCLK  */
5040 
5041        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5042           if(SiS_Pr->SiS_UseROM) {
5043 	     if(ROMAddr[0x220] & 0x01) {
5044                 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5045 	     }
5046           }
5047        }
5048 
5049     } else {
5050 
5051        CRT2ModeNo = 0xfe;
5052        VCLK = SiS_Pr->CSRClock;					/* Get VCLK */
5053 
5054     }
5055 
5056     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5057     colorth >>= 1;
5058     if(!colorth) colorth++;
5059 
5060     data = data * VCLK * colorth;
5061     if(data % (MCLK << 4)) {
5062       	data = data / (MCLK << 4);
5063       	data++;
5064     } else {
5065       	data = data / (MCLK << 4);
5066     }
5067 
5068     if(data <= 6) data = 6;
5069     if(data > 0x14) data = 0x14;
5070 
5071     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5072     if(HwInfo->jChipType == SIS_300) {
5073        if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5074        else             temp = (temp & (~0x1F)) | 0x16;
5075        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5076        	  temp = (temp & (~0x1F)) | 0x13;
5077        }
5078     } else {
5079        if( ( (HwInfo->jChipType == SIS_630) ||
5080              (HwInfo->jChipType == SIS_730) )  &&
5081            (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5082       {
5083 	  temp = (temp & (~0x1F)) | 0x1b;
5084       } else {
5085 	  temp = (temp & (~0x1F)) | 0x16;
5086       }
5087     }
5088     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5089 
5090     if( (HwInfo->jChipType == SIS_630) &&
5091         (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5092     {
5093    	if(data > 0x13) data = 0x13;
5094     }
5095     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5096 
5097   } else {  /* If mode <= 0x13, we just restore everything */
5098 
5099     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5100     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5101 
5102   }
5103 }
5104 #endif
5105 
5106 /* Set CRT2 FIFO on 315/330 series */
5107 #ifdef SIS315H
5108 static void
SiS_SetCRT2FIFO_310(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)5109 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5110 {
5111   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5112   if( (HwInfo->jChipType == SIS_760)      &&
5113       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5114       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5115       (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5116       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5117      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5118      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5119      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5120      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5121      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5122      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5123   } else {
5124      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5125   }
5126 
5127 }
5128 #endif
5129 
5130 static USHORT
SiS_GetVGAHT2(SiS_Private * SiS_Pr)5131 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5132 {
5133   ULONG tempax,tempbx;
5134 
5135   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5136   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5137   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5138   return((USHORT)tempax);
5139 }
5140 
5141 /* Set Part 1 / SiS bridge slave mode */
5142 static void
SiS_SetGroup1_301(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)5143 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5144                   PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5145 {
5146   USHORT  push1,push2;
5147   USHORT  tempax,tempbx,tempcx,temp;
5148   USHORT  resinfo,modeflag,xres=0;
5149   unsigned char p1_7, p1_8;
5150 
5151   if(ModeNo <= 0x13) {
5152      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5153      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5154   } else if(SiS_Pr->UseCustomMode) {
5155      modeflag = SiS_Pr->CModeFlag;
5156      resinfo = 0;
5157      xres = SiS_Pr->CHDisplay;
5158   } else {
5159      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5160      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5161      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5162   }
5163 
5164   /* The following is only done if bridge is in slave mode: */
5165 
5166   if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5167      if(xres >= 1600) {
5168         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5169      }
5170   }
5171 
5172   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
5173 
5174   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
5175 
5176   if(modeflag & Charx8Dot) tempcx = 0x08;
5177   else                     tempcx = 0x09;
5178 
5179   tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
5180   if(modeflag & HalfDCLK) tempax >>= 1;
5181   tempax = ((tempax / tempcx) - 1) & 0xff;
5182   tempbx = tempax;
5183 
5184   temp = tempax;
5185   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5186 
5187   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5188      if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5189         temp += 2;
5190      }
5191   }
5192   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5193      if(resinfo == SIS_RI_800x600) temp -= 2;
5194   }
5195   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
5196 
5197   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
5198 
5199   tempax = 0xFFFF;
5200   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5201   if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5202   if(modeflag & HalfDCLK)         tempax >>= 1;
5203   tempax = (tempax / tempcx) - 5;
5204   tempcx = tempax;
5205 
5206   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5207      temp = tempcx - 1;
5208      if(!(modeflag & HalfDCLK)) {
5209         temp -= 6;
5210         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5211            temp -= 2;
5212            if(ModeNo > 0x13) temp -= 10;
5213         }
5214      }
5215   } else {
5216      tempcx = (tempcx + tempbx) >> 1;
5217      temp = (tempcx & 0x00FF) + 2;
5218      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5219         temp--;
5220         if(!(modeflag & HalfDCLK)) {
5221            if((modeflag & Charx8Dot)) {
5222               temp += 4;
5223               if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5224               if(HwInfo->jChipType >= SIS_315H) {
5225 	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5226               }
5227            }
5228         }
5229      } else {
5230         if(!(modeflag & HalfDCLK)) {
5231            temp -= 4;
5232            if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5233 	      (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5234               if(SiS_Pr->SiS_VGAHDE >= 800) {
5235                  temp -= 7;
5236 	         if(HwInfo->jChipType < SIS_315H) {
5237                     if(SiS_Pr->SiS_ModeType == ModeEGA) {
5238                        if(SiS_Pr->SiS_VGAVDE == 1024) {
5239                           temp += 15;
5240                           if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5241 		  	     temp += 7;
5242                        }
5243                     }
5244 	         }
5245 		 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5246                     if(SiS_Pr->SiS_VGAHDE >= 1280) {
5247                        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5248 		    }
5249                  }
5250               }
5251            }
5252         }
5253      }
5254   }
5255 
5256   p1_7 = temp;
5257   p1_8 = 0x00;
5258 
5259   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5260      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5261         if(ModeNo <= 0x01) {
5262 	   p1_7 = 0x2a;
5263 	   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5264 	   else 	      			p1_8 = 0x41;
5265 	} else if(SiS_Pr->SiS_ModeType == ModeText) {
5266 	   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5267 	   else 	    			p1_7 = 0x55;
5268 	   p1_8 = 0x00;
5269 	} else if(ModeNo <= 0x13) {
5270 	   if(modeflag & HalfDCLK) {
5271 	      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5272 		 p1_7 = 0x30;
5273 		 p1_8 = 0x03;
5274 	      } else {
5275 	 	 p1_7 = 0x2f;
5276 		 p1_8 = 0x02;
5277 	      }
5278 	   } else {
5279 	      p1_7 = 0x5b;
5280 	      p1_8 = 0x03;
5281 	   }
5282 	} else if( ((HwInfo->jChipType >= SIS_315H) &&
5283 	            ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5284 	           ((HwInfo->jChipType < SIS_315H) &&
5285 		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5286 	   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5287 	      p1_7 = 0x30,
5288 	      p1_8 = 0x03;
5289 	   } else {
5290 	      p1_7 = 0x2f;
5291 	      p1_8 = 0x03;
5292 	   }
5293         }
5294      }
5295   }
5296 
5297   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5298      if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5299         p1_7 = 0x63;
5300 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5301      }
5302      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5303         if(!(modeflag & HalfDCLK)) {
5304 	   p1_7 = 0xb2;
5305 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5306 	      p1_7 = 0xab;
5307 	   }
5308 	}
5309      } else {
5310         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5311 	   if(modeflag & HalfDCLK) p1_7 = 0x30;
5312 	}
5313      }
5314   }
5315 
5316   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
5317   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
5318 
5319   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
5320 
5321   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5322 
5323   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
5324 
5325   tempcx = 0x121;
5326   tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
5327   if     (tempbx == 357) tempbx = 350;
5328   else if(tempbx == 360) tempbx = 350;
5329   else if(tempbx == 375) tempbx = 350;
5330   else if(tempbx == 405) tempbx = 400;
5331   else if(tempbx == 420) tempbx = 400;
5332   else if(tempbx == 525) tempbx = 480;
5333   push2 = tempbx;
5334   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5335      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5336       	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5337            if     (tempbx == 350) tempbx += 5;
5338            else if(tempbx == 480) tempbx += 5;
5339       	}
5340      }
5341   }
5342   tempbx -= 2;
5343   temp = tempbx & 0x00FF;
5344   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
5345 
5346   tempbx = push2;
5347   tempbx--;
5348   temp = tempbx & 0x00FF;
5349 #if 0
5350   /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5351   if(xxx()) {
5352       if(temp == 0xdf) temp = 0xda;
5353   }
5354 #endif
5355   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5356 
5357   temp = 0;
5358   if(modeflag & DoubleScanMode) temp |= 0x80;
5359   if(HwInfo->jChipType >= SIS_661) {
5360      if(tempbx & 0x0200)        temp |= 0x20;
5361      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5362      if(tempbx & 0x0100)  tempcx |= 0x000a;
5363      if(tempbx & 0x0400)  tempcx |= 0x1200;
5364   } else {
5365      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5366      if(tempbx & 0x0100)  tempcx |= 0x0002;
5367      if(tempbx & 0x0400)  tempcx |= 0x0600;
5368   }
5369 
5370   if(tempbx & 0x0200)  tempcx |= 0x0040;
5371 
5372   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
5373 
5374   tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5375 
5376   if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5377      if(resinfo != SIS_RI_1280x1024) {
5378 	tempbx += (tempax << 1);
5379      }
5380   } else if(HwInfo->jChipType >= SIS_315H) {
5381      if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5382 	tempbx += (tempax << 1);
5383      }
5384   }
5385 
5386   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5387      tempbx -= 10;
5388   } else {
5389      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5390         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5391            tempbx += 40;
5392 	   if(HwInfo->jChipType >= SIS_315H) {
5393 	      if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5394 	   }
5395 	}
5396      }
5397   }
5398   tempax >>= 2;
5399   tempax++;
5400   tempax += tempbx;
5401   push1 = tempax;
5402   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5403      if(tempbx <= 513)  {
5404      	if(tempax >= 513) tempbx = 513;
5405      }
5406   }
5407   temp = tempbx & 0x00FF;
5408   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
5409 
5410   tempbx--;
5411   temp = tempbx & 0x00FF;
5412   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5413 
5414   if(tempbx & 0x0100) tempcx |= 0x0008;
5415 
5416   if(tempbx & 0x0200) {
5417      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5418   }
5419   tempbx++;
5420 
5421   if(tempbx & 0x0100) tempcx |= 0x0004;
5422   if(tempbx & 0x0200) tempcx |= 0x0080;
5423   if(tempbx & 0x0400) {
5424      if(HwInfo->jChipType >= SIS_661)        tempcx |= 0x0800;
5425      else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5426      else                                    tempcx |= 0x0C00;
5427   }
5428 
5429   tempbx = push1;
5430   temp = tempbx & 0x000F;
5431   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
5432 
5433   if(tempbx & 0x0010) tempcx |= 0x2000;
5434 
5435   temp = tempcx & 0x00FF;
5436   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
5437 
5438   temp = (tempcx & 0xFF00) >> 8;
5439   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
5440 
5441   tempax = modeflag;
5442   temp = (tempax & 0xFF00) >> 8;
5443   temp = (temp >> 1) & 0x09;
5444   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01;		/* Always 8 dotclock */
5445   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
5446 
5447   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
5448 
5449   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
5450 
5451   temp = 0x00;
5452   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5453      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5454 	temp = 0x80;
5455      }
5456   }
5457   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
5458 
5459   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5460   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5461 }
5462 
5463 /* Setup panel link
5464  * This is used for LVDS, LCDA and Chrontel TV output
5465  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5466  */
5467 static void
SiS_SetGroup1_LVDS(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)5468 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5469                    PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5470 {
5471   USHORT modeflag,resinfo;
5472   USHORT push2,tempax,tempbx,tempcx,temp;
5473   ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5474   BOOLEAN islvds = FALSE, issis  = FALSE, chkdclkfirst = FALSE;
5475 #ifdef SIS300
5476   USHORT crt2crtc;
5477 #endif
5478 #ifdef SIS315H
5479   USHORT pushcx;
5480 #endif
5481 
5482   if(ModeNo <= 0x13) {
5483      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5484      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5485 #ifdef SIS300
5486      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5487 #endif
5488   } else if(SiS_Pr->UseCustomMode) {
5489      modeflag = SiS_Pr->CModeFlag;
5490      resinfo = 0;
5491 #ifdef SIS300
5492      crt2crtc = 0;
5493 #endif
5494   } else {
5495      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5496      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5497 #ifdef SIS300
5498      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5499 #endif
5500   }
5501 
5502   /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
5503   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
5504      ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
5505      islvds = TRUE;
5506   }
5507 
5508   /* is really sis if sis bridge, but not 301B-DH */
5509   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5510      issis = TRUE;
5511   }
5512 
5513   if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5514      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5515         chkdclkfirst = TRUE;
5516      }
5517   }
5518 
5519 #ifdef SIS315H
5520   if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5521      if(IS_SIS330) {
5522         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5523      } else if(IS_SIS740) {
5524         if(islvds) {
5525            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5526 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5527         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5528            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5529         }
5530      } else {
5531         if(islvds) {
5532            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5533 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5534         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5535            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5536 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5537 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5538 	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5539 	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5540 	      }
5541 	   }
5542         }
5543      }
5544   }
5545 #endif
5546 
5547   /* Horizontal */
5548 
5549   tempax = SiS_Pr->SiS_LCDHDES;
5550   if(islvds) {
5551      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5552         if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5553            if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5554               (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5555   	      tempax -= 8;
5556 	   }
5557 	}
5558      }
5559   }
5560 
5561   temp = (tempax & 0x0007);
5562   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5563   temp = (tempax >> 3) & 0x00FF;
5564   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5565 
5566   tempbx = SiS_Pr->SiS_HDE;
5567   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5568      if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5569         (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5570         tempbx >>= 1;
5571      }
5572      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5573         tempbx = SiS_Pr->PanelXRes;
5574      }
5575   }
5576 
5577   tempax += tempbx;
5578   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5579 
5580   temp = tempax;
5581   if(temp & 0x07) temp += 8;
5582   temp >>= 3;
5583   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5584 
5585   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5586 
5587   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5588      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5589         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5590      }
5591   }
5592 
5593   tempcx += tempax;
5594   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5595 
5596   temp = (tempcx >> 3) & 0x00FF;
5597   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5598      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5599         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5600            switch(ModeNo) {
5601            case 0x04:
5602            case 0x05:
5603            case 0x0d: temp = 0x56; break;
5604            case 0x10: temp = 0x60; break;
5605            case 0x13: temp = 0x5f; break;
5606            case 0x40:
5607            case 0x41:
5608            case 0x4f:
5609            case 0x43:
5610            case 0x44:
5611            case 0x62:
5612            case 0x56:
5613            case 0x53:
5614            case 0x5d:
5615            case 0x5e: temp = 0x54; break;
5616            }
5617         }
5618      }
5619   }
5620   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5621 
5622   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5623      temp += 2;
5624      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5625         temp += 8;
5626         if(SiS_Pr->PanelHRE != 999) {
5627            temp = tempcx + SiS_Pr->PanelHRE;
5628 	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5629 	   temp >>= 3;
5630         }
5631      }
5632   } else {
5633      temp += 10;
5634   }
5635 
5636   temp &= 0x1F;
5637   temp |= ((tempcx & 0x07) << 5);
5638 #if 0
5639   if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       		/* WRONG? BIOS loads cl, not ah */
5640 #endif
5641   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5642 
5643   /* Vertical */
5644 
5645   tempax = SiS_Pr->SiS_VGAVDE;
5646   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5647      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5648 	tempax = SiS_Pr->PanelYRes;
5649      }
5650   }
5651 
5652   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5653   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5654 
5655   push2 = tempbx;
5656 
5657   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5658   if(HwInfo->jChipType < SIS_315H) {
5659      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5660         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5661 	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5662 	}
5663      }
5664   }
5665   if(islvds) tempcx >>= 1;
5666   else       tempcx >>= 2;
5667 
5668   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5669       (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5670       (SiS_Pr->PanelVRS != 999) ) {
5671      tempcx = SiS_Pr->PanelVRS;
5672      tempbx += tempcx;
5673      if(issis) tempbx++;
5674   } else {
5675      tempbx += tempcx;
5676      if(HwInfo->jChipType < SIS_315H) tempbx++;
5677      else if(issis)                   tempbx++;
5678   }
5679 
5680   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;	/* BPLVRS  */
5681 
5682   temp = tempbx & 0x00FF;
5683   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5684      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5685         if(ModeNo == 0x10) temp = 0xa9;
5686      }
5687   }
5688   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5689 
5690   tempcx >>= 3;
5691   tempcx++;
5692 
5693   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5694      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5695         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5696      }
5697   }
5698 
5699   tempcx += tempbx;
5700   temp = tempcx & 0x000F;
5701   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5702 
5703   temp = ((tempbx >> 8) & 0x07) << 3;
5704   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5705      if(SiS_Pr->SiS_HDE != 640) {
5706         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5707      }
5708   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5709   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5710   tempbx = 0x87;
5711   if((HwInfo->jChipType >= SIS_315H) ||
5712      (HwInfo->jChipRevision >= 0x30)) {
5713      tempbx = 0x07;
5714      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5715 	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5716      }
5717      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5718      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5719 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5720 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5721 	} else {
5722 	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5723 	}
5724      }
5725   }
5726   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5727 
5728   tempbx = push2;                                      		/* BPLVDEE */
5729 
5730   tempcx = SiS_Pr->SiS_LCDVDES;                        		/* BPLVDES */
5731 
5732   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5733      switch(SiS_Pr->SiS_LCDResInfo) {
5734      case Panel_640x480:
5735         tempbx = SiS_Pr->SiS_VGAVDE - 1;
5736         tempcx = SiS_Pr->SiS_VGAVDE;
5737 	break;
5738      case Panel_800x600:
5739         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5740            if(resinfo == SIS_RI_800x600) tempcx++;
5741         }
5742 	break;
5743      case Panel_1024x600:
5744         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5745            if(resinfo == SIS_RI_1024x600) tempcx++;
5746            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5747 	      if(resinfo == SIS_RI_800x600) tempcx++;
5748 	   }
5749         }
5750 	break;
5751      case Panel_1024x768:
5752         if(HwInfo->jChipType < SIS_315H) {
5753            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5754               if(resinfo == SIS_RI_1024x768) tempcx++;
5755 	   }
5756         }
5757 	break;
5758      }
5759   }
5760 
5761   temp = ((tempbx >> 8) & 0x07) << 3;
5762   temp = temp | ((tempcx >> 8) & 0x07);
5763   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5764   /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++;  */
5765   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5766   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5767 
5768   /* Vertical scaling */
5769 
5770   if(HwInfo->jChipType < SIS_315H) {
5771 
5772 #ifdef SIS300      /* 300 series */
5773      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5774      temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5775      tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5776      if(temp) tempeax++;
5777 
5778      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5779 
5780      temp = (USHORT)(tempeax & 0x00FF);
5781      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5782      tempvcfact = temp;
5783 #endif /* SIS300 */
5784 
5785   } else {
5786 
5787 #ifdef SIS315H  /* 315 series */
5788      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5789      tempebx = SiS_Pr->SiS_VDE;
5790      temp = (tempeax % tempebx);
5791      tempeax = tempeax / tempebx;
5792      if(temp) tempeax++;
5793      tempvcfact = tempeax;
5794 
5795      temp = (USHORT)(tempeax & 0x00FF);
5796      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5797      temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5798      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5799      temp = (USHORT)((tempeax & 0x00030000) >> 16);
5800      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5801      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5802 
5803      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5804         temp = (USHORT)(tempeax & 0x00FF);
5805         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5806         temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5807         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5808         temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5809         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5810         temp = 0;
5811         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5812         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5813      }
5814 #endif
5815 
5816   }
5817 
5818   /* Horizontal scaling */
5819 
5820   tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5821   if(chkdclkfirst) {
5822      if(modeflag & HalfDCLK) tempeax >>= 1;
5823   }
5824   tempebx = tempeax << 16;
5825   if(SiS_Pr->SiS_HDE == tempeax) {
5826      tempecx = 0xFFFF;
5827   } else {
5828      tempecx = tempebx / SiS_Pr->SiS_HDE;
5829      if(HwInfo->jChipType >= SIS_315H) {
5830         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5831      }
5832   }
5833 
5834   if(HwInfo->jChipType >= SIS_315H) {
5835      tempeax = (tempebx / tempecx) - 1;
5836   } else {
5837      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5838   }
5839   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5840   temp = (USHORT)(tempecx & 0x00FF);
5841   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5842 
5843   if(HwInfo->jChipType >= SIS_315H) {
5844      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5845      tempbx = (USHORT)(tempeax & 0xFFFF);
5846   } else {
5847      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5848      tempbx = tempvcfact & 0x3f;
5849      if(tempbx == 0) tempbx = 64;
5850      tempeax /= tempbx;
5851      tempbx = (USHORT)(tempeax & 0xFFFF);
5852   }
5853   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5854   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5855      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5856      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
5857   }
5858 
5859   temp = ((tempbx >> 8) & 0x07) << 3;
5860   temp = temp | ((tempecx >> 8) & 0x07);
5861   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5862   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5863 
5864   tempecx >>= 16;   	                                  	/* BPLHCFACT  */
5865   if(!chkdclkfirst) {
5866      if(modeflag & HalfDCLK) tempecx >>= 1;
5867   }
5868   temp = (USHORT)((tempecx & 0xFF00) >> 8);
5869   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5870   temp = (USHORT)(tempecx & 0x00FF);
5871   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5872 
5873 #ifdef SIS315H
5874   if(HwInfo->jChipType >= SIS_315H) {
5875      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5876         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
5877            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5878 	}
5879      } else {
5880         if(islvds) {
5881            if(HwInfo->jChipType == SIS_740) {
5882               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5883            } else {
5884 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5885            }
5886         }
5887      }
5888   }
5889 #endif
5890 
5891 #ifdef SIS300
5892   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5893      int i;
5894      UCHAR TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
5895      UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5896      UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5897 
5898      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5899      for(i=0; i<5; i++) {
5900         SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
5901      }
5902      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5903         if(ModeNo == 0x13) {
5904 	   for(i=0; i<4; i++) {
5905 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5906 	   }
5907 	} else if(ModeNo == 0x10) {
5908 	   for(i=0; i<4; i++) {
5909 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5910 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5911 	   }
5912 	}
5913      }
5914      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5915   }
5916 #endif
5917 
5918 #ifdef SIS315H
5919   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5920      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5921      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5922      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5923      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5924      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5925      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5926      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5927      tempax = SiS_Pr->SiS_HDE;                       		/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5928      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5929         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5930      tempax += 64;
5931      temp = tempax & 0x00FF;
5932      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
5933      temp = ((tempax & 0xFF00) >> 8) << 3;
5934      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5935      tempax += 32;		                     		/* Blpe=lBlps+32 */
5936      temp = tempax & 0x00FF;
5937      if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
5938      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
5939      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/* Bflml=0 */
5940      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
5941 
5942      tempax = SiS_Pr->SiS_VDE;
5943      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5944         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5945      tempax >>= 1;
5946      temp = tempax & 0x00FF;
5947      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
5948      temp = ((tempax & 0xFF00) >> 8) << 3;
5949      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5950 
5951      tempeax = SiS_Pr->SiS_HDE;
5952      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5953         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
5954      tempeax <<= 2;                       			/* BDxFIFOSTOP = (HDE*4)/128 */
5955      tempebx = 128;
5956      temp = (USHORT)(tempeax % tempebx);
5957      tempeax = tempeax / tempebx;
5958      if(temp) tempeax++;
5959      temp = (USHORT)(tempeax & 0x003F);
5960      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
5961      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
5962      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5963      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5964      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
5965 
5966      tempax = SiS_Pr->SiS_HDE;
5967      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5968         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5969      tempax >>= 4;                        			/* BDxWadroff = HDE*4/8/8 */
5970      pushcx = tempax;
5971      temp = tempax & 0x00FF;
5972      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5973      temp = ((tempax & 0xFF00) >> 8) << 3;
5974      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5975 
5976      tempax = SiS_Pr->SiS_VDE;                             	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5977      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5978         SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5979      tempeax = (tempax * pushcx);
5980      tempebx = 0x00100000 + tempeax;
5981      temp = (USHORT)tempebx & 0x000000FF;
5982      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5983      temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
5984      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5985      temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
5986      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5987      temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
5988      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5989 
5990      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5991      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5992      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5993      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5994      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5995 
5996      if(SiS_Pr->SiS_IF_DEF_FSTN) {
5997         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5998         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5999         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6000         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6001         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6002         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6003         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6004         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6005         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6006         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6007         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6008         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6009         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6010         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6011         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6012         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6013         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6014         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6015         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6016         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6017      }
6018   }
6019 #endif  /* SIS315H */
6020 }
6021 
6022 /* Set Part 1 */
6023 static void
SiS_SetGroup1(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)6024 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6025               PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6026 {
6027   UCHAR   *ROMAddr = HwInfo->pjVirtualRomBase;
6028   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6029   USHORT  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6030 #ifdef SIS315H
6031   USHORT  tempbl=0;
6032 #endif
6033 
6034   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6035      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6036      return;
6037   }
6038 
6039   if(ModeNo <= 0x13) {
6040      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6041   } else if(SiS_Pr->UseCustomMode) {
6042      modeflag = SiS_Pr->CModeFlag;
6043   } else {
6044      CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6045      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6046      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6047   }
6048 
6049   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6050 
6051   if( ! ((HwInfo->jChipType >= SIS_315H) &&
6052          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6053          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6054 
6055      if(HwInfo->jChipType < SIS_315H ) {
6056 #ifdef SIS300
6057   	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6058 #endif
6059      } else {
6060 #ifdef SIS315H
6061         SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6062 #endif
6063      }
6064 
6065      /* 1. Horizontal setup */
6066 
6067      if(HwInfo->jChipType < SIS_315H ) {
6068 
6069 #ifdef SIS300   /* ------------- 300 series --------------*/
6070 
6071     	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
6072     	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6073 
6074     	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6075     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6076 
6077     	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6078     	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6079 
6080 	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6081     	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6082     	tempbx = pushbx + tempcx;
6083     	tempcx <<= 1;
6084     	tempcx += tempbx;
6085 
6086 	bridgeadd = 12;
6087 
6088 #endif /* SIS300 */
6089 
6090      } else {
6091 
6092 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
6093 
6094 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
6095 	if(modeflag & HalfDCLK) {
6096 	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6097 	      tempcx >>= 1;
6098 	   } else {
6099 	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
6100 	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6101 	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6102 	         tempcx = SiS_Pr->SiS_HT - tempax;
6103 	      }
6104 	   }
6105 	}
6106 	tempcx--;
6107 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6108 	temp = (tempcx >> 4) & 0xF0;
6109 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6110 
6111 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
6112 	tempbx = SiS_Pr->SiS_VGAHDE;
6113 	tempcx -= tempbx;
6114 	tempcx >>= 2;
6115 	if(modeflag & HalfDCLK) {
6116 	   tempbx >>= 1;
6117 	   tempcx >>= 1;
6118 	}
6119 	tempbx += 16;
6120 
6121 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6122 
6123 	pushbx = tempbx;
6124 	tempcx >>= 1;
6125 	tempbx += tempcx;
6126 	tempcx += tempbx;
6127 
6128 	bridgeadd = 16;
6129 
6130 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6131 	   if(HwInfo->jChipType >= SIS_661) {
6132 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6133 		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6134 		 if(resinfo == SIS_RI_1280x1024) {
6135 		    tempcx = (tempcx & 0xff00) | 0x30;
6136 		 } else if(resinfo == SIS_RI_1600x1200) {
6137 		    tempcx = (tempcx & 0xff00) | 0xff;
6138 		 }
6139 	      }
6140 	   }
6141         }
6142 
6143 #endif  /* SIS315H */
6144 
6145      }  /* 315/330 series */
6146 
6147      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6148 
6149         if(SiS_Pr->UseCustomMode) {
6150 	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6151 	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6152 	   tempax = SiS_Pr->SiS_VGAHT;
6153 	   if(modeflag & HalfDCLK) tempax >>= 1;
6154 	   tempax--;
6155 	   if(tempcx > tempax) tempcx = tempax;
6156 	}
6157 
6158 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6159 	   unsigned char cr4, cr14, cr5, cr15;
6160 	   if(SiS_Pr->UseCustomMode) {
6161 	      cr4  = SiS_Pr->CCRT1CRTC[4];
6162 	      cr14 = SiS_Pr->CCRT1CRTC[14];
6163 	      cr5  = SiS_Pr->CCRT1CRTC[5];
6164 	      cr15 = SiS_Pr->CCRT1CRTC[15];
6165 	   } else {
6166 	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6167 	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6168 	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6169 	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6170 	   }
6171            tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6172            tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6173 	   tempcx &= 0x00FF;
6174 	   tempcx |= (tempbx & 0xFF00);
6175            tempbx += bridgeadd;
6176            tempcx += bridgeadd;
6177 	   tempax = SiS_Pr->SiS_VGAHT;
6178 	   if(modeflag & HalfDCLK) tempax >>= 1;
6179 	   tempax--;
6180 	   if(tempcx > tempax) tempcx = tempax;
6181         }
6182 
6183         if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6184       	   tempbx = 1040;
6185       	   tempcx = 1044;   /* HWCursor bug! */
6186         }
6187 
6188      }
6189 
6190      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6191 
6192      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6193 
6194      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6195      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6196 
6197      /* 2. Vertical setup */
6198 
6199      tempcx = SiS_Pr->SiS_VGAVT - 1;
6200      temp = tempcx & 0x00FF;
6201 
6202      if(HwInfo->jChipType < SIS_661) {
6203         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6204 	   if(HwInfo->jChipType < SIS_315H) {
6205 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6206 	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6207 	            temp--;
6208 	         }
6209               }
6210 	   } else {
6211  	      temp--;
6212            }
6213         } else if(HwInfo->jChipType >= SIS_315H) {
6214 	   temp--;
6215 	}
6216      }
6217      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6218 
6219      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6220      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6221 
6222      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6223      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6224 
6225      if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6226         tempbx++;
6227    	tempax = tempbx;
6228 	tempcx++;
6229 	tempcx -= tempax;
6230 	tempcx >>= 2;
6231 	tempbx += tempcx;
6232 	if(tempcx < 4) tempcx = 4;
6233 	tempcx >>= 2;
6234 	tempcx += tempbx;
6235 	tempcx++;
6236      } else {
6237   	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6238   	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6239      }
6240 
6241      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6242 	if(SiS_Pr->UseCustomMode) {
6243 	   tempbx = SiS_Pr->CVSyncStart;
6244 	   tempcx = SiS_Pr->CVSyncEnd;
6245 	}
6246         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6247 	   unsigned char cr8, cr7, cr13;
6248 	   if(SiS_Pr->UseCustomMode) {
6249 	      cr8    = SiS_Pr->CCRT1CRTC[8];
6250 	      cr7    = SiS_Pr->CCRT1CRTC[7];
6251 	      cr13   = SiS_Pr->CCRT1CRTC[13];
6252 	      tempcx = SiS_Pr->CCRT1CRTC[9];
6253 	   } else {
6254 	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6255 	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6256 	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6257 	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6258 	   }
6259       	   tempbx = cr8;
6260       	   if(cr7  & 0x04) tempbx |= 0x0100;
6261       	   if(cr7  & 0x80) tempbx |= 0x0200;
6262       	   if(cr13 & 0x08) tempbx |= 0x0400;
6263        	}
6264      }
6265      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6266 
6267      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6268      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6269 
6270      /* 3. Panel delay compensation */
6271 
6272      if(HwInfo->jChipType < SIS_315H) {
6273 
6274 #ifdef SIS300  /* ---------- 300 series -------------- */
6275 
6276 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6277 	   temp = 0x20;
6278 	   if(HwInfo->jChipType == SIS_300) {
6279 	      temp = 0x10;
6280 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6281 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6282 	   }
6283 	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6284 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6285 	   }
6286 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6287 	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6288 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6289 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6290       	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6291       	      else 					    temp = 0x20;
6292     	   }
6293 	   if(SiS_Pr->SiS_UseROM) {
6294 	      if(ROMAddr[0x220] & 0x80) {
6295 	         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6296 	   	    temp = ROMAddr[0x221];
6297 		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6298 		    temp = ROMAddr[0x222];
6299 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6300 		    temp = ROMAddr[0x223];
6301 		 else
6302 		    temp = ROMAddr[0x224];
6303 		 temp &= 0x3c;
6304 	      }
6305 	   }
6306 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6307 	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC & 0x3c;
6308 	   }
6309 
6310 	} else {
6311 	   temp = 0x20;
6312 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6313 	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6314 	   }
6315 	   if(SiS_Pr->SiS_UseROM) {
6316 	      if(ROMAddr[0x220] & 0x80) {
6317 	         temp = ROMAddr[0x220] & 0x3c;
6318 	      }
6319 	   }
6320 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6321 	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6322 	   }
6323         }
6324 
6325     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6326 
6327 #endif  /* SIS300 */
6328 
6329      } else {
6330 
6331 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
6332 
6333         if(HwInfo->jChipType < SIS_661) {
6334 
6335 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6336 
6337 	      if(HwInfo->jChipType == SIS_740) temp = 0x03;
6338 	      else 		               temp = 0x00;
6339 
6340 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6341 	      tempbl = 0xF0;
6342 	      if(HwInfo->jChipType == SIS_650) {
6343 		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6344 		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6345 		 }
6346 	      }
6347 
6348 	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6349 		 temp = 0x08;
6350 		 tempbl = 0;
6351 		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6352 		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6353 		 }
6354 	      }
6355 
6356 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6357 	   }
6358 
6359 	} /* < 661 */
6360 
6361     	tempax = 0;
6362     	if(modeflag & DoubleScanMode) tempax |= 0x80;
6363     	if(modeflag & HalfDCLK)       tempax |= 0x40;
6364     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6365 
6366 #endif  /* SIS315H */
6367 
6368      }
6369 
6370   }  /* Slavemode */
6371 
6372   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6373      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6374         /* For 301BDH with LCD, we set up the Panel Link */
6375 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6376      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6377     	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6378      }
6379   } else {
6380      if(HwInfo->jChipType < SIS_315H) {
6381 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6382      } else {
6383 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6384            if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6385     	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6386            }
6387 	} else {
6388 	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6389 	}
6390      }
6391   }
6392 }
6393 
6394 /*********************************************/
6395 /*         SET PART 2 REGISTER GROUP         */
6396 /*********************************************/
6397 
6398 #ifdef SIS315H
6399 static UCHAR *
SiS_GetGroup2CLVXPtr(SiS_Private * SiS_Pr,int tabletype,PSIS_HW_INFO HwInfo)6400 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6401 {
6402    const UCHAR  *tableptr = NULL;
6403    USHORT       a, b, p = 0;
6404 
6405    a = SiS_Pr->SiS_VGAHDE;
6406    b = SiS_Pr->SiS_HDE;
6407    if(tabletype) {
6408       a = SiS_Pr->SiS_VGAVDE;
6409       b = SiS_Pr->SiS_VDE;
6410    }
6411 
6412    if(a < b) {
6413       tableptr = SiS_Part2CLVX_1;
6414    } else if(a == b) {
6415       tableptr = SiS_Part2CLVX_2;
6416    } else {
6417       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6418 	 tableptr = SiS_Part2CLVX_4;
6419       } else {
6420 	 tableptr = SiS_Part2CLVX_3;
6421       }
6422       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6423 	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
6424 	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
6425 	 else 				         	tableptr = SiS_Part2CLVX_5;
6426       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6427 	 tableptr = SiS_Part2CLVX_6;
6428       }
6429       do {
6430 	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6431 	 p += 0x42;
6432       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6433       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6434    }
6435    p += 2;
6436    return((UCHAR *)&tableptr[p]);
6437 }
6438 
6439 static void
SiS_SetGroup2_C_ELV(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)6440 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6441 	      	    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6442 {
6443    UCHAR *tableptr;
6444    int i, j;
6445    UCHAR temp;
6446 
6447    if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6448 
6449    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6450    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6451       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6452    }
6453    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6454       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6455       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6456          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6457       }
6458    }
6459    temp = 0x10;
6460    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6461    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6462 }
6463 
6464 static BOOLEAN
SiS_GetCRT2Part2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * CRT2Index,USHORT * ResIndex,PSIS_HW_INFO HwInfo)6465 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6466 		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6467 		    USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6468 {
6469 
6470   if(HwInfo->jChipType < SIS_315H) return FALSE;
6471 
6472   if(ModeNo <= 0x13)
6473      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6474   else
6475      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6476 
6477   (*ResIndex) &= 0x3f;
6478   (*CRT2Index) = 0;
6479 
6480   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6481      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6482         (*CRT2Index) = 200;
6483      }
6484   }
6485 
6486   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6487      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6488         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6489      }
6490   }
6491   return(((*CRT2Index) != 0));
6492 }
6493 #endif
6494 
6495 #ifdef SIS300
6496 static void
SiS_Group2LCDSpecial(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT crt2crtc)6497 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6498 {
6499    USHORT tempcx;
6500    const UCHAR atable[] = {
6501        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6502        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6503    };
6504 
6505    if(!SiS_Pr->UseCustomMode) {
6506       if( ( ( (HwInfo->jChipType == SIS_630) ||
6507               (HwInfo->jChipType == SIS_730) ) &&
6508             (HwInfo->jChipRevision > 2) )  &&
6509           (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6510           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6511           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6512          if(ModeNo == 0x13) {
6513             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6514             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6515             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6516          } else {
6517             if((crt2crtc & 0x3F) == 4) {
6518                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6519                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6520                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6521                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6522                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6523             }
6524          }
6525       }
6526 
6527       if(HwInfo->jChipType < SIS_315H) {
6528          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6529             crt2crtc &= 0x1f;
6530             tempcx = 0;
6531             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6532                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6533                   tempcx += 7;
6534                }
6535             }
6536             tempcx += crt2crtc;
6537             if(crt2crtc >= 4) {
6538                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6539             }
6540 
6541             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6542                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6543                   if(crt2crtc == 4) {
6544                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6545                   }
6546                }
6547             }
6548             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6549             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6550          }
6551       }
6552    }
6553 }
6554 
6555 /* For ECS A907. Highly preliminary. */
6556 static void
SiS_Set300Part2Regs(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT ModeNo)6557 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6558     		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6559 		    USHORT ModeNo)
6560 {
6561   USHORT crt2crtc, resindex;
6562   int    i,j;
6563   const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6564 
6565   if(HwInfo->jChipType != SIS_300) return;
6566   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6567   if(SiS_Pr->UseCustomMode) return;
6568 
6569   if(ModeNo <= 0x13) {
6570      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6571   } else {
6572      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6573   }
6574 
6575   resindex = crt2crtc & 0x3F;
6576   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6577   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6578 
6579   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6580   if(ModeNo > 0x13) {
6581      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6582      resindex = 4;
6583   }
6584 
6585   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6586   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6587   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6588         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6589   }
6590   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6591         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6592   }
6593   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6594         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6595   }
6596   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6597   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6598 }
6599 #endif
6600 
6601 static void
SiS_SetTVSpecial(SiS_Private * SiS_Pr,USHORT ModeNo)6602 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6603 {
6604   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6605   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6606   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6607 
6608   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6609      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6610         const UCHAR specialtv[] = {
6611 		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6612 		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6613 		0x58,0xe4,0x73,0xda,0x13
6614 	};
6615 	int i, j;
6616 	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6617 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6618 	}
6619 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6620 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6621 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6622 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6623 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6624 	   } else {
6625 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6626 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6627 	   }
6628 	}
6629      }
6630   } else {
6631      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6632         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6633         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6634         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6635      } else {
6636         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6637         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6638      }
6639   }
6640 }
6641 
6642 static void
SiS_SetGroup2_Tail(SiS_Private * SiS_Pr,USHORT ModeNo)6643 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6644 {
6645   USHORT temp;
6646 
6647   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6648      if(SiS_Pr->SiS_VGAVDE == 525) {
6649 	temp = 0xc3;
6650 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6651 	   temp++;
6652 	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6653 	}
6654 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6655 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6656      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6657 	temp = 0x4d;
6658 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6659 	   temp++;
6660 	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6661 	}
6662 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6663      }
6664   }
6665 
6666   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6667      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6668 	if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6669 	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6670 	   /* Not always for LV, see SetGrp2 */
6671 	}
6672 	temp = 1;
6673 	if(ModeNo <= 0x13) temp = 3;
6674 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6675      }
6676 #if 0
6677      /* 651+301C, for 1280x768 - do I really need that? */
6678      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6679         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6680 	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6681 	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6682 	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6683 	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
6684 	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6685 	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
6686 	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6687 	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6688 	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6689 	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6690 	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
6691 	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6692 	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6693 	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
6694 	   }
6695 	}
6696      }
6697 #endif
6698   }
6699 }
6700 
6701 static void
SiS_SetGroup2(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)6702 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6703 	      PSIS_HW_INFO HwInfo)
6704 {
6705   USHORT      i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6706   USHORT      push2, modeflag, crt2crtc, bridgeoffset;
6707   ULONG       longtemp;
6708   const       UCHAR *PhasePoint;
6709   const       UCHAR *TimingPoint;
6710 #ifdef SIS315H
6711   USHORT      resindex, CRT2Index;
6712   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6713 
6714   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6715 #endif
6716 
6717   if(ModeNo <= 0x13) {
6718      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6719      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6720   } else if(SiS_Pr->UseCustomMode) {
6721      modeflag = SiS_Pr->CModeFlag;
6722      crt2crtc = 0;
6723   } else {
6724      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6725      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6726   }
6727 
6728   temp = 0;
6729   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6730   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6731   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6732   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6733 
6734   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
6735 
6736   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6737 
6738   PhasePoint  = SiS_Pr->SiS_PALPhase;
6739   TimingPoint = SiS_Pr->SiS_PALTiming;
6740 
6741   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6742 
6743      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6744      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6745         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6746         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6747 	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6748 #if 0
6749            if(!(modeflag & Charx8Dot))  TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6750 #endif
6751         }
6752      }
6753 
6754   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6755 
6756      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      TimingPoint = &SiS_YPbPrTable[2][0];
6757      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6758      else					  TimingPoint = &SiS_YPbPrTable[0][0];
6759 
6760      PhasePoint = SiS_Pr->SiS_NTSCPhase;
6761 
6762   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6763 
6764      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6765          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6766 	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6767         PhasePoint = SiS_Pr->SiS_PALPhase2;
6768      }
6769 
6770   } else {
6771 
6772      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6773      PhasePoint  = SiS_Pr->SiS_NTSCPhase;
6774      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6775 	PhasePoint = SiS_Pr->SiS_PALPhase;
6776      }
6777 
6778      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6779 	 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6780 	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6781         PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6782 	if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6783 	   PhasePoint = SiS_Pr->SiS_PALPhase2;
6784 	}
6785      }
6786 
6787   }
6788 
6789   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6790      PhasePoint = SiS_Pr->SiS_PALMPhase;
6791      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6792 	 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6793 	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6794         PhasePoint = SiS_Pr->SiS_PALMPhase2;
6795      }
6796   }
6797 
6798   if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6799      PhasePoint = SiS_Pr->SiS_PALNPhase;
6800      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6801 	 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6802 	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6803 	PhasePoint = SiS_Pr->SiS_PALNPhase2;
6804      }
6805   }
6806 
6807   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6808      PhasePoint = SiS_Pr->SiS_SpecialPhase;
6809      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6810         PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6811      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6812         PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6813      }
6814   }
6815 
6816   for(i=0x31, j=0; i<=0x34; i++, j++) {
6817      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6818   }
6819 
6820   for(i=0x01, j=0; i<=0x2D; i++, j++) {
6821      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6822   }
6823   for(i=0x39; i<=0x45; i++, j++) {
6824      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6825   }
6826 
6827   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6828      if(SiS_Pr->SiS_ModeType != ModeText) {
6829         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6830      }
6831   }
6832 
6833   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6834 
6835   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6836   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6837   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6838   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6839 
6840   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) 	tempax = 950;
6841   else if(SiS_Pr->SiS_TVMode & TVSetPAL)      	tempax = 520;
6842   else 			            		tempax = 440; /* NTSC, YPbPr 525, 750 */
6843 
6844   if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
6845       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6846         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6847 
6848      tempax -= SiS_Pr->SiS_VDE;
6849      tempax >>= 2;
6850      tempax &= 0x00ff;
6851 
6852      temp = tempax + (USHORT)TimingPoint[0];
6853      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6854 
6855      temp = tempax + (USHORT)TimingPoint[1];
6856      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6857 
6858      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6859         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6860            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 19 */
6861            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 52 */
6862         } else {
6863            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6864            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6865         }
6866      }
6867 
6868   }
6869 
6870   tempcx = SiS_Pr->SiS_HT;
6871   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6872   tempcx--;
6873   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
6874   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6875   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6876 
6877   tempcx = SiS_Pr->SiS_HT >> 1;
6878   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6879   tempcx += 7;
6880   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6881   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6882 
6883   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6884   tempbx += tempcx;
6885   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6886   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6887 
6888   tempbx += 8;
6889   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6890      tempbx -= 4;
6891      tempcx = tempbx;
6892   }
6893   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6894 
6895   j += 2;
6896   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6897   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6898   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6899 
6900   tempcx += 8;
6901   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6902   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6903 
6904   tempcx = SiS_Pr->SiS_HT >> 1;
6905   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6906   j += 2;
6907   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6908   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6909 
6910   tempcx -= 11;
6911   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6912      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6913   }
6914   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6915 
6916   tempbx = SiS_Pr->SiS_VDE;
6917   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6918      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6919      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6920      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6921   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6922              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6923      tempbx >>= 1;
6924      if(HwInfo->jChipType >= SIS_315H) {
6925         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6926 	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6927 	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6928 	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6929 	      if(crt2crtc == 4) tempbx++;
6930 	   }
6931 	}
6932      }
6933      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6934         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6935 	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6936 	}
6937 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6938 	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6939         }
6940      }
6941   }
6942   tempbx -= 2;
6943   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6944 
6945   temp = (tempcx >> 8) & 0x0F;
6946   temp |= ((tempbx >> 2) & 0xC0);
6947   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6948      temp |= 0x10;
6949      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6950   }
6951   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6952 
6953   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6954      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6955   }
6956 
6957 #if 0
6958   /* TEST qqqq */
6959   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6960      for(i=0x01, j=0; i<=0x2D; i++, j++) {
6961         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6962      }
6963      for(i=0x39; i<=0x45; i++, j++) {
6964         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6965      }
6966   }
6967 #endif
6968 
6969   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6970      tempbx = SiS_Pr->SiS_VDE;
6971      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6972          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6973         tempbx >>= 1;
6974      }
6975      tempbx -= 3;
6976      temp = ((tempbx >> 3) & 0x60) | 0x18;
6977      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6978      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6979 
6980      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6981 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6982      }
6983   }
6984 
6985   tempbx = 0;
6986   if(!(modeflag & HalfDCLK)) {
6987      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6988         tempax = 0;
6989         tempbx |= 0x20;
6990      }
6991   }
6992 
6993   tempch = tempcl = 0x01;
6994   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6995      if(SiS_Pr->SiS_VGAHDE >= 1024) {
6996         if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
6997            tempch = 0x19;
6998 	   tempcl = 0x20;
6999            if(SiS_Pr->SiS_VGAHDE >= 1280) {
7000               tempch = 0x14;
7001               tempbx &= ~0x20;
7002            }
7003         }
7004      }
7005   }
7006 
7007   if(!(tempbx & 0x20)) {
7008      if(modeflag & HalfDCLK) tempcl <<= 1;
7009      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7010      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7011      tempax = longtemp / SiS_Pr->SiS_HDE;
7012      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7013      tempbx |= ((tempax >> 8) & 0x1F);
7014      tempcx = tempax >> 13;
7015   }
7016 
7017   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7018   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7019 
7020   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7021 
7022      tempcx &= 0x07;
7023      if(tempbx & 0x20) tempcx = 0;
7024      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7025 
7026      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7027         tempbx = 0x0382;
7028         tempcx = 0x007e;
7029      } else {
7030         tempbx = 0x0369;
7031         tempcx = 0x0061;
7032      }
7033      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7034      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7035      temp = (tempcx & 0x0300) >> 6;
7036      temp |= ((tempbx >> 8) & 0x03);
7037      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7038         temp |= 0x10;
7039 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7040 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7041      }
7042      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7043 
7044      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7045      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7046 
7047      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7048 
7049      if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7050         temp = 0;
7051         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7052         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7053      }
7054 
7055   }
7056 
7057   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7058      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7059         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7060         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7061      }
7062      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7063   }
7064 
7065   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7066      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7067         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7068      }
7069   }
7070 
7071   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7072 
7073   /* From here: Part2 LCD setup */
7074 
7075   tempbx = SiS_Pr->SiS_HDE;
7076   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7077   tempbx--;			         	/* RHACTE = HDE - 1 */
7078   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7079   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7080 
7081   temp = 0x01;
7082   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7083      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7084         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7085            temp = 0x02;
7086 	   if(HwInfo->jChipType >= SIS_315H) {
7087               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7088                  temp = 0x01;
7089 	      }
7090 	   }
7091         }
7092      }
7093   }
7094   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7095 
7096   tempbx = SiS_Pr->SiS_VDE - 1;
7097   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7098   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7099 
7100   tempcx = SiS_Pr->SiS_VT - 1;
7101   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7102   temp = (tempcx >> 3) & 0xE0;
7103   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7104      /* Enable dithering; only do this for 32bpp mode */
7105      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7106         temp |= 0x10;
7107      }
7108   }
7109   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7110 
7111   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7112   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7113 
7114   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7115   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7116 
7117 #ifdef SIS315H
7118   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7119                           			&CRT2Index, &resindex, HwInfo)) {
7120       switch(CRT2Index) {
7121         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7122 	case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7123 	default:  CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;   break;
7124       }
7125 
7126       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7127       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7128       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7129         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7130       }
7131       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7132         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7133       }
7134       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7135         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7136       }
7137       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7138       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7139 
7140       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7141 
7142 
7143   } else {
7144 #endif
7145 
7146     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7147     /*             Clevo dual-link 1024x768 */
7148     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7149     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7150 
7151     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7152        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7153           tempbx = SiS_Pr->SiS_VDE - 1;
7154           tempcx = SiS_Pr->SiS_VT - 1;
7155        } else {
7156           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7157 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7158        }
7159     } else {
7160        tempbx = SiS_Pr->PanelYRes;
7161        tempcx = SiS_Pr->SiS_VT;
7162        tempax = 1;
7163        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7164           tempax = SiS_Pr->PanelYRes;
7165 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7166           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7167              tempax = tempcx = 0;
7168           } else {
7169              tempax -= SiS_Pr->SiS_VDE;
7170           }
7171           tempax >>= 1;
7172        }
7173        tempcx -= tempax; /* lcdvdes */
7174        tempbx -= tempax; /* lcdvdee */
7175     }
7176 
7177     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7178 
7179 #ifdef TWDEBUG
7180     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7181 #endif
7182 
7183     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7184     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7185 
7186     temp = (tempbx >> 5) & 0x38;
7187     temp |= ((tempcx >> 8) & 0x07);
7188     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7189 
7190     tempax = SiS_Pr->SiS_VDE;
7191     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7192        tempax = SiS_Pr->PanelYRes;
7193     }
7194     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7195     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7196        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7197 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7198        }
7199     }
7200 
7201     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7202     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7203        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7204           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7205              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7206 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7207 	     else           { tempax >>= 2;           }
7208              tempbx -= (tempax - 1);
7209 	  } else {
7210 	     tempbx -= 10;
7211 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7212 	  }
7213        }
7214     }
7215     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7216        tempbx++;
7217        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7218           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7219 	     tempbx = 770;
7220 	     tempcx = 3;
7221 	  }
7222        }
7223     }
7224 
7225     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7226 
7227     if(SiS_Pr->UseCustomMode) {
7228        tempbx = SiS_Pr->CVSyncStart;
7229     }
7230 
7231 #ifdef TWDEBUG
7232     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7233 #endif
7234 
7235     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7236 
7237     temp = (tempbx >> 4) & 0xF0;
7238     tempbx += (tempcx + 1);
7239     temp |= (tempbx & 0x0F);
7240 
7241     if(SiS_Pr->UseCustomMode) {
7242        temp &= 0xf0;
7243        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7244     }
7245 
7246 #ifdef TWDEBUG
7247     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7248 #endif
7249 
7250     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7251 
7252 #ifdef SIS300
7253     SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7254 #endif
7255 
7256     bridgeoffset = 7;
7257     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)          bridgeoffset += 2;
7258     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7259     if(SiS_IsDualLink(SiS_Pr, HwInfo))        		 bridgeoffset++;
7260 
7261     temp = 0;
7262     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7263        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7264           temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7265 	  if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7266        }
7267     }
7268     temp += bridgeoffset;
7269     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7270     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7271 
7272     tempcx = SiS_Pr->SiS_HT;
7273     tempax = tempbx = SiS_Pr->SiS_HDE;
7274     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7275        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7276           tempax = SiS_Pr->PanelXRes;
7277           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7278        }
7279     }
7280     if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7281        tempcx >>= 1;
7282        tempbx >>= 1;
7283        tempax >>= 1;
7284     }
7285 
7286 #ifdef TWDEBUG
7287     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7288 #endif
7289 
7290     tempbx += bridgeoffset;
7291 
7292     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7293     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7294 
7295     tempcx = (tempcx - tempax) >> 2;
7296 
7297     tempbx += tempcx;
7298     push2 = tempbx;
7299 
7300     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7301        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7302           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7303              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7304 	  }
7305        }
7306     }
7307 
7308     if(SiS_Pr->UseCustomMode) {
7309        tempbx = SiS_Pr->CHSyncStart;
7310        if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7311        tempbx += bridgeoffset;
7312     }
7313 
7314 #ifdef TWDEBUG
7315     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7316 #endif
7317 
7318     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7319     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7320 
7321     tempbx = push2;
7322 
7323     tempcx <<= 1;
7324     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7325        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7326     }
7327     tempbx += tempcx;
7328 
7329     if(SiS_Pr->UseCustomMode) {
7330        tempbx = SiS_Pr->CHSyncEnd;
7331        if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7332        tempbx += bridgeoffset;
7333     }
7334 
7335 #ifdef TWDEBUG
7336     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7337 #endif
7338 
7339     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7340 
7341     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7342 
7343 #ifdef SIS300
7344     SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7345 #endif
7346 #ifdef SIS315H
7347   } /* CRT2-LCD from table */
7348 #endif
7349 }
7350 
7351 /*********************************************/
7352 /*         SET PART 3 REGISTER GROUP         */
7353 /*********************************************/
7354 
7355 static void
SiS_SetGroup3(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)7356 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7357               PSIS_HW_INFO HwInfo)
7358 {
7359   USHORT 	i;
7360   const UCHAR  	*tempdi;
7361 
7362   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7363 
7364 #ifndef SIS_CP
7365   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7366 #else
7367   SIS_CP_INIT301_CP
7368 #endif
7369 
7370   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7371      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7372      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7373   } else {
7374      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7375      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7376   }
7377 
7378   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7379      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7380      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7381      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7382   }
7383 
7384   tempdi = NULL;
7385   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7386      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7387      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7388         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7389      }
7390   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7391      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7392         tempdi = SiS_HiTVGroup3_1;
7393         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7394      }
7395   }
7396   if(tempdi) {
7397      for(i=0; i<=0x3E; i++) {
7398         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7399      }
7400      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7401 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7402 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7403 	}
7404      }
7405   }
7406 
7407 #ifdef SIS_CP
7408   SIS_CP_INIT301_CP2
7409 #endif
7410 }
7411 
7412 /*********************************************/
7413 /*         SET PART 4 REGISTER GROUP         */
7414 /*********************************************/
7415 
7416 #ifdef SIS315H
7417 static void
SiS_ShiftXPos(SiS_Private * SiS_Pr,int shift)7418 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7419 {
7420    USHORT temp, temp1, temp2;
7421 
7422    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7423    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7424    temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7425    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7426    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7427    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7428    temp = (USHORT)((int)(temp) + shift);
7429    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7430    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7431    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7432    temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7433    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7434    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7435 }
7436 
7437 static void
SiS_SetGroup4_C_ELV(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)7438 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7439                     USHORT ModeNo, USHORT ModeIdIndex)
7440 {
7441    USHORT temp, temp1, resinfo = 0;
7442 
7443    if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7444    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7445 
7446    if(ModeNo > 0x13) {
7447       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7448    }
7449 
7450    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7451    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7452    if(!(temp & 0x01)) {
7453       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7454       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7455       if(HwInfo->jChipType < SIS_661) {
7456          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7457       }
7458       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7459       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7460       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7461       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7462       else					   temp = 0x0402;
7463       if(HwInfo->jChipType >= SIS_661) {
7464          temp1 = 0;
7465 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7466 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7467 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7468 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7469       } else {
7470          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7471 	 if(temp1 == 0x01) temp |= 0x01;
7472 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7473 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7474       }
7475       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7476 
7477       if(HwInfo->jChipType >= SIS_661) { 		/* ? */
7478          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7479             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7480 	       if(resinfo == SIS_RI_1024x768) {
7481 	          SiS_ShiftXPos(SiS_Pr, 97);
7482 	       } else {
7483 	          SiS_ShiftXPos(SiS_Pr, 111);
7484 	       }
7485 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7486 	       SiS_ShiftXPos(SiS_Pr, 136);
7487 	    }
7488          }
7489       }
7490    }
7491 }
7492 #endif
7493 
7494 static void
SiS_SetCRT2VCLK(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7495 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7496                  USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7497 {
7498   USHORT vclkindex;
7499   USHORT temp, reg1, reg2;
7500 
7501   if(SiS_Pr->UseCustomMode) {
7502      reg1 = SiS_Pr->CSR2B;
7503      reg2 = SiS_Pr->CSR2C;
7504   } else {
7505      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7506                                  HwInfo);
7507      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7508      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7509   }
7510 
7511   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7512      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7513         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7514  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7515 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7516      } else {
7517         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7518         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7519      }
7520   } else {
7521      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7522      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7523      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7524   }
7525   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7526   temp = 0x08;
7527   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7528   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7529 }
7530 
7531 static void
SiS_SetGroup4(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7532 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7533   	      USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7534 {
7535   USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7536   ULONG tempebx,tempeax,templong;
7537 
7538   if(ModeNo <= 0x13) {
7539      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7540      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7541   } else if(SiS_Pr->UseCustomMode) {
7542      modeflag = SiS_Pr->CModeFlag;
7543      resinfo = 0;
7544   } else {
7545      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7546      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7547   }
7548 
7549   if(HwInfo->jChipType >= SIS_315H) {
7550      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7551         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7552            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7553         }
7554      }
7555   }
7556 
7557   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7558      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7559         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7560      }
7561   }
7562 
7563   if(HwInfo->jChipType >= SIS_315H) {
7564      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7565         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7566 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7567 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7568 	   }
7569 #ifdef SET_EMI
7570 	   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7571 	      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7572 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7573 	      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7574 	   }
7575 #endif
7576 	}
7577    	return;
7578      }
7579   }
7580 
7581   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7582 
7583   tempbx = SiS_Pr->SiS_RVBHCMAX;
7584   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7585 
7586   temp = (tempbx >> 1) & 0x80;
7587 
7588   tempcx = SiS_Pr->SiS_VGAHT - 1;
7589   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7590 
7591   temp |= ((tempcx >> 5) & 0x78);
7592 
7593   tempcx = SiS_Pr->SiS_VGAVT - 1;
7594   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7595   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7596 
7597   temp |= ((tempcx >> 8) & 0x07);
7598   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7599 
7600   tempbx = SiS_Pr->SiS_VGAHDE;
7601   if(modeflag & HalfDCLK)            tempbx >>= 1;
7602   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7603 
7604   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7605      temp = 0;
7606      if(tempbx > 800)        temp = 0x60;
7607   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7608      temp = 0;
7609      if(tempbx == 1024)      temp = 0xA0;
7610      else if(tempbx > 1024)  temp = 0xC0;
7611   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7612      temp = 0;
7613      if(tempbx >= 1280)      temp = 0x40;
7614      else if(tempbx >= 1024) temp = 0x20;
7615   } else {
7616      temp = 0x80;
7617      if(tempbx >= 1024)      temp = 0xA0;
7618   }
7619 
7620   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7621      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7622   }
7623 
7624   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7625 
7626   tempeax = SiS_Pr->SiS_VGAVDE;
7627   tempebx = SiS_Pr->SiS_VDE;
7628   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7629      if(!(temp & 0xE0)) tempebx >>=1;
7630   }
7631 
7632   tempcx = SiS_Pr->SiS_RVBHRS;
7633   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7634   tempcx >>= 8;
7635   tempcx |= 0x40;
7636 
7637   if(tempeax <= tempebx) {
7638      tempcx ^= 0x40;
7639   } else {
7640      tempeax -= tempebx;
7641   }
7642 
7643   tempeax *= (256 * 1024);
7644   templong = tempeax % tempebx;
7645   tempeax /= tempebx;
7646   if(templong) tempeax++;
7647 
7648   temp = (USHORT)(tempeax & 0x000000FF);
7649   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7650   temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7651   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7652   temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7653   temp |= (tempcx & 0x4F);
7654   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7655 
7656   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7657 
7658      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7659 
7660      /* Calc Linebuffer max address and set/clear decimode */
7661      tempbx = 0;
7662      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7663      tempax = SiS_Pr->SiS_VGAHDE;
7664      if(modeflag & HalfDCLK)            tempax >>= 1;
7665      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7666      if(tempax > 800) {
7667         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7668 	   tempax -= 800;
7669 	} else {  /* 651+301C: Only if TVNoHiviNoYPbPr */
7670 	   tempbx = 0x08;
7671            if(tempax == 1024) tempax *= 25;
7672            else	              tempax *= 20;
7673 	   temp = tempax % 32;
7674 	   tempax /= 32;
7675 	   if(temp) tempax++;
7676 	   tempax++;
7677 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7678 	      (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7679 	      if(resinfo == SIS_RI_1024x768) {
7680 	         /* Otherwise white line at right edge */
7681 	         tempax = (tempax & 0xff00) | 0x20;
7682 	      }
7683 	   }
7684 	}
7685      }
7686      tempax--;
7687      temp = ((tempax >> 4) & 0x30) | tempbx;
7688      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7689      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7690 
7691      temp = 0x0036; tempbx = 0xD0;
7692      if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7693 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7694      }
7695      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7696         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7697 	   temp |= 0x01;
7698 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7699 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7700   	         temp &= ~0x01;
7701 	      }
7702 	   }
7703 	}
7704      }
7705      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7706 
7707      tempbx = SiS_Pr->SiS_HT >> 1;
7708      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7709      tempbx -= 2;
7710      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7711      temp = (tempbx >> 5) & 0x38;
7712      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7713 
7714      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7715 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7716            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7717 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7718 	}
7719 	if(HwInfo->jChipType >= SIS_315H) {
7720 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7721 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7722 	   }
7723 	}
7724 #ifdef SET_EMI
7725 	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7726 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7727 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7728 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7729 	}
7730 #endif
7731      }
7732 
7733   }  /* 301B */
7734 
7735   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7736 }
7737 
7738 /*********************************************/
7739 /*         SET PART 5 REGISTER GROUP         */
7740 /*********************************************/
7741 
7742 static void
SiS_SetGroup5(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)7743 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7744               PSIS_HW_INFO HwInfo)
7745 {
7746 
7747   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7748 
7749   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7750      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7751         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7752         SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7753      }
7754   }
7755 }
7756 
7757 /*********************************************/
7758 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7759 /*********************************************/
7760 
7761 static void
SiS_ModCRT1CRTC(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7762 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7763                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7764 {
7765   USHORT tempah,i,modeflag,j;
7766   USHORT ResIndex,DisplayType;
7767   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7768 
7769   if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7770   else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7771 
7772   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7773      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7774      (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7775      return;
7776 
7777   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7778                           &ResIndex, &DisplayType))) {
7779      return;
7780   }
7781 
7782   if(HwInfo->jChipType < SIS_315H) {
7783      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7784   }
7785 
7786   switch(DisplayType) {
7787     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
7788     case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
7789     case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
7790     case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
7791     case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
7792     case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
7793     case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
7794     case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
7795     case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
7796     case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
7797     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
7798     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
7799     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
7800     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
7801     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
7802     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
7803     case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
7804     case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
7805     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7806     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7807     case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7808     case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7809     case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
7810     case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7811     case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7812     case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7813     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7814     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
7815     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
7816     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
7817     case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
7818     case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
7819     case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
7820     case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
7821     case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
7822     case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1;          break;
7823     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
7824     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
7825     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
7826     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
7827     case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
7828     case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
7829     case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
7830     case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
7831     case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
7832     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
7833     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
7834   }
7835 
7836   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7837 
7838   tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
7839   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
7840 
7841   for(i=0x02,j=1;i<=0x05;i++,j++){
7842     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7843     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7844   }
7845   for(i=0x06,j=5;i<=0x07;i++,j++){
7846     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7847     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7848   }
7849   for(i=0x10,j=7;i<=0x11;i++,j++){
7850     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7851     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7852   }
7853   for(i=0x15,j=9;i<=0x16;i++,j++){
7854     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7855     SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7856   }
7857   for(i=0x0A,j=11;i<=0x0C;i++,j++){
7858     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7859     SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7860   }
7861 
7862   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7863   tempah &= 0xE0;
7864   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7865 
7866   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7867   tempah &= 0x01;
7868   tempah <<= 5;
7869   if(modeflag & DoubleScanMode)  tempah |= 0x080;
7870   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7871 }
7872 
7873 /*********************************************/
7874 /*              SET CRT2 ECLK                */
7875 /*********************************************/
7876 
7877 static void
SiS_SetCRT2ECLK(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7878 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7879            USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7880 {
7881   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
7882   USHORT clkbase, vclkindex=0;
7883   UCHAR  sr2b, sr2c;
7884 
7885   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
7886 	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7887         if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
7888 	   RefreshRateTableIndex--;
7889 	}
7890 	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7891                                     RefreshRateTableIndex, HwInfo);
7892 	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7893   } else {
7894         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7895                                     RefreshRateTableIndex, HwInfo);
7896   }
7897 
7898   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7899   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7900 
7901   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7902      if(SiS_Pr->SiS_UseROM) {
7903 	if(ROMAddr[0x220] & 0x01) {
7904            sr2b = ROMAddr[0x227];
7905 	   sr2c = ROMAddr[0x228];
7906 	}
7907      }
7908   }
7909 
7910   clkbase = 0x02B;
7911   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7912      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7913     	clkbase += 3;
7914      }
7915   }
7916 
7917   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7918   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7919   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7920   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7921   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7922   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7923   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7924   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7925   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7926 }
7927 
7928 /*********************************************/
7929 /*           SET UP CHRONTEL CHIPS           */
7930 /*********************************************/
7931 
7932 static void
SiS_SetCHTVReg(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)7933 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7934                USHORT RefreshRateTableIndex)
7935 {
7936   USHORT temp, tempbx, tempcl;
7937   USHORT TVType, resindex;
7938   const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
7939 
7940   if(ModeNo <= 0x13)
7941      tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7942   else
7943      tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7944 
7945   TVType = 0;
7946   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7947   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7948   	TVType += 2;
7949 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7950 	   if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7951 	}
7952 	if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7953 		TVType = 4;
7954 		if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7955 	} else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7956 		TVType = 6;
7957 		if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7958 	}
7959   }
7960   switch(TVType) {
7961      case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7962      case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7963      case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
7964      case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7965      case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7966      case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7967      case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7968      case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7969      case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7970      default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7971   }
7972   resindex = tempcl & 0x3F;
7973 
7974   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7975 
7976 #ifdef SIS300
7977 
7978      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7979 
7980      /* We don't support modes >800x600 */
7981      if (resindex > 5) return;
7982 
7983      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7984     	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7985     	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
7986      } else {
7987     	SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7988     	SiS_SetCH700x(SiS_Pr,0x7109);	/* Black level for NTSC (113)*/
7989      }
7990 
7991      temp = CHTVRegData[resindex].Reg[0];
7992      tempbx=((temp&0x00FF)<<8)|0x00;	/* Mode register */
7993      SiS_SetCH700x(SiS_Pr,tempbx);
7994      temp = CHTVRegData[resindex].Reg[1];
7995      tempbx=((temp&0x00FF)<<8)|0x07;	/* Start active video register */
7996      SiS_SetCH700x(SiS_Pr,tempbx);
7997      temp = CHTVRegData[resindex].Reg[2];
7998      tempbx=((temp&0x00FF)<<8)|0x08;	/* Position overflow register */
7999      SiS_SetCH700x(SiS_Pr,tempbx);
8000      temp = CHTVRegData[resindex].Reg[3];
8001      tempbx=((temp&0x00FF)<<8)|0x0A;	/* Horiz Position register */
8002      SiS_SetCH700x(SiS_Pr,tempbx);
8003      temp = CHTVRegData[resindex].Reg[4];
8004      tempbx=((temp&0x00FF)<<8)|0x0B;	/* Vertical Position register */
8005      SiS_SetCH700x(SiS_Pr,tempbx);
8006 
8007      /* Set minimum flicker filter for Luma channel (SR1-0=00),
8008                 minimum text enhancement (S3-2=10),
8009    	        maximum flicker filter for Chroma channel (S5-4=10)
8010 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8011       */
8012      SiS_SetCH700x(SiS_Pr,0x2801);
8013 
8014      /* Set video bandwidth
8015             High bandwith Luma composite video filter(S0=1)
8016             low bandwith Luma S-video filter (S2-1=00)
8017 	    disable peak filter in S-video channel (S3=0)
8018 	    high bandwidth Chroma Filter (S5-4=11)
8019 	    =00110001=0x31
8020      */
8021      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
8022 
8023      /* Register 0x3D does not exist in non-macrovision register map
8024             (Maybe this is a macrovision register?)
8025       */
8026 #ifndef SIS_CP
8027      SiS_SetCH70xx(SiS_Pr,0x003D);
8028 #endif
8029 
8030      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8031             all other bits a read-only. Macrovision?
8032       */
8033      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8034 
8035      /* Register 0x11 only contains 3 writable bits (S0-S2) for
8036             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8037       */
8038      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8039 
8040      /* Clear DSEN
8041       */
8042      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8043 
8044      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
8045        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8046          if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
8047       	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);   	/* loop filter off */
8048            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
8049          } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
8050            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
8051            SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8052            SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8053            SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8054            SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8055            SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8056            SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8057            SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8058            SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);       /* Loop filter on for mode 23 */
8059            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
8060          }
8061        } else {
8062          if(resindex == 0x04) {     			 /* ----- 640x480 underscan; Mode 17 */
8063            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
8064            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8065          } else if(resindex == 0x05) {   		 /* ----- 800x600 underscan: Mode 24 */
8066 #if 0
8067            SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8068            SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);	 /* FSCI for mode 24 is 428,554,851 */
8069            SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);       /* 198b3a63 */
8070            SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8071            SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8072            SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8073            SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8074            SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8075            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off for mode 24 */
8076            SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);	 /* ACIV off, need to set FSCI */
8077 #endif     /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8078 	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
8079            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8080          }
8081        }
8082      } else {						/* ---- PAL ---- */
8083            /* We don't play around with FSCI in PAL mode */
8084          if(resindex == 0x04) {
8085            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
8086            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8087          } else {
8088            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
8089            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
8090          }
8091      }
8092 
8093 #endif  /* 300 */
8094 
8095   } else {
8096 
8097      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8098 
8099 #ifdef SIS315H
8100 
8101      /* We don't support modes >1024x768 */
8102      if (resindex > 6) return;
8103 
8104      temp = CHTVRegData[resindex].Reg[0];
8105      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8106         temp |= 0x10;
8107      }
8108      tempbx=((temp & 0x00FF) << 8) | 0x00;
8109      SiS_SetCH701x(SiS_Pr,tempbx);
8110 
8111      temp = CHTVRegData[resindex].Reg[1];
8112      tempbx=((temp & 0x00FF) << 8) | 0x01;
8113      SiS_SetCH701x(SiS_Pr,tempbx);
8114 
8115      temp = CHTVRegData[resindex].Reg[2];
8116      tempbx=((temp & 0x00FF) << 8) | 0x02;
8117      SiS_SetCH701x(SiS_Pr,tempbx);
8118 
8119      temp = CHTVRegData[resindex].Reg[3];
8120      tempbx=((temp & 0x00FF) << 8) | 0x04;
8121      SiS_SetCH701x(SiS_Pr,tempbx);
8122 
8123      temp = CHTVRegData[resindex].Reg[4];
8124      tempbx=((temp & 0x00FF) << 8) | 0x03;
8125      SiS_SetCH701x(SiS_Pr,tempbx);
8126 
8127      temp = CHTVRegData[resindex].Reg[5];
8128      tempbx=((temp & 0x00FF) << 8) | 0x05;
8129      SiS_SetCH701x(SiS_Pr,tempbx);
8130 
8131      temp = CHTVRegData[resindex].Reg[6];
8132      tempbx=((temp & 0x00FF) << 8) | 0x06;
8133      SiS_SetCH701x(SiS_Pr,tempbx);
8134 
8135      temp = CHTVRegData[resindex].Reg[7];
8136      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8137 	temp = 0x66;
8138      }
8139      tempbx=((temp & 0x00FF) << 8) | 0x07;
8140      SiS_SetCH701x(SiS_Pr,tempbx);
8141 
8142      temp = CHTVRegData[resindex].Reg[8];
8143      tempbx=((temp & 0x00FF) << 8) | 0x08;
8144      SiS_SetCH701x(SiS_Pr,tempbx);
8145 
8146      temp = CHTVRegData[resindex].Reg[9];
8147      tempbx=((temp & 0x00FF) << 8) | 0x15;
8148      SiS_SetCH701x(SiS_Pr,tempbx);
8149 
8150      temp = CHTVRegData[resindex].Reg[10];
8151      tempbx=((temp & 0x00FF) << 8) | 0x1f;
8152      SiS_SetCH701x(SiS_Pr,tempbx);
8153 
8154      temp = CHTVRegData[resindex].Reg[11];
8155      tempbx=((temp & 0x00FF) << 8) | 0x0c;
8156      SiS_SetCH701x(SiS_Pr,tempbx);
8157 
8158      temp = CHTVRegData[resindex].Reg[12];
8159      tempbx=((temp & 0x00FF) << 8) | 0x0d;
8160      SiS_SetCH701x(SiS_Pr,tempbx);
8161 
8162      temp = CHTVRegData[resindex].Reg[13];
8163      tempbx=((temp & 0x00FF) << 8) | 0x0e;
8164      SiS_SetCH701x(SiS_Pr,tempbx);
8165 
8166      temp = CHTVRegData[resindex].Reg[14];
8167      tempbx=((temp & 0x00FF) << 8) | 0x0f;
8168      SiS_SetCH701x(SiS_Pr,tempbx);
8169 
8170      temp = CHTVRegData[resindex].Reg[15];
8171      tempbx=((temp & 0x00FF) << 8) | 0x10;
8172      SiS_SetCH701x(SiS_Pr,tempbx);
8173 
8174      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8175      /* D1 should be set for PAL, PAL-N and NTSC-J,
8176         but I won't do that for PAL unless somebody
8177 	tells me to do so. Since the BIOS uses
8178 	non-default CIV values and blacklevels,
8179 	this might be compensated anyway.
8180       */
8181      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8182      SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8183 
8184 #endif	/* 315 */
8185 
8186   }
8187 
8188 #ifdef SIS_CP
8189   SIS_CP_INIT301_CP3
8190 #endif
8191 
8192 }
8193 
8194 void
SiS_Chrontel701xBLOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8195 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8196 {
8197   USHORT temp;
8198 
8199   /* Enable Chrontel 7019 LCD panel backlight */
8200   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8201      if(HwInfo->jChipType == SIS_740) {
8202         SiS_SetCH701x(SiS_Pr,0x6566);
8203      } else {
8204         temp = SiS_GetCH701x(SiS_Pr,0x66);
8205         temp |= 0x20;
8206 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8207      }
8208   }
8209 }
8210 
8211 void
SiS_Chrontel701xBLOff(SiS_Private * SiS_Pr)8212 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8213 {
8214   USHORT temp;
8215 
8216   /* Disable Chrontel 7019 LCD panel backlight */
8217   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8218      temp = SiS_GetCH701x(SiS_Pr,0x66);
8219      temp &= 0xDF;
8220      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8221   }
8222 }
8223 
8224 #ifdef SIS315H  /* ----------- 315 series only ---------- */
8225 
8226 static void
SiS_ChrontelPowerSequencing(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8227 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8228 {
8229   UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8230   UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8231   UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8232   UCHAR asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8233   UCHAR asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8234   UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8235   UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8236   UCHAR *tableptr = NULL;
8237   int i;
8238 
8239   /* Set up Power up/down timing */
8240 
8241   if(HwInfo->jChipType == SIS_740) {
8242      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8243         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8244         else    			          tableptr = table1024_740;
8245      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8246                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8247 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8248 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8249         else					  tableptr = table1400_740;
8250      } else return;
8251   } else {
8252      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8253         tableptr = table1024_650;
8254      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8255                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8256 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8257         tableptr = table1400_650;
8258      } else return;
8259   }
8260 
8261   for(i=0; i<5; i++) {
8262      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8263   }
8264 }
8265 
8266 static void
SiS_SetCH701xForLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8267 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8268 {
8269   UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8270                             0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8271   UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8272                             0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8273   UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8274    			    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8275   UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8276                             0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8277   UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8278   			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8279   UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8280                             0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8281   UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8282    		   	    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8283   UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8284                             0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8285   UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8286   			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8287   UCHAR *tableptr = NULL;
8288   USHORT tempbh;
8289   int i;
8290 
8291   if(HwInfo->jChipType == SIS_740) {
8292      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8293      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8294      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8295      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8296      else return;
8297   } else {
8298      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8299      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8300      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8301      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8302      else return;
8303   }
8304 
8305   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8306   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8307      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8308      if(tempbh == 0xc8) {
8309         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8310      } else if(tempbh == 0xdb) {
8311         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8312 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8313      } else if(tempbh == 0xde) {
8314         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8315      }
8316   }
8317 
8318   if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8319   else     			   tempbh = 0x0c;
8320 
8321   for(i = 0; i < tempbh; i++) {
8322      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8323   }
8324   SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8325   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8326   tempbh |= 0xc0;
8327   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8328 
8329   if(HwInfo->jChipType == SIS_740) {
8330      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8331      tempbh &= 0xfb;
8332      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8333      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8334      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8335      tempbh |= 0x40;
8336      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8337      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8338      tempbh &= 0x3f;
8339      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8340   }
8341 }
8342 
8343 static void
SiS_ChrontelResetVSync(SiS_Private * SiS_Pr)8344 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8345 {
8346   unsigned char temp, temp1;
8347 
8348   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8349   SiS_SetCH701x(SiS_Pr,0x3e49);
8350   temp = SiS_GetCH701x(SiS_Pr,0x47);
8351   temp &= 0x7f;	/* Use external VSYNC */
8352   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8353   SiS_LongDelay(SiS_Pr,3);
8354   temp = SiS_GetCH701x(SiS_Pr,0x47);
8355   temp |= 0x80;	/* Use internal VSYNC */
8356   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8357   SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8358 }
8359 
8360 void
SiS_Chrontel701xOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8361 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8362 {
8363   USHORT temp;
8364 
8365   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8366      if(HwInfo->jChipType == SIS_740) {
8367         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8368         temp |= 0x04;	/* Invert XCLK phase */
8369         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8370      }
8371      if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8372         temp = SiS_GetCH701x(SiS_Pr,0x01);
8373 	temp &= 0x3f;
8374 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8375 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8376      }
8377      if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8378         temp = SiS_GetCH701x(SiS_Pr,0x01);
8379 	temp &= 0x3f;
8380 	temp |= 0xc0;	/* Enable SCART + CVBS */
8381 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8382      }
8383      if(HwInfo->jChipType == SIS_740) {
8384         SiS_ChrontelResetVSync(SiS_Pr);
8385         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
8386      } else {
8387         SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
8388         temp = SiS_GetCH701x(SiS_Pr,0x49);
8389         if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8390            temp = SiS_GetCH701x(SiS_Pr,0x73);
8391 	   temp |= 0x60;
8392 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8393         }
8394         temp = SiS_GetCH701x(SiS_Pr,0x47);
8395         temp &= 0x7f;
8396         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8397         SiS_LongDelay(SiS_Pr,2);
8398         temp = SiS_GetCH701x(SiS_Pr,0x47);
8399         temp |= 0x80;
8400         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8401      }
8402   }
8403 }
8404 
8405 void
SiS_Chrontel701xOff(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8406 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8407 {
8408   USHORT temp;
8409 
8410   /* Complete power down of LVDS */
8411   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8412      if(HwInfo->jChipType == SIS_740) {
8413         SiS_LongDelay(SiS_Pr,1);
8414 	SiS_GenericDelay(SiS_Pr,0x16ff);
8415 	SiS_SetCH701x(SiS_Pr,0xac76);
8416 	SiS_SetCH701x(SiS_Pr,0x0066);
8417      } else {
8418         SiS_LongDelay(SiS_Pr,2);
8419 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8420 	temp &= 0xfc;
8421 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8422 	SiS_SetCH701x(SiS_Pr,0x0066);
8423      }
8424   }
8425 }
8426 
8427 static void
SiS_ChrontelResetDB(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8428 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8429 {
8430      USHORT temp;
8431 
8432      if(HwInfo->jChipType == SIS_740) {
8433 
8434         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8435         temp &= 0x01;
8436         if(!temp) {
8437 
8438            if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8439 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8440 	      SiS_SetCH701x(SiS_Pr,0x3e49);
8441 	   }
8442 	   /* Reset Chrontel 7019 datapath */
8443            SiS_SetCH701x(SiS_Pr,0x1048);
8444            SiS_LongDelay(SiS_Pr,1);
8445            SiS_SetCH701x(SiS_Pr,0x1848);
8446 
8447 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8448 	      SiS_ChrontelResetVSync(SiS_Pr);
8449 	      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8450 	   }
8451 
8452         } else {
8453 
8454 	   /* Clear/set/clear GPIO */
8455            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8456 	   temp &= 0xef;
8457 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8458 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8459 	   temp |= 0x10;
8460 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8461 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8462 	   temp &= 0xef;
8463 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8464 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8465 	   if(!temp) {
8466 	      SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8467 	   }
8468         }
8469 
8470      } else { /* 650 */
8471         /* Reset Chrontel 7019 datapath */
8472         SiS_SetCH701x(SiS_Pr,0x1048);
8473         SiS_LongDelay(SiS_Pr,1);
8474         SiS_SetCH701x(SiS_Pr,0x1848);
8475      }
8476 }
8477 
8478 void
SiS_ChrontelInitTVVSync(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8479 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8480 {
8481      USHORT temp;
8482 
8483      if(HwInfo->jChipType == SIS_740) {
8484 
8485         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8486            SiS_ChrontelResetVSync(SiS_Pr);
8487         }
8488 
8489      } else {
8490 
8491         SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
8492         temp = SiS_GetCH701x(SiS_Pr,0x49);
8493         temp &= 1;
8494         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8495 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8496 	   temp &= 0x70;
8497 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
8498 	   SiS_LongDelay(SiS_Pr,3);
8499 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8500 	   temp |= 0x80;
8501 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
8502         }
8503 
8504      }
8505 }
8506 
8507 static void
SiS_ChrontelDoSomething3(SiS_Private * SiS_Pr,USHORT ModeNo,PSIS_HW_INFO HwInfo)8508 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8509 {
8510      USHORT temp,temp1;
8511 
8512      if(HwInfo->jChipType == SIS_740) {
8513 
8514         temp = SiS_GetCH701x(SiS_Pr,0x61);
8515         if(temp < 1) {
8516            temp++;
8517 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8518         }
8519         SiS_SetCH701x(SiS_Pr,0x4566);  /* Panel power on */
8520         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on */
8521         SiS_LongDelay(SiS_Pr,1);
8522         SiS_GenericDelay(SiS_Pr,0x16ff);
8523 
8524      } else {  /* 650 */
8525 
8526         temp1 = 0;
8527         temp = SiS_GetCH701x(SiS_Pr,0x61);
8528         if(temp < 2) {
8529            temp++;
8530 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8531 	   temp1 = 1;
8532         }
8533         SiS_SetCH701x(SiS_Pr,0xac76);
8534         temp = SiS_GetCH701x(SiS_Pr,0x66);
8535         temp |= 0x5f;
8536         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8537         if(ModeNo > 0x13) {
8538            if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8539 	      SiS_GenericDelay(SiS_Pr,0x3ff);
8540 	   } else {
8541 	      SiS_GenericDelay(SiS_Pr,0x2ff);
8542 	   }
8543         } else {
8544            if(!temp1)
8545 	      SiS_GenericDelay(SiS_Pr,0x2ff);
8546         }
8547         temp = SiS_GetCH701x(SiS_Pr,0x76);
8548         temp |= 0x03;
8549         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8550         temp = SiS_GetCH701x(SiS_Pr,0x66);
8551         temp &= 0x7f;
8552         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8553         SiS_LongDelay(SiS_Pr,1);
8554 
8555      }
8556 }
8557 
8558 static void
SiS_ChrontelDoSomething2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8559 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8560 {
8561      USHORT temp,tempcl,tempch;
8562 
8563      SiS_LongDelay(SiS_Pr, 1);
8564      tempcl = 3;
8565      tempch = 0;
8566 
8567      do {
8568        temp = SiS_GetCH701x(SiS_Pr,0x66);
8569        temp &= 0x04;  /* PLL stable? -> bail out */
8570        if(temp == 0x04) break;
8571 
8572        if(HwInfo->jChipType == SIS_740) {
8573           /* Power down LVDS output, PLL normal operation */
8574           SiS_SetCH701x(SiS_Pr,0xac76);
8575        }
8576 
8577        SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8578 
8579        if(tempcl == 0) {
8580            if(tempch == 3) break;
8581 	   SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8582 	   tempcl = 3;
8583 	   tempch++;
8584        }
8585        tempcl--;
8586        temp = SiS_GetCH701x(SiS_Pr,0x76);
8587        temp &= 0xfb;  /* Reset PLL */
8588        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8589        SiS_LongDelay(SiS_Pr,2);
8590        temp = SiS_GetCH701x(SiS_Pr,0x76);
8591        temp |= 0x04;  /* PLL normal operation */
8592        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8593        if(HwInfo->jChipType == SIS_740) {
8594           SiS_SetCH701x(SiS_Pr,0xe078);	/* PLL loop filter */
8595        } else {
8596           SiS_SetCH701x(SiS_Pr,0x6078);
8597        }
8598        SiS_LongDelay(SiS_Pr,2);
8599     } while(0);
8600 
8601     SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
8602 }
8603 
8604 void
SiS_ChrontelDoSomething1(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8605 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8606 {
8607      USHORT temp;
8608 
8609      temp = SiS_GetCH701x(SiS_Pr,0x03);
8610      temp |= 0x80;	/* Set datapath 1 to TV   */
8611      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8612      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8613 
8614      if(HwInfo->jChipType == SIS_740) {
8615 
8616         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8617         temp &= 0xfb;	/* Normal XCLK phase */
8618         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8619 
8620         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8621 
8622         temp = SiS_GetCH701x(SiS_Pr,0x64);
8623         temp |= 0x40;	/* ? Bit not defined */
8624         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8625 
8626         temp = SiS_GetCH701x(SiS_Pr,0x03);
8627         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8628         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8629 
8630 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8631 	   SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8632 	   SiS_LongDelay(SiS_Pr, 1);
8633 	   SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8634 	   SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8635 	   SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8636 	   SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8637 	} else {
8638            temp = SiS_GetCH701x(SiS_Pr,0x66);
8639            if(temp != 0x45) {
8640               SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8641               SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8642               SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8643            }
8644 	}
8645 
8646      } else { /* 650 */
8647 
8648         SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8649         SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8650         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8651         SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8652         SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on, LVDS normal operation */
8653 
8654      }
8655 
8656 }
8657 #endif  /* 315 series  */
8658 
8659 /*********************************************/
8660 /*      MAIN: SET CRT2 REGISTER GROUP        */
8661 /*********************************************/
8662 
8663 BOOLEAN
SiS_SetCRT2Group(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo)8664 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8665 {
8666 #ifdef SIS300
8667    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
8668 #endif
8669    USHORT ModeIdIndex, RefreshRateTableIndex;
8670 #if 0
8671    USHORT temp;
8672 #endif
8673 
8674    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8675 
8676    if(!SiS_Pr->UseCustomMode) {
8677       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8678    } else {
8679       ModeIdIndex = 0;
8680    }
8681 
8682    /* Used for shifting CR33 */
8683    SiS_Pr->SiS_SelectCRT2Rate = 4;
8684 
8685    SiS_UnLockCRT2(SiS_Pr, HwInfo);
8686 
8687    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8688 
8689    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8690 
8691    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8692       SiS_DisableBridge(SiS_Pr,HwInfo);
8693       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8694          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8695       }
8696       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8697    }
8698 
8699    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8700       SiS_LockCRT2(SiS_Pr, HwInfo);
8701       SiS_DisplayOn(SiS_Pr);
8702       return TRUE;
8703    }
8704 
8705    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8706 
8707    /* Set up Panel Link for LVDS and LCDA */
8708    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8709    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8710        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8711        ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8712       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8713    }
8714 
8715 #ifdef LINUX_XF86
8716 #ifdef TWDEBUG
8717   xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8718   xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8719   xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8720   xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8721   xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8722 #endif
8723 #endif
8724 
8725    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8726       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8727    }
8728 
8729    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8730 
8731         if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8732 
8733 	   SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8734 #ifdef SIS315H
8735 	   SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8736 #endif
8737       	   SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8738       	   SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8739 #ifdef SIS315H
8740 	   SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8741 #endif
8742       	   SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8743 
8744 	   SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8745 
8746 	   /* For 301BDH (Panel link initialization): */
8747 	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8748 	      if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8749 		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8750 		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8751 		       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8752 		                       RefreshRateTableIndex,HwInfo);
8753 		    }
8754                  }
8755 	      }
8756 	      SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8757 		              RefreshRateTableIndex,HwInfo);
8758 	   }
8759         }
8760 
8761    } else {
8762 
8763         SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8764 
8765         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8766     	   SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8767 	}
8768 
8769         SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8770 
8771 	if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8772      	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8773 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8774 	         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8775 #ifdef SIS315H
8776 		    SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8777 #endif
8778 		 }
8779 	      }
8780 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8781        		 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8782 	      }
8783      	   }
8784 	}
8785 
8786    }
8787 
8788 #ifdef SIS300
8789    if(HwInfo->jChipType < SIS_315H) {
8790       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8791 	 if(SiS_Pr->SiS_UseOEM) {
8792 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8793 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8794 	          SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8795 	       			    RefreshRateTableIndex);
8796 	       }
8797 	    } else {
8798        	       SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8799 	       			 RefreshRateTableIndex);
8800 	    }
8801 	 }
8802 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8803             if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8804 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8805 	       SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8806 	    }
8807             if(HwInfo->jChipType == SIS_730) {
8808                SiS_DisplayOn(SiS_Pr);
8809 	    }
8810          }
8811       }
8812       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8813           if(HwInfo->jChipType != SIS_730) {
8814              SiS_DisplayOn(SiS_Pr);
8815 	  }
8816       }
8817    }
8818 #endif
8819 
8820 #ifdef SIS315H
8821    if(HwInfo->jChipType >= SIS_315H) {
8822       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8823 	 if(HwInfo->jChipType < SIS_661) {
8824 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8825             SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8826 	 } else {
8827 	    SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8828 	 }
8829          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8830       }
8831    }
8832 #endif
8833 
8834    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8835       SiS_EnableBridge(SiS_Pr, HwInfo);
8836    }
8837 
8838    SiS_DisplayOn(SiS_Pr);
8839 
8840    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8841       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8842 	 /* Disable LCD panel when using TV */
8843 	 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
8844       } else {
8845 	 /* Disable TV when using LCD */
8846 	 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
8847       }
8848    }
8849 
8850    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8851       SiS_LockCRT2(SiS_Pr,HwInfo);
8852    }
8853 
8854    return TRUE;
8855 }
8856 
8857 
8858 /*********************************************/
8859 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8860 /*********************************************/
8861 
8862 void
SiS_SiS30xBLOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8863 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8864 {
8865   /* Switch on LCD backlight on SiS30xLV */
8866   SiS_DDC2Delay(SiS_Pr,0xff00);
8867   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8868      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8869      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
8870   }
8871   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8872      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8873   }
8874 }
8875 
8876 void
SiS_SiS30xBLOff(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8877 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8878 {
8879   /* Switch off LCD backlight on SiS30xLV */
8880   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8881   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
8882   SiS_DDC2Delay(SiS_Pr,0xe000);
8883 }
8884 
8885 /*********************************************/
8886 /*          DDC RELATED FUNCTIONS            */
8887 /*********************************************/
8888 
8889 static void
SiS_SetupDDCN(SiS_Private * SiS_Pr)8890 SiS_SetupDDCN(SiS_Private *SiS_Pr)
8891 {
8892   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8893   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
8894   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8895      SiS_Pr->SiS_DDC_NData &= 0x0f;
8896      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
8897   }
8898 }
8899 
8900 #ifdef SIS300
8901 static UCHAR *
SiS_SetTrumpBlockLoop(SiS_Private * SiS_Pr,UCHAR * dataptr)8902 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
8903 {
8904   int i, j, num;
8905   USHORT tempah,temp;
8906   UCHAR *mydataptr;
8907 
8908   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8909      mydataptr = dataptr;
8910      num = *mydataptr++;
8911      if(!num) return mydataptr;
8912      if(i) {
8913         SiS_SetStop(SiS_Pr);
8914 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
8915      }
8916      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
8917      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8918      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
8919      if(temp) continue;				/*    (ERROR: no ack) */
8920      tempah = *mydataptr++;
8921      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
8922      if(temp) continue;				/*    (ERROR: no ack) */
8923      for(j=0; j<num; j++) {
8924         tempah = *mydataptr++;
8925         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8926 	if(temp) break;
8927      }
8928      if(temp) continue;
8929      if(SiS_SetStop(SiS_Pr)) continue;
8930      return mydataptr;
8931   }
8932   return NULL;
8933 }
8934 
8935 static BOOLEAN
SiS_SetTrumpionBlock(SiS_Private * SiS_Pr,UCHAR * dataptr)8936 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
8937 {
8938   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
8939   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8940   SiS_Pr->SiS_DDC_Data  = 0x02;              	/* Bitmask in IndexReg for Data */
8941   SiS_Pr->SiS_DDC_Clk   = 0x01;              	/* Bitmask in IndexReg for Clk */
8942   SiS_SetupDDCN(SiS_Pr);
8943 
8944   SiS_SetSwitchDDC2(SiS_Pr);
8945 
8946   while(*dataptr) {
8947      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8948      if(!dataptr) return FALSE;
8949   }
8950 #ifdef TWDEBUG
8951   xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8952 #endif
8953   return TRUE;
8954 }
8955 #endif
8956 
8957 /* The Chrontel 700x is connected to the 630/730 via
8958  * the 630/730's DDC/I2C port.
8959  *
8960  * On 630(S)T chipset, the index changed from 0x11 to
8961  * 0x0a, possibly for working around the DDC problems
8962  */
8963 
8964 static BOOLEAN
SiS_SetChReg(SiS_Private * SiS_Pr,USHORT tempbx,USHORT myor)8965 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
8966 {
8967   USHORT tempah,temp,i;
8968 
8969   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8970      if(i) {
8971         SiS_SetStop(SiS_Pr);
8972 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8973      }
8974      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
8975      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8976      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
8977      if(temp) continue;				/*    (ERROR: no ack) */
8978      tempah = tempbx & 0x00FF;			/* Write RAB */
8979      tempah |= myor;                            /* (700x: set bit 7, see datasheet) */
8980      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
8981      if(temp) continue;				/*    (ERROR: no ack) */
8982      tempah = (tempbx & 0xFF00) >> 8;
8983      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
8984      if(temp) continue;				/*    (ERROR: no ack) */
8985      if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
8986      SiS_Pr->SiS_ChrontelInit = 1;
8987      return TRUE;
8988   }
8989   return FALSE;
8990 }
8991 
8992 #ifdef SIS300
8993 /* Write Trumpion register */
8994 void
SiS_SetTrumpReg(SiS_Private * SiS_Pr,USHORT tempbx)8995 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
8996 {
8997   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
8998   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8999   SiS_Pr->SiS_DDC_Data  = 0x02;              	/* Bitmask in IndexReg for Data */
9000   SiS_Pr->SiS_DDC_Clk   = 0x01;              	/* Bitmask in IndexReg for Clk */
9001   SiS_SetupDDCN(SiS_Pr);
9002   SiS_SetChReg(SiS_Pr, tempbx, 0);
9003 }
9004 #endif
9005 
9006 /* Write to Chrontel 700x */
9007 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9008 void
SiS_SetCH700x(SiS_Private * SiS_Pr,USHORT tempbx)9009 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9010 {
9011   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9012 
9013   if(!(SiS_Pr->SiS_ChrontelInit)) {
9014      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9015      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9016      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9017      SiS_SetupDDCN(SiS_Pr);
9018   }
9019 
9020   if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9021       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9022      SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 7 = SC;  Bit 6 = SD */
9023      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
9024      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
9025      SiS_SetupDDCN(SiS_Pr);
9026 
9027      SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9028   }
9029 }
9030 
9031 /* Write to Chrontel 701x */
9032 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9033 void
SiS_SetCH701x(SiS_Private * SiS_Pr,USHORT tempbx)9034 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9035 {
9036   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9037   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9038   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9039   SiS_SetupDDCN(SiS_Pr);
9040   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9041   SiS_SetChReg(SiS_Pr, tempbx, 0);
9042 }
9043 
9044 void
SiS_SetCH70xx(SiS_Private * SiS_Pr,USHORT tempbx)9045 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9046 {
9047   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9048      SiS_SetCH700x(SiS_Pr,tempbx);
9049   else
9050      SiS_SetCH701x(SiS_Pr,tempbx);
9051 }
9052 
9053 static USHORT
SiS_GetChReg(SiS_Private * SiS_Pr,USHORT myor)9054 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9055 {
9056   USHORT tempah,temp,i;
9057 
9058   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
9059      if(i) {
9060         SiS_SetStop(SiS_Pr);
9061 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9062      }
9063      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
9064      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9065      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
9066      if(temp) continue;				/*        (ERROR: no ack) */
9067      tempah = SiS_Pr->SiS_DDC_ReadAddr | myor;	/* Write RAB (700x: | 0x80) */
9068      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9069      if(temp) continue;				/*        (ERROR: no ack) */
9070      if (SiS_SetStart(SiS_Pr)) continue;	/* Re-start */
9071      tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9072      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
9073      if(temp) continue;				/*        (ERROR: no ack) */
9074      tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
9075      if(SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
9076      SiS_Pr->SiS_ChrontelInit = 1;
9077      return(tempah);
9078   }
9079   return 0xFFFF;
9080 }
9081 
9082 #ifdef SIS300
9083 /* Read from Trumpion */
9084 USHORT
SiS_GetTrumpReg(SiS_Private * SiS_Pr,USHORT tempbx)9085 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9086 {
9087   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;	/* DAB */
9088   SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9089   SiS_Pr->SiS_DDC_Data  = 0x02;         /* Bitmask in IndexReg for Data */
9090   SiS_Pr->SiS_DDC_Clk   = 0x01;         /* Bitmask in IndexReg for Clk */
9091   SiS_SetupDDCN(SiS_Pr);
9092   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9093   return(SiS_GetChReg(SiS_Pr,0));
9094 }
9095 #endif
9096 
9097 /* Read from Chrontel 700x */
9098 /* Parameter is [Register no (S7-S0)] */
9099 USHORT
SiS_GetCH700x(SiS_Private * SiS_Pr,USHORT tempbx)9100 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9101 {
9102   USHORT result;
9103 
9104   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9105 
9106   if(!(SiS_Pr->SiS_ChrontelInit)) {
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   }
9112 
9113   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9114 
9115   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9116       (!SiS_Pr->SiS_ChrontelInit) ) {
9117 
9118      SiS_Pr->SiS_DDC_Index = 0x0a;
9119      SiS_Pr->SiS_DDC_Data  = 0x80;
9120      SiS_Pr->SiS_DDC_Clk   = 0x40;
9121      SiS_SetupDDCN(SiS_Pr);
9122 
9123      result = SiS_GetChReg(SiS_Pr,0x80);
9124   }
9125   return(result);
9126 }
9127 
9128 /* Read from Chrontel 701x */
9129 /* Parameter is [Register no (S7-S0)] */
9130 USHORT
SiS_GetCH701x(SiS_Private * SiS_Pr,USHORT tempbx)9131 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9132 {
9133   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9134   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9135   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9136   SiS_SetupDDCN(SiS_Pr);
9137   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9138 
9139   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9140 
9141   return(SiS_GetChReg(SiS_Pr,0));
9142 }
9143 
9144 /* Read from Chrontel 70xx */
9145 /* Parameter is [Register no (S7-S0)] */
9146 USHORT
SiS_GetCH70xx(SiS_Private * SiS_Pr,USHORT tempbx)9147 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9148 {
9149   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9150      return(SiS_GetCH700x(SiS_Pr, tempbx));
9151   else
9152      return(SiS_GetCH701x(SiS_Pr, tempbx));
9153 }
9154 
9155 /* Our own DDC functions */
9156 USHORT
SiS_InitDDCRegs(SiS_Private * SiS_Pr,unsigned long VBFlags,int VGAEngine,USHORT adaptnum,USHORT DDCdatatype,BOOLEAN checkcr32)9157 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9158                 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9159 {
9160      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9161      unsigned char flag, cr32;
9162      USHORT        temp = 0, myadaptnum = adaptnum;
9163 
9164      if(adaptnum != 0) {
9165         if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9166 	if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9167      }
9168 
9169      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9170 
9171      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9172 
9173      SiS_Pr->SiS_DDC_SecAddr = 0;
9174      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9175      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9176      SiS_Pr->SiS_DDC_Index = 0x11;
9177      flag = 0xff;
9178 
9179      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9180 
9181 #if 0
9182      if(VBFlags & VB_SISBRIDGE) {
9183 	if(myadaptnum == 0) {
9184 	   if(!(cr32 & 0x20)) {
9185 	      myadaptnum = 2;
9186 	      if(!(cr32 & 0x10)) {
9187 	         myadaptnum = 1;
9188 		 if(!(cr32 & 0x08)) {
9189 		    myadaptnum = 0;
9190 		 }
9191 	      }
9192 	   }
9193         }
9194      }
9195 #endif
9196 
9197      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9198 
9199         if(myadaptnum != 0) {
9200 	   flag = 0;
9201 	   if(VBFlags & VB_SISBRIDGE) {
9202 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9203               SiS_Pr->SiS_DDC_Index = 0x0f;
9204 	   }
9205         }
9206 
9207 	if(!(VBFlags & VB_301)) {
9208 	   if((cr32 & 0x80) && (checkcr32)) {
9209               if(myadaptnum >= 1) {
9210 	         if(!(cr32 & 0x08)) {
9211 	             myadaptnum = 1;
9212 		     if(!(cr32 & 0x10)) return 0xFFFF;
9213                  }
9214 	      }
9215 	   }
9216 	}
9217 
9218 	temp = 4 - (myadaptnum * 2);
9219 	if(flag) temp = 0;
9220 
9221      } else {						/* 315/330 series */
9222 
9223      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9224 
9225 	if(VBFlags & VB_SISBRIDGE) {
9226 	   if(myadaptnum == 2) {
9227 	      myadaptnum = 1;
9228            }
9229 	}
9230 
9231         if(myadaptnum == 1) {
9232      	   flag = 0;
9233 	   if(VBFlags & VB_SISBRIDGE) {
9234 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9235               SiS_Pr->SiS_DDC_Index = 0x0f;
9236 	   }
9237         }
9238 
9239         if((cr32 & 0x80) && (checkcr32)) {
9240            if(myadaptnum >= 1) {
9241 	      if(!(cr32 & 0x08)) {
9242 	         myadaptnum = 1;
9243 		 if(!(cr32 & 0x10)) return 0xFFFF;
9244 	      }
9245 	   }
9246         }
9247 
9248         temp = myadaptnum;
9249         if(myadaptnum == 1) {
9250            temp = 0;
9251 	   if(VBFlags & VB_LVDS) flag = 0xff;
9252         }
9253 
9254 	if(flag) temp = 0;
9255     }
9256 
9257     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9258     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9259 
9260     SiS_SetupDDCN(SiS_Pr);
9261 
9262 #ifdef TWDEBUG
9263     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9264     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9265 #endif
9266 
9267     return 0;
9268 }
9269 
9270 USHORT
SiS_WriteDABDDC(SiS_Private * SiS_Pr)9271 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9272 {
9273    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9274    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9275   	return 0xFFFF;
9276    }
9277    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9278    	return 0xFFFF;
9279    }
9280    return(0);
9281 }
9282 
9283 USHORT
SiS_PrepareReadDDC(SiS_Private * SiS_Pr)9284 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9285 {
9286    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9287    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9288    	return 0xFFFF;
9289    }
9290    return(0);
9291 }
9292 
9293 USHORT
SiS_PrepareDDC(SiS_Private * SiS_Pr)9294 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9295 {
9296    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9297    if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9298    return(0);
9299 }
9300 
9301 void
SiS_SendACK(SiS_Private * SiS_Pr,USHORT yesno)9302 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9303 {
9304    SiS_SetSCLKLow(SiS_Pr);
9305    if(yesno) {
9306       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9307       		      SiS_Pr->SiS_DDC_Index,
9308                       SiS_Pr->SiS_DDC_NData,
9309 		      SiS_Pr->SiS_DDC_Data);
9310    } else {
9311       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9312       		      SiS_Pr->SiS_DDC_Index,
9313                       SiS_Pr->SiS_DDC_NData,
9314 		      0);
9315    }
9316    SiS_SetSCLKHigh(SiS_Pr);
9317 }
9318 
9319 USHORT
SiS_DoProbeDDC(SiS_Private * SiS_Pr)9320 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9321 {
9322     unsigned char mask, value;
9323     USHORT  temp, ret=0;
9324     BOOLEAN failed = FALSE;
9325 
9326     SiS_SetSwitchDDC2(SiS_Pr);
9327     if(SiS_PrepareDDC(SiS_Pr)) {
9328          SiS_SetStop(SiS_Pr);
9329 #ifdef TWDEBUG
9330          xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9331 #endif
9332          return(0xFFFF);
9333     }
9334     mask = 0xf0;
9335     value = 0x20;
9336     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9337        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9338        SiS_SendACK(SiS_Pr, 0);
9339        if(temp == 0) {
9340            mask = 0xff;
9341 	   value = 0xff;
9342        } else {
9343            failed = TRUE;
9344 	   ret = 0xFFFF;
9345 #ifdef TWDEBUG
9346            xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9347 #endif
9348        }
9349     }
9350     if(failed == FALSE) {
9351        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9352        SiS_SendACK(SiS_Pr, 1);
9353        temp &= mask;
9354        if(temp == value) ret = 0;
9355        else {
9356           ret = 0xFFFF;
9357 #ifdef TWDEBUG
9358           xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9359 #endif
9360           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9361              if(temp == 0x30) ret = 0;
9362           }
9363        }
9364     }
9365     SiS_SetStop(SiS_Pr);
9366     return(ret);
9367 }
9368 
9369 USHORT
SiS_ProbeDDC(SiS_Private * SiS_Pr)9370 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9371 {
9372    USHORT flag;
9373 
9374    flag = 0x180;
9375    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9376    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9377    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9378    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9379    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9380    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9381    if(!(flag & 0x1a)) flag = 0;
9382    return(flag);
9383 }
9384 
9385 USHORT
SiS_ReadDDC(SiS_Private * SiS_Pr,USHORT DDCdatatype,unsigned char * buffer)9386 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9387 {
9388    USHORT flag, length, i;
9389    unsigned char chksum,gotcha;
9390 
9391    if(DDCdatatype > 4) return 0xFFFF;
9392 
9393    flag = 0;
9394    SiS_SetSwitchDDC2(SiS_Pr);
9395    if(!(SiS_PrepareDDC(SiS_Pr))) {
9396       length = 127;
9397       if(DDCdatatype != 1) length = 255;
9398       chksum = 0;
9399       gotcha = 0;
9400       for(i=0; i<length; i++) {
9401          buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9402 	 chksum += buffer[i];
9403 	 gotcha |= buffer[i];
9404 	 SiS_SendACK(SiS_Pr, 0);
9405       }
9406       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9407       chksum += buffer[i];
9408       SiS_SendACK(SiS_Pr, 1);
9409       if(gotcha) flag = (USHORT)chksum;
9410       else flag = 0xFFFF;
9411    } else {
9412       flag = 0xFFFF;
9413    }
9414    SiS_SetStop(SiS_Pr);
9415    return(flag);
9416 }
9417 
9418 /* Our private DDC functions
9419 
9420    It complies somewhat with the corresponding VESA function
9421    in arguments and return values.
9422 
9423    Since this is probably called before the mode is changed,
9424    we use our pre-detected pSiS-values instead of SiS_Pr as
9425    regards chipset and video bridge type.
9426 
9427    Arguments:
9428        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
9429                  CRT2 DDC is only supported on SiS301, 301B, 302B.
9430        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9431        buffer: ptr to 256 data bytes which will be filled with read data.
9432 
9433    Returns 0xFFFF if error, otherwise
9434        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9435        if DDCdatatype = 0:  Returns supported DDC modes
9436 
9437  */
9438 USHORT
SiS_HandleDDC(SiS_Private * SiS_Pr,unsigned long VBFlags,int VGAEngine,USHORT adaptnum,USHORT DDCdatatype,unsigned char * buffer)9439 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9440               USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9441 {
9442    unsigned char sr1f,cr17=1;
9443    USHORT result;
9444 
9445    if(adaptnum > 2) return 0xFFFF;
9446    if(DDCdatatype > 4) return 0xFFFF;
9447    if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9448    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9449 
9450    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9451    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9452    if(VGAEngine == SIS_300_VGA) {
9453       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9454       if(!cr17) {
9455          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9456          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9457          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9458       }
9459    }
9460    if((sr1f) || (!cr17)) {
9461       SiS_WaitRetrace1(SiS_Pr);
9462       SiS_WaitRetrace1(SiS_Pr);
9463       SiS_WaitRetrace1(SiS_Pr);
9464       SiS_WaitRetrace1(SiS_Pr);
9465    }
9466 
9467    if(DDCdatatype == 0) {
9468       result = SiS_ProbeDDC(SiS_Pr);
9469    } else {
9470       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9471    }
9472    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9473    if(VGAEngine == SIS_300_VGA) {
9474       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9475    }
9476    return result;
9477 }
9478 
9479 #ifdef LINUX_XF86
9480 
9481 static BOOLEAN
checkedid1(unsigned char * buffer)9482 checkedid1(unsigned char *buffer)
9483 {
9484    /* Check header */
9485    if((buffer[0] != 0x00) ||
9486       (buffer[1] != 0xff) ||
9487       (buffer[2] != 0xff) ||
9488       (buffer[3] != 0xff) ||
9489       (buffer[4] != 0xff) ||
9490       (buffer[5] != 0xff) ||
9491       (buffer[6] != 0xff) ||
9492       (buffer[7] != 0x00))
9493       return FALSE;
9494 
9495    /* Check EDID version and revision */
9496    if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9497 
9498    /* Check week of manufacture for sanity */
9499    if(buffer[0x10] > 53) return FALSE;
9500 
9501    /* Check year of manufacture for sanity */
9502    if(buffer[0x11] > 40) return FALSE;
9503 
9504    return TRUE;
9505 }
9506 
9507 static BOOLEAN
checkedid2(unsigned char * buffer)9508 checkedid2(unsigned char *buffer)
9509 {
9510    USHORT year = buffer[6] | (buffer[7] << 8);
9511 
9512    /* Check EDID version */
9513    if((buffer[0] & 0xf0) != 0x20) return FALSE;
9514 
9515    /* Check week of manufacture for sanity */
9516    if(buffer[5] > 53) return FALSE;
9517 
9518    /* Check year of manufacture for sanity */
9519    if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9520 
9521    return TRUE;
9522 }
9523 
9524 /* Sense the LCD parameters (CR36, CR37) via DDC */
9525 /* SiS30x(B) only */
9526 USHORT
SiS_SenseLCDDDC(SiS_Private * SiS_Pr,SISPtr pSiS)9527 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9528 {
9529    USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9530    USHORT index, myindex, lumsize, numcodes;
9531    unsigned char cr37=0, seekcode;
9532    BOOLEAN checkexpand = FALSE;
9533    int retry, i;
9534    unsigned char buffer[256];
9535 
9536    for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9537    SiS_Pr->CP_HaveCustomData = FALSE;
9538    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9539    SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9540    SiS_Pr->CP_PreferredIndex = -1;
9541 
9542    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9543    if(pSiS->VBFlags & VB_30xBDH) return 0;
9544 
9545    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9546 
9547    SiS_Pr->SiS_DDC_SecAddr = 0x00;
9548 
9549    /* Probe supported DA's */
9550    flag = SiS_ProbeDDC(SiS_Pr);
9551 #ifdef TWDEBUG
9552    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9553    	"CRT2 DDC capabilities 0x%x\n", flag);
9554 #endif
9555    if(flag & 0x10) {
9556       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
9557       DDCdatatype = 4;
9558    } else if(flag & 0x08) {
9559       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
9560       DDCdatatype = 3;
9561    } else if(flag & 0x02) {
9562       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
9563       DDCdatatype = 1;
9564    } else return 0;				/* no DDC support (or no device attached) */
9565 
9566    /* Read the entire EDID */
9567    retry = 2;
9568    do {
9569       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9570          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9571 	 	"CRT2: DDC read failed (attempt %d), %s\n",
9572 		(3-retry), (retry == 1) ? "giving up" : "retrying");
9573 	 retry--;
9574 	 if(retry == 0) return 0xFFFF;
9575       } else break;
9576    } while(1);
9577 
9578 #ifdef TWDEBUG
9579    for(i=0; i<256; i+=16) {
9580        xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9581        	"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9582 	buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
9583 	buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
9584 	buffer[i+8],  buffer[i+9], buffer[i+10], buffer[i+11],
9585 	buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9586    }
9587 #endif
9588 
9589    /* Analyze EDID and retrieve LCD panel information */
9590    paneltype = 0;
9591    switch(DDCdatatype) {
9592    case 1:							/* Analyze EDID V1 */
9593       /* Catch a few clear cases: */
9594       if(!(checkedid1(buffer))) {
9595          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9596 	 	"CRT2: EDID corrupt\n");
9597 	 return 0;
9598       }
9599 
9600       if(!(buffer[0x14] & 0x80)) {
9601          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9602 	        "CRT2: Attached display expects analog input (0x%02x)\n",
9603 		buffer[0x14]);
9604       	 return 0;
9605       }
9606 
9607       if((buffer[0x18] & 0x18) != 0x08) {
9608          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9609 	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
9610 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9611 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9612 		     "undefined"),
9613 		buffer[0x18]);
9614 	 return 0;
9615       }
9616 
9617       /* Now analyze the first Detailed Timing Block and see
9618        * if the preferred timing mode is stored there. If so,
9619        * check if this is a standard panel for which we already
9620        * know the timing.
9621        */
9622 
9623       paneltype = Panel_Custom;
9624       checkexpand = FALSE;
9625 
9626       if(buffer[0x18] & 0x02) {
9627 
9628          xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9629          yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9630 
9631 	 SiS_Pr->CP_PreferredX = xres;
9632 	 SiS_Pr->CP_PreferredY = yres;
9633 
9634          switch(xres) {
9635 #if 0	    /* Treat as custom */
9636             case 800:
9637 	        if(yres == 600) {
9638 	     	   paneltype = Panel_800x600;
9639 	     	   checkexpand = TRUE;
9640 	        }
9641 	        break;
9642 #endif
9643             case 1024:
9644 	        if(yres == 768) {
9645 	     	   paneltype = Panel_1024x768;
9646 	     	   checkexpand = TRUE;
9647 	        }
9648 	        break;
9649 	    case 1280:
9650 	        if(yres == 1024) {
9651 	     	   paneltype = Panel_1280x1024;
9652 		   checkexpand = TRUE;
9653 	        } else if(yres == 960) {
9654 	           if(pSiS->VGAEngine == SIS_300_VGA) {
9655 		      paneltype = Panel300_1280x960;
9656 		   } else {
9657 		      paneltype = Panel310_1280x960;
9658 		   }
9659 	        } else if(yres == 768) {
9660 		   if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
9661 		       ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
9662 		       ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
9663 	       	      paneltype = Panel_1280x768;
9664 		      checkexpand = FALSE;
9665 		      cr37 |= 0x10;
9666 		   }
9667 	        }
9668 	        break;
9669 	    case 1400:
9670 	        if(pSiS->VGAEngine == SIS_315_VGA) {
9671 	           if(yres == 1050) {
9672 	              paneltype = Panel310_1400x1050;
9673 		      checkexpand = TRUE;
9674 	           }
9675 	        }
9676       	        break;
9677 #if 0	    /* Treat this as custom, as we have no valid timing data yet */
9678 	    case 1600:
9679 	        if(pSiS->VGAEngine == SIS_315_VGA) {
9680 		   if(pSiS->VBFlags & VB_301C) {
9681 	              if(yres == 1200) {
9682 	                 paneltype = Panel310_1600x1200;
9683 		         checkexpand = TRUE;
9684 		      }
9685 	           }
9686 	        }
9687       	        break;
9688 #endif
9689          }
9690 
9691 	 if(paneltype != Panel_Custom) {
9692 	    if((buffer[0x47] & 0x18) == 0x18) {
9693 	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9694 	    } else {
9695 	       /* What now? There is no digital separate output timing... */
9696 	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9697 	       	   "CRT2: Unable to retrieve Sync polarity information\n");
9698 	       cr37 |= 0xc0;  /* Default */
9699 	    }
9700 	 }
9701 
9702       }
9703 
9704       /* If we still don't know what panel this is, we take it
9705        * as a custom panel and derive the timing data from the
9706        * detailed timing blocks
9707        */
9708       if(paneltype == Panel_Custom) {
9709 
9710          BOOLEAN havesync = FALSE;
9711 	 int i, temp, base = 0x36;
9712 	 unsigned long estpack;
9713 	 unsigned short estx[] = {
9714 	 	720, 720, 640, 640, 640, 640, 800, 800,
9715 		800, 800, 832,1024,1024,1024,1024,1280,
9716 		1152
9717 	 };
9718 	 unsigned short esty[] = {
9719 	 	400, 400, 480, 480, 480, 480, 600, 600,
9720 		600, 600, 624, 768, 768, 768, 768,1024,
9721 		870
9722 	 };
9723 
9724 	 paneltype = 0;
9725 	 SiS_Pr->CP_Supports64048075 = TRUE;
9726 
9727 	 /* Find the maximum resolution */
9728 
9729 	 /* 1. From Established timings */
9730 	 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9731 	 for(i=16; i>=0; i--) {
9732 	     if(estpack & (1 << i)) {
9733 	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9734 		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9735 	     }
9736 	 }
9737 
9738 	 /* 2. From Standard Timings */
9739 	 for(i=0x26; i < 0x36; i+=2) {
9740 	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9741 	       temp = (buffer[i] + 31) * 8;
9742 	       if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9743 	       switch((buffer[i+1] & 0xc0) >> 6) {
9744 	       case 0x03: temp = temp * 9 / 16; break;
9745 	       case 0x02: temp = temp * 4 / 5;  break;
9746 	       case 0x01: temp = temp * 3 / 4;  break;
9747 	       }
9748 	       if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9749 	    }
9750 	 }
9751 
9752 	 /* Now extract the Detailed Timings and convert them into modes */
9753 
9754          for(i = 0; i < 4; i++, base += 18) {
9755 
9756 	    /* Is this a detailed timing block or a monitor descriptor? */
9757 	    if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9758 
9759       	       xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9760                yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
9761 
9762 	       SiS_Pr->CP_HDisplay[i] = xres;
9763 	       SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
9764                SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
9765 	       SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
9766 	       SiS_Pr->CP_HBlankStart[i] = xres + 1;
9767 	       SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
9768 
9769 	       SiS_Pr->CP_VDisplay[i] = yres;
9770                SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
9771                SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
9772 	       SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
9773 	       SiS_Pr->CP_VBlankStart[i] = yres + 1;
9774 	       SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
9775 
9776 	       SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
9777 
9778 	       SiS_Pr->CP_DataValid[i] = TRUE;
9779 
9780 	       /* Sort out invalid timings, interlace and too high clocks */
9781 	       if((SiS_Pr->CP_HDisplay[i] & 7)						||
9782 	          (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  			||
9783 	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   			||
9784 	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     			||
9785 	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) 			||
9786 	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    			||
9787 	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      			||
9788 	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  			||
9789 	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   			||
9790 	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     			||
9791 	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  			||
9792 	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    			||
9793 	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      			||
9794 		  (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
9795 	           ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
9796 		  (buffer[base+17] & 0x80)) {
9797 
9798 	          SiS_Pr->CP_DataValid[i] = FALSE;
9799 
9800 	       } else {
9801 
9802 	          paneltype = Panel_Custom;
9803 
9804 		  SiS_Pr->CP_HaveCustomData = TRUE;
9805 
9806 		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
9807 	          if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
9808 		  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
9809 
9810 		  if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
9811 	             SiS_Pr->CP_PreferredIndex = i;
9812 	          }
9813 
9814 		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
9815 		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
9816 
9817 		  /* By default we drive the LCD at 75Hz in 640x480 mode; if
9818 		   * the panel does not provide this mode, use 60hz
9819 		   */
9820 		  if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9821 
9822 	          /* We must assume the panel can scale, since we have
9823 	           * no scaling data
9824 		   */
9825 	          checkexpand = FALSE;
9826 	          cr37 |= 0x10;
9827 
9828 	          /* Extract the sync polarisation information. This only works
9829 	           * if the Flags indicate a digital separate output.
9830 	           */
9831 	          if((buffer[base+17] & 0x18) == 0x18) {
9832 		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
9833 		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
9834 		     SiS_Pr->CP_SyncValid[i] = TRUE;
9835 		     if(!havesync) {
9836 	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
9837 			havesync = TRUE;
9838 	   	     }
9839 	          } else {
9840 		     SiS_Pr->CP_SyncValid[i] = FALSE;
9841 		  }
9842 	       }
9843             }
9844 	 }
9845 	 if(!havesync) {
9846 	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9847 	       	   "CRT2: Unable to retrieve Sync polarity information\n");
9848    	 }
9849       }
9850 
9851       if(paneltype && checkexpand) {
9852          /* If any of the Established low-res modes is supported, the
9853 	  * panel can scale automatically. For 800x600 panels, we only
9854 	  * check the even lower ones.
9855 	  */
9856 	 if(paneltype == Panel_800x600) {
9857 	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
9858 	 } else {
9859             if(buffer[0x23])	    cr37 |= 0x10;
9860 	 }
9861       }
9862 
9863       break;
9864 
9865    case 3:							/* Analyze EDID V2 */
9866    case 4:
9867       index = 0;
9868 
9869       if(!(checkedid2(buffer))) {
9870          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9871 	 	"CRT2: EDID corrupt\n");
9872 	 return 0;
9873       }
9874 
9875       if((buffer[0x41] & 0x0f) == 0x03) {
9876          index = 0x42 + 3;
9877          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9878 	 	"CRT2: Display supports TMDS input on primary interface\n");
9879       } else if((buffer[0x41] & 0xf0) == 0x30) {
9880          index = 0x46 + 3;
9881          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9882 	 	"CRT2: Display supports TMDS input on secondary interface\n");
9883       } else {
9884          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9885 	 	"CRT2: Display does not support TMDS video interface (0x%02x)\n",
9886 		buffer[0x41]);
9887 	 return 0;
9888       }
9889 
9890       paneltype = Panel_Custom;
9891       SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
9892       SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
9893       switch(xres) {
9894 #if 0
9895          case 800:
9896 	     if(yres == 600) {
9897 	     	paneltype = Panel_800x600;
9898 	     	checkexpand = TRUE;
9899 	     }
9900 	     break;
9901 #endif
9902          case 1024:
9903 	     if(yres == 768) {
9904 	     	paneltype = Panel_1024x768;
9905 	     	checkexpand = TRUE;
9906 	     }
9907 	     break;
9908 	 case 1280:
9909 	     if(yres == 960) {
9910 	        if(pSiS->VGAEngine == SIS_315_VGA) {
9911 	     	   paneltype = Panel310_1280x960;
9912 		} else {
9913 		   paneltype = Panel300_1280x960;
9914 		}
9915 	     } else if(yres == 1024) {
9916 	     	paneltype = Panel_1280x1024;
9917 		checkexpand = TRUE;
9918 	     }
9919 	     /* 1280x768 treated as custom here */
9920 	     break;
9921 	 case 1400:
9922 	     if(pSiS->VGAEngine == SIS_315_VGA) {
9923 	        if(yres == 1050) {
9924 	           paneltype = Panel310_1400x1050;
9925 		   checkexpand = TRUE;
9926 	        }
9927 	     }
9928       	     break;
9929 #if 0    /* Treat this one as custom since we have no timing data yet */
9930 	 case 1600:
9931 	     if(pSiS->VGAEngine == SIS_315_VGA) {
9932 	        if(pSiS->VBFlags & VB_301C) {
9933 	           if(yres == 1200) {
9934 	              paneltype = Panel310_1600x1200;
9935 		      checkexpand = TRUE;
9936 		   }
9937 	        }
9938 	     }
9939       	     break;
9940 #endif
9941       }
9942 
9943       /* Determine if RGB18 or RGB24 */
9944       if(index) {
9945          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
9946 	    cr37 |= 0x01;
9947 	 }
9948       }
9949 
9950       if(checkexpand) {
9951          /* TODO - for now, we let the panel scale */
9952 	 cr37 |= 0x10;
9953       }
9954 
9955       /* Now seek 4-Byte Timing codes and extract sync pol info */
9956       index = 0x80;
9957       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
9958          lumsize = buffer[0x80] & 0x1f;
9959 	 if(buffer[0x80] & 0x80) lumsize *= 3;
9960 	 lumsize++;  /* luminance header byte */
9961 	 index += lumsize;
9962       }
9963       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
9964       index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
9965       numcodes = (buffer[0x7f] & 0xf8) >> 3;
9966       if(numcodes) {
9967          myindex = index;
9968  	 seekcode = (xres - 256) / 16;
9969      	 for(i=0; i<numcodes; i++) {
9970 	    if(buffer[myindex] == seekcode) break;
9971 	    myindex += 4;
9972 	 }
9973 	 if(buffer[myindex] == seekcode) {
9974 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
9975 	 } else {
9976 	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9977 	        "CRT2: Unable to retrieve Sync polarity information\n");
9978 	 }
9979       } else {
9980          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9981 	     "CRT2: Unable to retrieve Sync polarity information\n");
9982       }
9983 
9984       /* Now seek the detailed timing descriptions for custom panels */
9985       if(paneltype == Panel_Custom) {
9986 
9987          SiS_Pr->CP_Supports64048075 = TRUE;
9988 
9989          index += (numcodes * 4);
9990 	 numcodes = buffer[0x7f] & 0x07;
9991 	 for(i=0; i<numcodes; i++, index += 18) {
9992 	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
9993             yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
9994 
9995 	    SiS_Pr->CP_HDisplay[i] = xres;
9996 	    SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
9997             SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
9998 	    SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
9999 	    SiS_Pr->CP_HBlankStart[i] = xres + 1;
10000 	    SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10001 
10002 	    SiS_Pr->CP_VDisplay[i] = yres;
10003             SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10004             SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10005 	    SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10006 	    SiS_Pr->CP_VBlankStart[i] = yres + 1;
10007 	    SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10008 
10009 	    SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10010 
10011 	    SiS_Pr->CP_DataValid[i] = TRUE;
10012 
10013 	    if((SiS_Pr->CP_HDisplay[i] & 7)						||
10014 	       (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  			||
10015 	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   			||
10016 	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     			||
10017 	       (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) 			||
10018 	       (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    			||
10019 	       (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      			||
10020 	       (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  			||
10021 	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   			||
10022 	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     			||
10023 	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  			||
10024 	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    			||
10025 	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      			||
10026 	       (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10027 	        ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
10028 	       (buffer[index + 17] & 0x80)) {
10029 
10030 	       SiS_Pr->CP_DataValid[i] = FALSE;
10031 
10032 	    } else {
10033 
10034 	       SiS_Pr->CP_HaveCustomData = TRUE;
10035 
10036 	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10037 
10038 	       if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
10039 	          SiS_Pr->CP_PreferredIndex = i;
10040 	       }
10041 
10042 	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10043 	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10044 	       SiS_Pr->CP_SyncValid[i] = TRUE;
10045 
10046 	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10047 	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10048 
10049 	       /* We must assume the panel can scale, since we have
10050 	        * no scaling data
10051     	        */
10052 	       cr37 |= 0x10;
10053 
10054 	    }
10055 	 }
10056 
10057       }
10058 
10059       break;
10060 
10061    }
10062 
10063    /* 1280x960 panels are always RGB24, unable to scale and use
10064     * high active sync polarity
10065     */
10066    if(pSiS->VGAEngine == SIS_315_VGA) {
10067       if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10068    } else {
10069       if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10070    }
10071 
10072    for(i = 0; i < 7; i++) {
10073       if(SiS_Pr->CP_DataValid[i]) {
10074          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10075             "Non-standard LCD timing data no. %d:\n", i);
10076          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10077 	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10078 	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10079 	    SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10080          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10081             "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10082             SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10083    	    SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10084          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10085 	    "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10086 	 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10087 	    "   To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10088 	    SiS_Pr->CP_HDisplay[i],
10089 	    SiS_Pr->CP_VDisplay[i]);
10090       }
10091    }
10092 
10093    if(paneltype) {
10094        if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10095        if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10096        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10097        SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10098        cr37 &= 0xf1;
10099        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10100        SiS_Pr->PanelSelfDetected = TRUE;
10101 #ifdef TWDEBUG
10102        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10103        	   "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10104 #endif
10105    } else {
10106        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10107        SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10108    }
10109    return 0;
10110 }
10111 
10112 USHORT
SiS_SenseVGA2DDC(SiS_Private * SiS_Pr,SISPtr pSiS)10113 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10114 {
10115    USHORT DDCdatatype,flag;
10116    BOOLEAN foundcrt = FALSE;
10117    int retry;
10118    unsigned char buffer[256];
10119 
10120    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10121 
10122    if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10123 
10124    SiS_Pr->SiS_DDC_SecAddr = 0x00;
10125 
10126    /* Probe supported DA's */
10127    flag = SiS_ProbeDDC(SiS_Pr);
10128    if(flag & 0x10) {
10129       SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
10130       DDCdatatype = 4;
10131    } else if(flag & 0x08) {
10132       SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
10133       DDCdatatype = 3;
10134    } else if(flag & 0x02) {
10135       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
10136       DDCdatatype = 1;
10137    } else {
10138    	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10139 		"Do DDC answer\n");
10140    	return 0;				/* no DDC support (or no device attached) */
10141    }
10142 
10143    /* Read the entire EDID */
10144    retry = 2;
10145    do {
10146       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10147          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10148 	 	"CRT2: DDC read failed (attempt %d), %s\n",
10149 		(3-retry), (retry == 1) ? "giving up" : "retrying");
10150 	 retry--;
10151 	 if(retry == 0) return 0xFFFF;
10152       } else break;
10153    } while(1);
10154 
10155    /* Analyze EDID. We don't have many chances to
10156     * distinguish a flat panel from a CRT...
10157     */
10158    switch(DDCdatatype) {
10159    case 1:
10160       if(!(checkedid1(buffer))) {
10161           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10162 	  	"CRT2: EDID corrupt\n");
10163       	  return 0;
10164       }
10165       if(buffer[0x14] & 0x80) {			/* Display uses digital input */
10166           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10167 	  	"CRT2: Attached display expects digital input\n");
10168       	  return 0;
10169       }
10170       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10171       SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10172       foundcrt = TRUE;
10173       break;
10174    case 3:
10175    case 4:
10176       if(!(checkedid2(buffer))) {
10177           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10178 	  	"CRT2: EDID corrupt\n");
10179       	  return 0;
10180       }
10181       if( ((buffer[0x41] & 0x0f) != 0x01) &&  	/* Display does not support analog input */
10182           ((buffer[0x41] & 0x0f) != 0x02) &&
10183 	  ((buffer[0x41] & 0xf0) != 0x10) &&
10184 	  ((buffer[0x41] & 0xf0) != 0x20) ) {
10185 	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10186 	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
10187 		buffer[0x41]);
10188 	  return 0;
10189       }
10190       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10191       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10192       foundcrt = TRUE;
10193       break;
10194    }
10195 
10196    if(foundcrt) {
10197       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10198    }
10199    return(0);
10200 }
10201 
10202 #endif
10203 
10204 void
SiS_SetCH70xxANDOR(SiS_Private * SiS_Pr,USHORT tempax,USHORT tempbh)10205 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10206 {
10207   USHORT tempbl;
10208 
10209   tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10210   tempbl = (((tempbl & tempbh) << 8) | tempax);
10211   SiS_SetCH70xx(SiS_Pr,tempbl);
10212 }
10213 
10214 /* Generic I2C functions for Chrontel & DDC --------- */
10215 
10216 void
SiS_SetSwitchDDC2(SiS_Private * SiS_Pr)10217 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10218 {
10219   SiS_SetSCLKHigh(SiS_Pr);
10220   SiS_WaitRetrace1(SiS_Pr);
10221 
10222   SiS_SetSCLKLow(SiS_Pr);
10223   SiS_WaitRetrace1(SiS_Pr);
10224 }
10225 
10226 USHORT
SiS_ReadDDC1Bit(SiS_Private * SiS_Pr)10227 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10228 {
10229    SiS_WaitRetrace1(SiS_Pr);
10230    return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10231 }
10232 
10233 /* Set I2C start condition */
10234 /* This is done by a SD high-to-low transition while SC is high */
10235 USHORT
SiS_SetStart(SiS_Private * SiS_Pr)10236 SiS_SetStart(SiS_Private *SiS_Pr)
10237 {
10238   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
10239   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10240     		  SiS_Pr->SiS_DDC_Index,
10241                   SiS_Pr->SiS_DDC_NData,
10242 		  SiS_Pr->SiS_DDC_Data);             			   /* SD->high */
10243   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high */
10244   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10245   		  SiS_Pr->SiS_DDC_Index,
10246                   SiS_Pr->SiS_DDC_NData,
10247 		  0x00);                             			   /* SD->low = start condition */
10248   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
10249   return 0;
10250 }
10251 
10252 /* Set I2C stop condition */
10253 /* This is done by a SD low-to-high transition while SC is high */
10254 USHORT
SiS_SetStop(SiS_Private * SiS_Pr)10255 SiS_SetStop(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 		  0x00);          		   			   /* SD->low   */
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 		  SiS_Pr->SiS_DDC_Data);  	   			   /* SD->high = stop condition */
10267   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->high) */
10268   return 0;
10269 }
10270 
10271 /* Write 8 bits of data */
10272 USHORT
SiS_WriteDDC2Data(SiS_Private * SiS_Pr,USHORT tempax)10273 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10274 {
10275   USHORT i,flag,temp;
10276 
10277   flag = 0x80;
10278   for(i=0; i<8; i++) {
10279     SiS_SetSCLKLow(SiS_Pr);				                      /* SC->low */
10280     if(tempax & flag) {
10281       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10282       		      SiS_Pr->SiS_DDC_Index,
10283                       SiS_Pr->SiS_DDC_NData,
10284 		      SiS_Pr->SiS_DDC_Data);            		      /* Write bit (1) to SD */
10285     } else {
10286       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10287       		      SiS_Pr->SiS_DDC_Index,
10288                       SiS_Pr->SiS_DDC_NData,
10289 		      0x00);                            		      /* Write bit (0) to SD */
10290     }
10291     SiS_SetSCLKHigh(SiS_Pr);				                      /* SC->high */
10292     flag >>= 1;
10293   }
10294   temp = SiS_CheckACK(SiS_Pr);				                      /* Check acknowledge */
10295   return(temp);
10296 }
10297 
10298 USHORT
SiS_ReadDDC2Data(SiS_Private * SiS_Pr,USHORT tempax)10299 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10300 {
10301   USHORT i,temp,getdata;
10302 
10303   getdata=0;
10304   for(i=0; i<8; i++) {
10305     getdata <<= 1;
10306     SiS_SetSCLKLow(SiS_Pr);
10307     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10308     		    SiS_Pr->SiS_DDC_Index,
10309                     SiS_Pr->SiS_DDC_NData,
10310 		    SiS_Pr->SiS_DDC_Data);
10311     SiS_SetSCLKHigh(SiS_Pr);
10312     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10313     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10314   }
10315   return(getdata);
10316 }
10317 
10318 USHORT
SiS_SetSCLKLow(SiS_Private * SiS_Pr)10319 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10320 {
10321   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10322   		  SiS_Pr->SiS_DDC_Index,
10323                   SiS_Pr->SiS_DDC_NClk,
10324 		  0x00);      					/* SetSCLKLow()  */
10325   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10326   return 0;
10327 }
10328 
10329 USHORT
SiS_SetSCLKHigh(SiS_Private * SiS_Pr)10330 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10331 {
10332   USHORT temp, watchdog=1000;
10333 
10334   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10335   		  SiS_Pr->SiS_DDC_Index,
10336                   SiS_Pr->SiS_DDC_NClk,
10337 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
10338   do {
10339     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10340   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10341   if (!watchdog) {
10342 #ifdef TWDEBUG
10343         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10344 #endif
10345   	return 0xFFFF;
10346   }
10347   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10348   return 0;
10349 }
10350 
10351 /* Check I2C acknowledge */
10352 /* Returns 0 if ack ok, non-0 if ack not ok */
10353 USHORT
SiS_CheckACK(SiS_Private * SiS_Pr)10354 SiS_CheckACK(SiS_Private *SiS_Pr)
10355 {
10356   USHORT tempah;
10357 
10358   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
10359   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10360   		  SiS_Pr->SiS_DDC_Index,
10361                   SiS_Pr->SiS_DDC_NData,
10362 		  SiS_Pr->SiS_DDC_Data);     			   /* (SD->high) */
10363   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
10364   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10365   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
10366   if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* Ack OK if bit = 0 */
10367   else return(0);
10368 }
10369 
10370 /* End of I2C functions ----------------------- */
10371 
10372 
10373 /* =============== SiS 315/330 O.E.M. ================= */
10374 
10375 #ifdef SIS315H
10376 
10377 static USHORT
GetRAMDACromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10378 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10379 {
10380   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10381   USHORT romptr;
10382 
10383   if(HwInfo->jChipType < SIS_330) {
10384      romptr = SISGETROMW(0x128);
10385      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10386         romptr = SISGETROMW(0x12a);
10387   } else {
10388      romptr = SISGETROMW(0x1a8);
10389      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10390         romptr = SISGETROMW(0x1aa);
10391   }
10392   return(romptr);
10393 }
10394 
10395 static USHORT
GetLCDromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10396 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10397 {
10398   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10399   USHORT romptr;
10400 
10401   if(HwInfo->jChipType < SIS_330) {
10402      romptr = SISGETROMW(0x120);
10403      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10404         romptr = SISGETROMW(0x122);
10405   } else {
10406      romptr = SISGETROMW(0x1a0);
10407      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10408         romptr = SISGETROMW(0x1a2);
10409   }
10410   return(romptr);
10411 }
10412 
10413 static USHORT
GetTVromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10414 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10415 {
10416   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10417   USHORT romptr;
10418 
10419   if(HwInfo->jChipType < SIS_330) {
10420      romptr = SISGETROMW(0x114);
10421      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10422         romptr = SISGETROMW(0x11a);
10423   } else {
10424      romptr = SISGETROMW(0x194);
10425      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10426         romptr = SISGETROMW(0x19a);
10427   }
10428   return(romptr);
10429 }
10430 
10431 static USHORT
GetLCDPtrIndexBIOS(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10432 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10433 {
10434   USHORT index;
10435 
10436   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10437      if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10438         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10439 	   index >>= 4;
10440 	   index *= 3;
10441 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10442            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10443            return index;
10444 	}
10445      }
10446   }
10447 
10448   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10449   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
10450   else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10451   index--;
10452   index *= 3;
10453   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10454   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10455   return index;
10456 }
10457 
10458 static USHORT
GetLCDPtrIndex(SiS_Private * SiS_Pr)10459 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10460 {
10461   USHORT index;
10462 
10463   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10464   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
10465   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10466   return index;
10467 }
10468 
10469 static USHORT
GetTVPtrIndex(SiS_Private * SiS_Pr)10470 GetTVPtrIndex(SiS_Private *SiS_Pr)
10471 {
10472   USHORT index;
10473 
10474   index = 0;
10475   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10476   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10477 
10478   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10479 
10480   index <<= 1;
10481 
10482   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10483      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10484      index++;
10485   }
10486 
10487   return index;
10488 }
10489 
10490 static ULONG
GetOEMTVPtr661_2_GEN(SiS_Private * SiS_Pr,int addme)10491 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10492 {
10493    USHORT index = 0, temp = 0;
10494 
10495    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
10496    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
10497    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
10498    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10499    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10500       index = 4;
10501       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
10502       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10503    }
10504 
10505    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10506       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10507          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10508 	 index += addme;
10509 	 temp++;
10510       }
10511       temp += 0x0100;
10512    }
10513    return(ULONG)(index | (temp << 16));
10514 }
10515 
10516 static ULONG
GetOEMTVPtr661_2_OLD(SiS_Private * SiS_Pr)10517 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10518 {
10519    return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10520 }
10521 
10522 #if 0
10523 static ULONG
10524 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10525 {
10526    return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10527 }
10528 #endif
10529 
10530 static int
GetOEMTVPtr661(SiS_Private * SiS_Pr)10531 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10532 {
10533    int index = 0;
10534 
10535    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
10536    if(SiS_Pr->SiS_ROMNew) {
10537       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10538       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10539       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10540       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
10541    } else {
10542       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
10543       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10544       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10545       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10546    }
10547 
10548    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10549 
10550    return index;
10551 }
10552 
10553 static void
SetDelayComp(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo)10554 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10555 {
10556   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10557   USHORT delay=0,index,myindex,temp,romptr=0;
10558   BOOLEAN dochiptest = TRUE;
10559 
10560   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10561      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10562   } else {
10563      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10564   }
10565 
10566   /* Find delay (from ROM, internal tables, PCI subsystem) */
10567 
10568   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
10569 
10570      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10571         romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10572      }
10573      if(romptr) delay = ROMAddr[romptr];
10574      else {
10575         delay = 0x04;
10576         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10577 	   if(IS_SIS650) {
10578 	      delay = 0x0a;
10579 	   } else if(IS_SIS740) {
10580 	      delay = 0x00;
10581 	   } else if(HwInfo->jChipType < SIS_330) {
10582 	      delay = 0x0c;
10583 	   } else {
10584 	      delay = 0x0c;
10585 	   }
10586 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10587            delay = 0x00;
10588 	}
10589      }
10590 
10591   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
10592 
10593      BOOLEAN gotitfrompci = FALSE;
10594 
10595      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10596 
10597      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10598 	if(SiS_Pr->PDC != -1) {
10599            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10600 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10601 	   return;
10602 	}
10603      } else {
10604 	if(SiS_Pr->PDCA != -1) {
10605 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10606 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10607 	   return;
10608 	}
10609      }
10610 
10611      /* Custom Panel? */
10612 
10613      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10614         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10615 	   delay = 0x00;
10616 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10617 	      delay = 0x20;
10618 	   }
10619 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10620 	} else {
10621 	   delay = 0x0c;
10622 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10623 	   else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10624 	      if(IS_SIS740) delay = 0x01;
10625 	      else          delay = 0x03;
10626 	   }
10627 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10628 	}
10629         return;
10630      }
10631 
10632      /* This is a piece of typical SiS crap: They code the OEM LCD
10633       * delay into the code, at no defined place in the BIOS.
10634       * We now have to start doing a PCI subsystem check here.
10635       */
10636 
10637      switch(SiS_Pr->SiS_CustomT) {
10638      case CUT_COMPAQ1280:
10639      case CUT_COMPAQ12802:
10640 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10641 	   gotitfrompci = TRUE;
10642 	   dochiptest = FALSE;
10643 	   delay = 0x03;
10644 	}
10645 	break;
10646      case CUT_CLEVO1400:
10647      case CUT_CLEVO14002:
10648 	gotitfrompci = TRUE;
10649 	dochiptest = FALSE;
10650 	delay = 0x02;
10651 	break;
10652      case CUT_CLEVO1024:
10653      case CUT_CLEVO10242:
10654         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10655 	   gotitfrompci = TRUE;
10656 	   dochiptest = FALSE;
10657 	   delay = 0x33;
10658 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10659 	   delay &= 0x0f;
10660 	}
10661 	break;
10662      }
10663 
10664      /* Could we find it through the PCI ID? If no, use ROM or table */
10665 
10666      if(!gotitfrompci) {
10667 
10668         index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10669         myindex = GetLCDPtrIndex(SiS_Pr);
10670 
10671         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10672 
10673            if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10674 
10675               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10676 	         /* Always use the second pointer on 650; some BIOSes */
10677                  /* still carry old 301 data at the first location    */
10678 	         /* romptr = SISGETROMW(0x120);                       */
10679 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10680 	         romptr = SISGETROMW(0x122);
10681 	         if(!romptr) return;
10682 	         delay = ROMAddr[(romptr + index)];
10683 	      } else {
10684                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10685 	      }
10686 
10687           } else {
10688 
10689              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10690 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10691 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10692 
10693           }
10694 
10695         } else if(SiS_Pr->SiS_UseROM 			      &&
10696 		  (!(SiS_Pr->SiS_ROMNew))		      &&
10697 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10698 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10699 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10700 
10701 	   /* Data for 1280x1024 wrong in 301B BIOS */
10702            romptr = GetLCDromptr(SiS_Pr, HwInfo);
10703 	   if(!romptr) return;
10704 	   delay = ROMAddr[(romptr + index)];
10705 
10706         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10707 
10708 	   if(IS_SIS740) delay = 0x03;
10709 	   else          delay = 0x00;
10710 
10711 	} else {
10712 
10713            delay = SiS310_LCDDelayCompensation_301[myindex];
10714 	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10715 	      if(IS_SIS740) delay = 0x01;
10716 	      else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10717 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10718 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10719 	      if(IS_SIS740) delay = 0x01;  /* ? */
10720 	      else          delay = 0x03;
10721 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10722 	      if(IS_SIS740) delay = 0x01;
10723 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10724 	   }
10725 
10726         }
10727 
10728      }  /* got it from PCI */
10729 
10730      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10731 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10732 	dochiptest = FALSE;
10733      }
10734 
10735   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
10736 
10737      index = GetTVPtrIndex(SiS_Pr);
10738 
10739      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10740 
10741         if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
10742 
10743            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10744 	      /* Always use the second pointer on 650; some BIOSes */
10745               /* still carry old 301 data at the first location    */
10746               /* romptr = SISGETROMW(0x114);			   */
10747 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10748 	      romptr = SISGETROMW(0x11a);
10749 	      if(!romptr) return;
10750 	      delay = ROMAddr[romptr + index];
10751 
10752 	   } else {
10753 
10754 	      delay = SiS310_TVDelayCompensation_301B[index];
10755 
10756 	   }
10757 
10758         } else {
10759 
10760            switch(SiS_Pr->SiS_CustomT) {
10761 	   case CUT_COMPAQ1280:
10762 	   case CUT_COMPAQ12802:
10763 	   case CUT_CLEVO1400:
10764 	   case CUT_CLEVO14002:
10765 	      delay = 0x02;
10766 	      dochiptest = FALSE;
10767 	      break;
10768 	   case CUT_CLEVO1024:
10769 	   case CUT_CLEVO10242:
10770 	      delay = 0x03;
10771 	      dochiptest = FALSE;
10772    	      break;
10773 	   default:
10774               delay = SiS310_TVDelayCompensation_651301LV[index];
10775 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10776 	         delay = SiS310_TVDelayCompensation_651302LV[index];
10777 	      }
10778 	   }
10779         }
10780 
10781      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10782 
10783         romptr = GetTVromptr(SiS_Pr, HwInfo);
10784 	if(!romptr) return;
10785 	delay = ROMAddr[romptr + index];
10786 
10787      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10788 
10789         delay = SiS310_TVDelayCompensation_LVDS[index];
10790 
10791      } else {
10792 
10793 	delay = SiS310_TVDelayCompensation_301[index];
10794         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10795 	   if(IS_SIS740) {
10796 	      delay = SiS310_TVDelayCompensation_740301B[index];
10797 	      /* LV: use 301 data? BIOS bug? */
10798 	   } else {
10799               delay = SiS310_TVDelayCompensation_301B[index];
10800 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10801 	   }
10802 	}
10803 
10804      }
10805 
10806      if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
10807 	delay &= 0x0f;
10808 	dochiptest = FALSE;
10809      }
10810 
10811   } else return;
10812 
10813   /* Write delay */
10814 
10815   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10816 
10817      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
10818 
10819         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10820         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
10821 	   delay &= 0x0f;
10822 	   delay |= 0xb0;
10823         } else if(temp == 6) {
10824            delay &= 0x0f;
10825 	   delay |= 0xc0;
10826         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
10827 	   delay = 0x35;
10828         }
10829         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10830 
10831      } else {
10832 
10833         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10834 
10835      }
10836 
10837   } else {  /* LVDS */
10838 
10839      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10840         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10841      } else {
10842         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10843            delay <<= 4;
10844            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10845         } else {
10846            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10847         }
10848      }
10849 
10850   }
10851 
10852 }
10853 
10854 static void
SetAntiFlicker(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10855 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10856                USHORT ModeNo,USHORT ModeIdIndex)
10857 {
10858   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10859   USHORT index,temp,temp1,romptr=0;
10860 
10861   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10862 
10863   if(ModeNo<=0x13)
10864      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10865   else
10866      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10867 
10868   temp = GetTVPtrIndex(SiS_Pr);
10869   temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10870   temp1 = temp;
10871 
10872   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10873      if(HwInfo->jChipType >= SIS_661) {
10874         temp1 = GetOEMTVPtr661(SiS_Pr);
10875         temp1 >>= 1;
10876         romptr = SISGETROMW(0x260);
10877         if(HwInfo->jChipType >= SIS_760) {
10878 	   romptr = SISGETROMW(0x360);
10879 	}
10880      } else if(HwInfo->jChipType >= SIS_330) {
10881         romptr = SISGETROMW(0x192);
10882      } else {
10883         romptr = SISGETROMW(0x112);
10884      }
10885   }
10886 
10887   if(romptr) {
10888      temp1 <<= 1;
10889      temp = ROMAddr[romptr + temp1 + index];
10890   } else {
10891      temp = SiS310_TVAntiFlick1[temp][index];
10892   }
10893   temp <<= 4;
10894 
10895   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10896 }
10897 
10898 static void
SetEdgeEnhance(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10899 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10900                USHORT ModeNo,USHORT ModeIdIndex)
10901 {
10902   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10903   USHORT index,temp,temp1,romptr=0;
10904 
10905   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10906 
10907   if(ModeNo <= 0x13)
10908      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10909   else
10910      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10911 
10912   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10913      if(HwInfo->jChipType >= SIS_661) {
10914         romptr = SISGETROMW(0x26c);
10915         if(HwInfo->jChipType >= SIS_760) {
10916 	   romptr = SISGETROMW(0x36c);
10917 	}
10918 	temp1 = GetOEMTVPtr661(SiS_Pr);
10919         temp1 >>= 1;
10920      } else if(HwInfo->jChipType >= SIS_330) {
10921         romptr = SISGETROMW(0x1a4);
10922      } else {
10923         romptr = SISGETROMW(0x124);
10924      }
10925   }
10926 
10927   if(romptr) {
10928      temp1 <<= 1;
10929      temp = ROMAddr[romptr + temp1 + index];
10930   } else {
10931      temp = SiS310_TVEdge1[temp][index];
10932   }
10933   temp <<= 5;
10934   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10935 }
10936 
10937 static void
SetYFilter(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10938 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10939            USHORT ModeNo,USHORT ModeIdIndex)
10940 {
10941   USHORT index, temp, i, j;
10942 
10943   if(ModeNo <= 0x13) {
10944      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10945   } else {
10946      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10947   }
10948 
10949   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10950 
10951   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10952   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10953   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10954   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10955 
10956   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10957      for(i=0x35, j=0; i<=0x38; i++, j++) {
10958         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10959      }
10960      for(i=0x48; i<=0x4A; i++, j++) {
10961         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10962      }
10963   } else {
10964      for(i=0x35, j=0; i<=0x38; i++, j++) {
10965         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10966      }
10967   }
10968 }
10969 
10970 static void
SetPhaseIncr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10971 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10972              USHORT ModeNo,USHORT ModeIdIndex)
10973 {
10974   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
10975   USHORT index,temp,i,j,resinfo,romptr=0;
10976   ULONG  lindex;
10977 
10978   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10979 
10980   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10981   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10982 
10983   if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10984      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10985      lindex <<= 2;
10986      for(j=0, i=0x31; i<=0x34; i++, j++) {
10987         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
10988      }
10989      return;
10990   }
10991 
10992   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10993   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10994 
10995   if(ModeNo<=0x13) {
10996      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10997   } else {
10998      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10999   }
11000 
11001   temp = GetTVPtrIndex(SiS_Pr);
11002   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
11003    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
11004    */
11005   if(SiS_Pr->SiS_UseROM) {
11006      romptr = SISGETROMW(0x116);
11007      if(HwInfo->jChipType >= SIS_330) {
11008         romptr = SISGETROMW(0x196);
11009      }
11010      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11011         romptr = SISGETROMW(0x11c);
11012 	if(HwInfo->jChipType >= SIS_330) {
11013 	   romptr = SISGETROMW(0x19c);
11014 	}
11015 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11016 	   romptr = SISGETROMW(0x116);
11017 	   if(HwInfo->jChipType >= SIS_330) {
11018               romptr = SISGETROMW(0x196);
11019            }
11020 	}
11021      }
11022   }
11023   if(romptr) {
11024      romptr += (temp << 2);
11025      for(j=0, i=0x31; i<=0x34; i++, j++) {
11026         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11027      }
11028   } else {
11029      index = temp % 2;
11030      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
11031      for(j=0, i=0x31; i<=0x34; i++, j++) {
11032         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11033 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11034         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11035            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11036         else
11037            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11038      }
11039   }
11040 
11041   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11042      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11043         if((resinfo == SIS_RI_640x480) ||
11044 	   (resinfo == SIS_RI_800x600)) {
11045 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11046 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11047 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11048 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11049 	} else if(resinfo == SIS_RI_1024x768) {
11050 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11051 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11052 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11053 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11054 	}
11055      }
11056   }
11057 }
11058 
11059 void
SiS_OEM310Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11060 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11061                   USHORT ModeNo,USHORT ModeIdIndex)
11062 {
11063    SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11064 
11065    if(SiS_Pr->UseCustomMode) return;
11066 
11067    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11068       SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11069       SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11070       SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11071       if(SiS_Pr->SiS_VBType & VB_SIS301) {
11072          SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11073       }
11074    }
11075 }
11076 
11077 static void
SetDelayComp661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RTI)11078 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11079                 USHORT ModeIdIndex, USHORT RTI)
11080 {
11081    USHORT delay = 0, romptr = 0, index;
11082    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11083 
11084    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11085       return;
11086 
11087    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11088 
11089    if(SiS_Pr->SiS_ROMNew) {
11090       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
11091          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11092 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11093          index = 25;
11094          if(SiS_Pr->UseCustomMode) {
11095 	    index = SiS_Pr->CSRClock;
11096          } else if(ModeNo > 0x13) {
11097             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11098             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11099          }
11100 	 if(index < 25) index = 25;
11101          index = ((index / 25) - 1) << 1;
11102          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11103 	    index++;
11104 	 }
11105 	 romptr = SISGETROMW(0x104);  /* 0x4ae */
11106          delay = ROMAddr[romptr + index];
11107          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11108             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11109             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11110          } else {
11111             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11112 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11113          }
11114          return;
11115       }
11116    }
11117 
11118    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11119 
11120    if(SiS_Pr->UseCustomMode) delay = 0x04;
11121    else if(ModeNo <= 0x13)   delay = 0x04;
11122    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11123    delay |= (delay << 8);
11124 
11125    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11126 
11127       /* 3. TV */
11128 
11129       index = GetOEMTVPtr661(SiS_Pr);
11130       if(SiS_Pr->SiS_ROMNew) {
11131          romptr = SISGETROMW(0x106);  /* 0x4ba */
11132          delay = ROMAddr[romptr + index];
11133       } else {
11134          delay = 0x04;
11135       }
11136 
11137    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11138 
11139       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11140 
11141       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11142           ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11143 
11144 	 /* For LV, the BIOS must know about the correct value */
11145 	 delay = ROMAddr[romptr + 0x0d];		/* LCD  */
11146 	 delay |= (ROMAddr[romptr + 0x0c] << 8);	/* LCDA */
11147 
11148       } else {
11149 
11150          /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
11151          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11152             if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11153 	       delay = 0x0404;
11154             } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
11155 	       delay = 0x0404;
11156             } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11157 	       delay = 0x1004;
11158             } else
11159 	       delay = 0x0000;
11160          }
11161 
11162 	 /* Override by detected or user-set values */
11163 	 /* (but only if, for some reason, we can't read value from BIOS) */
11164          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11165             delay = SiS_Pr->PDC & 0x1f;
11166          }
11167          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11168             delay = (SiS_Pr->PDCA & 0x1f) << 8;
11169          }
11170 
11171       }
11172 
11173    }
11174 
11175    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11176       delay >>= 8;
11177       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11178       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11179    } else {
11180       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11181       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11182    }
11183 }
11184 
11185 static void
SetCRT2SyncDither661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT RTI)11186 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11187 {
11188    USHORT infoflag;
11189    UCHAR temp;
11190 
11191    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11192 
11193       if(ModeNo <= 0x13) {
11194          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11195       } else if(SiS_Pr->UseCustomMode) {
11196          infoflag = SiS_Pr->CInfoFlag;
11197       } else {
11198          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11199       }
11200       infoflag &= 0xc0;
11201 
11202       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
11203       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
11204          temp &= 0x3f;
11205 	 temp |= infoflag;
11206       } else {
11207          if(temp & 0x20) infoflag = temp;
11208       }
11209       if(temp & 0x01) infoflag |= 0x01;
11210 
11211       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11212          temp = 0x0c;
11213          if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
11214          temp |= (infoflag >> 6);
11215          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11216       } else {
11217          temp = 0;
11218          if(infoflag & 0x01) temp |= 0x80;
11219          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11220          temp = 0x30;
11221          if(infoflag & 0x01) temp = 0x20;
11222          infoflag &= 0xc0;
11223          temp |= infoflag;
11224          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11225       }
11226 
11227    }
11228 }
11229 
11230 static void
SetPanelParms661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)11231 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11232 {
11233    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11234    USHORT romptr, temp1, temp2;
11235 
11236    if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11237       if(SiS_Pr->LVDSHL != -1) {
11238          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11239       }
11240    }
11241 
11242    if(SiS_Pr->SiS_ROMNew) {
11243 
11244       if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11245          if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11246             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11247 	    temp2 = 0xfc;
11248 	    if(SiS_Pr->LVDSHL != -1) {
11249 	      temp1 &= 0xfc;
11250 	      temp2 = 0xf3;
11251 	    }
11252 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11253          }
11254 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11255             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11256             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11257 	 }
11258       }
11259 
11260    }
11261 }
11262 
11263 void
SiS_OEM661Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)11264 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11265                   USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11266 {
11267    if(SiS_Pr->SiS_VBType & VB_SISVB) {
11268 
11269       SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11270 
11271       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11272          SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11273          SetPanelParms661(SiS_Pr,HwInfo);
11274       }
11275 
11276       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11277          SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11278          SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11279          SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11280          if(SiS_Pr->SiS_VBType & VB_SIS301) {
11281             SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11282          }
11283       }
11284    }
11285 }
11286 
11287 /* FinalizeLCD
11288  * This finalizes some CRT2 registers for the very panel used.
11289  * If we have a backup if these registers, we use it; otherwise
11290  * we set the register according to most BIOSes. However, this
11291  * function looks quite different in every BIOS, so you better
11292  * pray that we have a backup...
11293  */
11294 void
SiS_FinalizeLCD(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)11295 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11296                 PSIS_HW_INFO HwInfo)
11297 {
11298   USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11299   USHORT resinfo,modeflag;
11300 
11301   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11302 
11303   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11304      if(SiS_Pr->LVDSHL != -1) {
11305         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11306      }
11307   }
11308 
11309   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11310   if(SiS_Pr->UseCustomMode) return;
11311 
11312   switch(SiS_Pr->SiS_CustomT) {
11313   case CUT_COMPAQ1280:
11314   case CUT_COMPAQ12802:
11315   case CUT_CLEVO1400:
11316   case CUT_CLEVO14002:
11317      return;
11318   }
11319 
11320   if(ModeNo <= 0x13) {
11321      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11322      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11323   } else {
11324      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11325      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11326   }
11327 
11328   if(IS_SIS650) {
11329      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11330         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11331 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11332 	} else {
11333            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11334 	}
11335      }
11336   }
11337 
11338   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11339      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11340         /* Maybe all panels? */
11341         if(SiS_Pr->LVDSHL == -1) {
11342            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11343 	}
11344 	return;
11345      }
11346   }
11347 
11348   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11349      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11350         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11351 	   if(SiS_Pr->LVDSHL == -1) {
11352 	      /* Maybe all panels? */
11353               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11354 	   }
11355 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11356 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11357 	      if(tempch == 3) {
11358 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11359 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11360 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11361 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11362 	      }
11363 	   }
11364 	   return;
11365 	}
11366      }
11367   }
11368 
11369   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11370      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11371 #ifdef SET_EMI
11372 	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11373 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11374 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11375 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11376 	}
11377 #endif
11378      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11379         if(SiS_Pr->LVDSHL == -1) {
11380            /* Maybe ACER only? */
11381            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11382 	}
11383      }
11384      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11385      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11386 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11387 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11388 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11389 	   if(tempch == 0x03) {
11390 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11391 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11392 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11393 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11394 	   }
11395 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11396 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11397 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11398 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11399 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11400 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11401 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11402 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11403 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11404 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11405 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11406 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
11407 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11408 	      if(ModeNo <= 0x13) {
11409 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11410 		 if((resinfo == 0) || (resinfo == 2)) return;
11411 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11412 		 if((resinfo == 1) || (resinfo == 3)) return;
11413 	      }
11414 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11415 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11416 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
11417 #if 0
11418 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
11419 		 tempbx--;
11420 		 temp = tempbx & 0xff;
11421 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11422 		 temp = (tempbx >> 8) & 0x03;
11423 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11424 #endif
11425 	      }
11426 	   } else if(ModeNo <= 0x13) {
11427 	      if(ModeNo <= 1) {
11428 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11429 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11430 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11431 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11432 	      }
11433 	      if(!(modeflag & HalfDCLK)) {
11434 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11435 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11436 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11437 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11438 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11439 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11440 		 if(ModeNo == 0x12) {
11441 		    switch(tempch) {
11442 		       case 0:
11443 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11444 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11445 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11446 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11447 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11448 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11449 			  break;
11450 		       case 2:
11451 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11452 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11453 			  break;
11454 		       case 3:
11455 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11456 			  break;
11457 		    }
11458 		 }
11459 	      }
11460 	   }
11461 	}
11462      } else {
11463         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11464 	tempcl &= 0x0f;
11465 	tempbh &= 0x70;
11466 	tempbh >>= 4;
11467 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11468 	tempbx = (tempbh << 8) | tempbl;
11469 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11470 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11471 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11472 	      	 tempbx = 770;
11473 	      } else {
11474 	         if(tempbx > 770) tempbx = 770;
11475 		 if(SiS_Pr->SiS_VGAVDE < 600) {
11476 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
11477 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
11478 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11479 		    tempbx -= tempax;
11480 		 }
11481 	      }
11482 	   } else return;
11483 	}
11484 	temp = tempbx & 0xff;
11485 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11486 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
11487 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11488      }
11489   }
11490 }
11491 
11492 #endif
11493 
11494 /*  =================  SiS 300 O.E.M. ================== */
11495 
11496 #ifdef SIS300
11497 
11498 void
SetOEMLCDData2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefTabIndex)11499 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11500                USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11501 {
11502   USHORT crt2crtc=0, modeflag, myindex=0;
11503   UCHAR  temp;
11504   int i;
11505 
11506   if(ModeNo <= 0x13) {
11507      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11508      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11509   } else {
11510      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11511      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11512   }
11513 
11514   crt2crtc &= 0x3f;
11515 
11516   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11517      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11518   }
11519 
11520   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11521      if(modeflag & HalfDCLK) myindex = 1;
11522 
11523      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11524         for(i=0; i<7; i++) {
11525            if(barco_p1[myindex][crt2crtc][i][0]) {
11526 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11527 	                      barco_p1[myindex][crt2crtc][i][0],
11528 	   	   	      barco_p1[myindex][crt2crtc][i][2],
11529 			      barco_p1[myindex][crt2crtc][i][1]);
11530 	   }
11531         }
11532      }
11533      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11534      if(temp & 0x80) {
11535         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11536         temp++;
11537         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11538      }
11539   }
11540 }
11541 
11542 static USHORT
GetOEMLCDPtr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,int Flag)11543 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11544 {
11545   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11546   USHORT tempbx=0,romptr=0;
11547   UCHAR customtable300[] = {
11548   	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11549 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11550   };
11551   UCHAR customtable630[] = {
11552   	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11553 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11554   };
11555 
11556   if(HwInfo->jChipType == SIS_300) {
11557 
11558     tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
11559     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11560     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11561        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11562     }
11563     if(SiS_Pr->SiS_UseROM) {
11564        if(ROMAddr[0x235] & 0x80) {
11565           tempbx = SiS_Pr->SiS_LCDTypeInfo;
11566           if(Flag) {
11567 	     romptr = SISGETROMW(0x255);
11568 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11569 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11570              if(tempbx == 0xFF) return 0xFFFF;
11571           }
11572 	  tempbx <<= 1;
11573 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11574        }
11575     }
11576 
11577   } else {
11578 
11579     if(Flag) {
11580        if(SiS_Pr->SiS_UseROM) {
11581           romptr = SISGETROMW(0x255);
11582 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11583 	  else 	     tempbx = 0xff;
11584        } else {
11585           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11586        }
11587        if(tempbx == 0xFF) return 0xFFFF;
11588        tempbx <<= 2;
11589        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11590        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11591        return tempbx;
11592     }
11593     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11594     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11595     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11596   }
11597   return tempbx;
11598 }
11599 
11600 static void
SetOEMLCDDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11601 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11602                USHORT ModeNo,USHORT ModeIdIndex)
11603 {
11604   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11605   USHORT index,temp,romptr=0;
11606 
11607   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11608 
11609   if(SiS_Pr->SiS_UseROM) {
11610      if(!(ROMAddr[0x237] & 0x01)) return;
11611      if(!(ROMAddr[0x237] & 0x02)) return;
11612      romptr = SISGETROMW(0x24b);
11613   }
11614 
11615   /* The Panel Compensation Delay should be set according to tables
11616    * here. Unfortunately, various BIOS versions don't case about
11617    * a uniform way using eg. ROM byte 0x220, but use different
11618    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11619    * Thus we don't set this if the user select a custom pdc or if
11620    * we otherwise detected a valid pdc.
11621    */
11622   if(SiS_Pr->PDC != -1) return;
11623 
11624   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11625 
11626   if(SiS_Pr->UseCustomMode)
11627      index = 0;
11628   else
11629      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11630 
11631   if(HwInfo->jChipType != SIS_300) {
11632      if(romptr) {
11633 	romptr += (temp * 2);
11634 	romptr = SISGETROMW(romptr);
11635 	romptr += index;
11636 	temp = ROMAddr[romptr];
11637      } else {
11638 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
11639     	   temp = SiS300_OEMLCDDelay2[temp][index];
11640 	} else {
11641            temp = SiS300_OEMLCDDelay3[temp][index];
11642         }
11643      }
11644   } else {
11645      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11646 	if(romptr) {
11647 	   romptr += (temp * 2);
11648 	   romptr = SISGETROMW(romptr);
11649 	   romptr += index;
11650 	   temp = ROMAddr[romptr];
11651 	} else {
11652 	   temp = SiS300_OEMLCDDelay5[temp][index];
11653 	}
11654      } else {
11655         if(SiS_Pr->SiS_UseROM) {
11656 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11657 	   if(romptr) {
11658 	      romptr += (temp * 2);
11659 	      romptr = SISGETROMW(romptr);
11660 	      romptr += index;
11661 	      temp = ROMAddr[romptr];
11662 	   } else {
11663 	      temp = SiS300_OEMLCDDelay4[temp][index];
11664 	   }
11665 	} else {
11666 	   temp = SiS300_OEMLCDDelay4[temp][index];
11667 	}
11668      }
11669   }
11670   temp &= 0x3c;
11671   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11672 }
11673 
11674 static void
SetOEMLCDData(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11675 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11676               USHORT ModeNo,USHORT ModeIdIndex)
11677 {
11678 #if 0  /* Unfinished; Data table missing */
11679   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11680   USHORT index,temp;
11681 
11682   if (SiS_Pr->SiS_UseROM) {
11683      if(!(ROMAddr[0x237] & 0x01)) return;
11684      if(!(ROMAddr[0x237] & 0x04)) return;
11685      /* No rom pointer in BIOS header! */
11686   }
11687 
11688   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
11689   if(temp = 0xFFFF) return;
11690 
11691   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11692   for(i=0x14, j=0; i<=0x17; i++, j++) {
11693       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11694   }
11695   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11696 
11697   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11698   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11699   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11700   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11701   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11702       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11703   }
11704 #endif
11705 }
11706 
11707 static USHORT
GetOEMTVPtr(SiS_Private * SiS_Pr)11708 GetOEMTVPtr(SiS_Private *SiS_Pr)
11709 {
11710   USHORT index;
11711 
11712   index = 0;
11713   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11714   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11715      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11716      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11717      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11718   } else {
11719      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11720      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11721   }
11722   return index;
11723 }
11724 
11725 static void
SetOEMTVDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11726 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11727               USHORT ModeNo,USHORT ModeIdIndex)
11728 {
11729   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11730   USHORT index,temp,romptr=0;
11731 
11732   if(SiS_Pr->SiS_UseROM) {
11733      if(!(ROMAddr[0x238] & 0x01)) return;
11734      if(!(ROMAddr[0x238] & 0x02)) return;
11735      romptr = SISGETROMW(0x241);
11736   }
11737 
11738   temp = GetOEMTVPtr(SiS_Pr);
11739 
11740   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11741 
11742   if(romptr) {
11743      romptr += (temp * 2);
11744      romptr = SISGETROMW(romptr);
11745      romptr += index;
11746      temp = ROMAddr[romptr];
11747   } else {
11748      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11749         temp = SiS300_OEMTVDelay301[temp][index];
11750      } else {
11751         temp = SiS300_OEMTVDelayLVDS[temp][index];
11752      }
11753   }
11754   temp &= 0x3c;
11755   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11756 }
11757 
11758 static void
SetOEMAntiFlicker(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11759 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11760                   USHORT ModeNo, USHORT ModeIdIndex)
11761 {
11762   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11763   USHORT index,temp,romptr=0;
11764 
11765   if(SiS_Pr->SiS_UseROM) {
11766      if(!(ROMAddr[0x238] & 0x01)) return;
11767      if(!(ROMAddr[0x238] & 0x04)) return;
11768      romptr = SISGETROMW(0x243);
11769   }
11770 
11771   temp = GetOEMTVPtr(SiS_Pr);
11772 
11773   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11774 
11775   if(romptr) {
11776      romptr += (temp * 2);
11777      romptr = SISGETROMW(romptr);
11778      romptr += index;
11779      temp = ROMAddr[romptr];
11780   } else {
11781      temp = SiS300_OEMTVFlicker[temp][index];
11782   }
11783   temp &= 0x70;
11784   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11785 }
11786 
11787 static void
SetOEMPhaseIncr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11788 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11789                 USHORT ModeNo,USHORT ModeIdIndex)
11790 {
11791   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11792   USHORT index,i,j,temp,romptr=0;
11793 
11794   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11795 
11796   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11797 
11798   if(SiS_Pr->SiS_UseROM) {
11799      if(!(ROMAddr[0x238] & 0x01)) return;
11800      if(!(ROMAddr[0x238] & 0x08)) return;
11801      romptr = SISGETROMW(0x245);
11802   }
11803 
11804   temp = GetOEMTVPtr(SiS_Pr);
11805 
11806   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11807 
11808   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11809      for(i=0x31, j=0; i<=0x34; i++, j++) {
11810         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11811      }
11812   } else {
11813      if(romptr) {
11814         romptr += (temp * 2);
11815 	romptr = SISGETROMW(romptr);
11816 	romptr += (index * 4);
11817         for(i=0x31, j=0; i<=0x34; i++, j++) {
11818 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11819 	}
11820      } else {
11821         for(i=0x31, j=0; i<=0x34; i++, j++) {
11822            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11823 	}
11824      }
11825   }
11826 }
11827 
11828 static void
SetOEMYFilter(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11829 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11830               USHORT ModeNo,USHORT ModeIdIndex)
11831 {
11832   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
11833   USHORT index,temp,i,j,romptr=0;
11834 
11835   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11836 
11837   if(SiS_Pr->SiS_UseROM) {
11838      if(!(ROMAddr[0x238] & 0x01)) return;
11839      if(!(ROMAddr[0x238] & 0x10)) return;
11840      romptr = SISGETROMW(0x247);
11841   }
11842 
11843   temp = GetOEMTVPtr(SiS_Pr);
11844 
11845   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11846   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11847   /* NTSCJ uses NTSC filters */
11848 
11849   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11850 
11851   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11852       for(i=0x35, j=0; i<=0x38; i++, j++) {
11853        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11854       }
11855       for(i=0x48; i<=0x4A; i++, j++) {
11856      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11857       }
11858   } else {
11859       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11860          romptr += (temp * 2);
11861 	 romptr = SISGETROMW(romptr);
11862 	 romptr += (index * 4);
11863 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11864        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11865          }
11866       } else {
11867          for(i=0x35, j=0; i<=0x38; i++, j++) {
11868        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11869          }
11870       }
11871   }
11872 }
11873 
11874 static USHORT
SiS_SearchVBModeID(SiS_Private * SiS_Pr,USHORT * ModeNo)11875 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
11876 {
11877    USHORT ModeIdIndex;
11878    UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
11879 
11880    if(*ModeNo <= 5) *ModeNo |= 1;
11881 
11882    for(ModeIdIndex=0; ; ModeIdIndex++) {
11883       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11884       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11885    }
11886 
11887    if(*ModeNo != 0x07) {
11888       if(*ModeNo > 0x03) return ModeIdIndex;
11889       if(VGAINFO & 0x80) return ModeIdIndex;
11890       ModeIdIndex++;
11891    }
11892 
11893    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11894 	                               /* else 350 lines */
11895    return ModeIdIndex;
11896 }
11897 
11898 void
SiS_OEM300Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefTableIndex)11899 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11900 		  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
11901 {
11902   USHORT OEMModeIdIndex=0;
11903 
11904   if(!SiS_Pr->UseCustomMode) {
11905      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11906      if(!(OEMModeIdIndex)) return;
11907   }
11908 
11909   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11910      SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11911      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11912         SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11913      }
11914   }
11915   if(SiS_Pr->UseCustomMode) return;
11916   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11917      SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
11918      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11919         SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11920     	SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11921        	SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11922      }
11923   }
11924 }
11925 #endif
11926 
11927