1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
2/*
3 * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740
4 * (Universal module for Linux kernel framebuffer, XFree86 4.x)
5 *
6 * Assembler-To-C translation
7 * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
8 *
9 * Based on BIOS
10 *     1.10.07, 1.10a for SiS650/LVDS+CH7019
11 *     1.07.1b, 1.10.6s for SiS650/301(B/LV), 650/301LVx
12 *     2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
13 *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
14 *     1.09b for 315/301(B)
15 *
16 * Permission to use, copy, modify, distribute, and sell this software and its
17 * documentation for any purpose is hereby granted without fee, provided that
18 * the above copyright notice appear in all copies and that both that
19 * copyright notice and this permission notice appear in supporting
20 * documentation, and that the name of the copyright holder not be used in
21 * advertising or publicity pertaining to distribution of the software without
22 * specific, written prior permission.  The copyright holder makes no representations
23 * about the suitability of this software for any purpose.  It is provided
24 * "as is" without express or implied warranty.
25 *
26 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
27 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
28 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
29 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
30 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
31 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
32 * PERFORMANCE OF THIS SOFTWARE.
33 *
34 */
35
36#include "init301.h"
37
38
39#define SIS650301NEW
40
41#ifdef SIS300
42#include "oem300.h"
43#endif
44
45#ifdef SIS315H
46#include "oem310.h"
47#endif
48
49#define SiS_I2CDELAY      1000
50#define SiS_I2CDELAYSHORT  333
51
52BOOLEAN
53SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
54                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
55{
56   USHORT ModeIdIndex;
57   USHORT RefreshRateTableIndex;
58
59   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
60
61   SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
62
63   /* TW: Used for shifting CR33 */
64   SiS_Pr->SiS_SelectCRT2Rate = 4;
65
66   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
67
68   RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
69
70   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
71
72   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
73      SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
74      SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
75   }
76
77   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
78      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
79      SiS_DisplayOn(SiS_Pr);
80      return(FALSE);
81   }
82
83   SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
84                   HwDeviceExtension);
85
86   /* LVDS, 650/301LV(LCDA) and 630/301B BIOS set up Panel Link */
87   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
88   	SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
89	                   HwDeviceExtension);
90   } else {
91        SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
92   }
93
94   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
95      SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
96                    HwDeviceExtension,RefreshRateTableIndex);
97   }
98
99   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
100
101        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
102
103	   SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
104	                 RefreshRateTableIndex,HwDeviceExtension);
105      	   SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
106	                 HwDeviceExtension);
107      	   SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
108	                 RefreshRateTableIndex,HwDeviceExtension);
109      	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
110	                 ModeNo,ModeIdIndex);
111
112	   /* TW: 630/301B BIOS does all this: */
113	   if(HwDeviceExtension->jChipType < SIS_315H) {
114	      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
115	         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
116		    if(!((SiS_Pr->SiS_SetFlag & CRT2IsVGA) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
117		       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
118		           SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
119		                           RefreshRateTableIndex,HwDeviceExtension);
120		       }
121                    }
122		 }
123		 SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
124		                 RefreshRateTableIndex,HwDeviceExtension);
125              }
126	   }
127
128        }
129
130   } else {
131
132        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
133	        if (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
134    	 	        SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
135		                        RefreshRateTableIndex,HwDeviceExtension);
136	        }
137	}
138        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
139     	 	SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
140		          RefreshRateTableIndex,HwDeviceExtension);
141	}
142	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
143     	  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
144	     /* TW: Inserted from 650/LVDS BIOS */
145	     if (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
146	        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
147		    SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
148		}
149	     }
150	     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
151	        /* TW: Set Chrontel registers only if CRT2 is TV */
152       		SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
153		               RefreshRateTableIndex);
154	     }
155     	  }
156	}
157
158   }
159
160#ifdef SIS300
161   if ( (HwDeviceExtension->jChipType==SIS_540)||
162        (HwDeviceExtension->jChipType==SIS_630)||
163        (HwDeviceExtension->jChipType==SIS_730)||
164        (HwDeviceExtension->jChipType==SIS_300) )
165    {
166	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
167       	   SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
168	}
169    }
170#endif
171
172#ifdef SIS315H
173   if ( (HwDeviceExtension->jChipType==SIS_315H)||
174        (HwDeviceExtension->jChipType==SIS_315PRO)||
175        (HwDeviceExtension->jChipType==SIS_550) ||
176        (HwDeviceExtension->jChipType==SIS_640) ||
177        (HwDeviceExtension->jChipType==SIS_740) ||
178        (HwDeviceExtension->jChipType==SIS_650))
179   {
180        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
181#ifdef SIS650301NEW
182	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
183#else
184	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
185#endif
186           SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
187           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
188        }
189   }
190#endif
191
192   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
193      SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
194      SiS_DisplayOn(SiS_Pr);
195   }
196
197   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
198	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
199	     /* TW: Disable LCD panel when using TV */
200	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
201	} else {
202	     /* TW: Disable TV when using LCD */
203	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
204	}
205   }
206
207   SiS_DisplayOn(SiS_Pr);
208
209   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
210      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
211   }
212
213   return 1;
214}
215
216/* TW: Checked with 650/LVDS (1.10.07) and 630+301B/LVDS BIOS */
217BOOLEAN
218SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,
219                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
220{
221    USHORT temp,temp1,temp2;
222
223    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
224         return(1);
225    temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
226    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
227    temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
228    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55);
229    temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
230    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1);
231    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp);
232    if(HwDeviceExtension->jChipType >= SIS_315H) {
233       if(temp2 == 0x55) return(0);
234       else return(1);
235    } else {
236       if(temp2 != 0x55) return(1);
237       else {
238          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
239          return(0);
240       }
241    }
242}
243
244/* TW: Set Part1 registers */
245/* TW: Checked with 650/LVDS (1.10.07), 650/301LV (II) and 630/301B (II) BIOS */
246/* TW: Pass 2: Checked with 650/301LVx 1.10.6s, 630/301B 2.04.5a */
247void
248SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
249              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
250	      USHORT RefreshRateTableIndex)
251{
252  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0, tempbl=0;
253  USHORT  pushbx=0, CRT1Index=0;
254#ifdef SIS315H
255  USHORT  pushcx=0;
256#endif
257  USHORT  modeflag, resinfo=0;
258
259  if(ModeNo<=0x13) {
260	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
261  } else {
262    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
263    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
264	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
265  }
266
267  /* TW: Removed 301B301LV.. check here; LCDA exists with LVDS as well */
268  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
269
270	   /* TW: From 650/LVDS BIOS; 301(B+LV) version does not set Sync  */
271	   if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {
272	       SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
273                               RefreshRateTableIndex,HwDeviceExtension);
274	   }
275
276	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
277     	                      HwDeviceExtension,RefreshRateTableIndex);
278
279  } else {
280
281     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
282         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
283	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
284
285        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
286                        RefreshRateTableIndex,HwDeviceExtension);
287
288     } else {
289
290        SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
291      		       RefreshRateTableIndex,HwDeviceExtension);
292
293        if (HwDeviceExtension->jChipType < SIS_315H ) {
294#ifdef SIS300
295    	      SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
296#endif
297        } else {
298#ifdef SIS315H
299              SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
300#endif
301	}
302
303        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
304                        RefreshRateTableIndex,HwDeviceExtension);
305
306	/* 1. Horizontal setup */
307
308        if (HwDeviceExtension->jChipType < SIS_315H ) {
309
310#ifdef SIS300
311                /* ------------- 300 series --------------*/
312
313    		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
314    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
315
316    		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
317    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
318
319    		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
320    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
321
322    		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
323    		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
324    		tempbx = pushbx + tempcx;
325    		tempcx <<= 1;
326    		tempcx += tempbx;
327
328    		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
329      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
330			        CRT1Index &= 0x3F;
331        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
332        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
333        			tempbx = (tempbx - 1) << 3;
334        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
335        			tempcx &= 0x1F;
336        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
337        			temp = (temp & 0x04) << (6-2);
338        			tempcx = ((tempcx | temp) - 1) << 3;
339      			}
340
341    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
342        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
343      					tempbx = 1040;
344      					tempcx = 1042;
345      				}
346    			}
347	        }
348
349    		temp = tempbx & 0x00FF;
350    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
351#endif
352
353 	} else {
354
355#ifdef SIS315H
356     	   /* ---------------------- 310 series ------------------*/
357
358	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
359		pushcx = tempcx;
360		if(modeflag & HalfDCLK)  tempcx >>= 1;
361		tempcx--;
362
363		temp = tempcx & 0xff;
364		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
365
366		temp = ((tempcx & 0xff00) >> 8) << 4;
367		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
368
369		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
370		tempbx = SiS_Pr->SiS_VGAHDE;
371		tempcx -= tempbx;
372		tempcx >>= 2;
373		if(modeflag & HalfDCLK) {
374		    tempbx >>= 1;
375		    tempcx >>= 1;
376		}
377		tempbx += 16;
378
379		temp = tempbx & 0xff;
380		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
381
382		pushbx = tempbx;
383		tempcx >>= 1;
384		tempbx += tempcx;
385		tempcx += tempbx;
386
387		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
388             	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
389                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
390                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
391                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
392                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
393               		tempcx &= 0x1F;
394                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
395                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
396                	tempcx = ((tempcx | temp) - 3) << 3;    	/* (VGAHRE-3)*8 */
397                	tempbx += 16;
398                	tempcx += 16;
399			tempax = SiS_Pr->SiS_VGAHT;
400			if (modeflag & HalfDCLK)  tempax >>= 1;
401			tempax--;
402			if (tempcx > tempax)  tempcx = tempax;
403             	   }
404         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
405             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
406      		 	 tempbx = 1040;
407      		 	 tempcx = 1042;
408      	     	      }
409         	   }
410		   /* TW: Makes no sense, but is in 650/301LVx 1.10.6s */
411         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
412		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
413             	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
414      		 	    tempbx = 1040;
415      		 	    tempcx = 1042;
416      	     	         }
417		      }
418         	   }
419                }
420
421		temp = tempbx & 0xff;
422	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
423
424#endif  /* SIS315H */
425
426     	}  /* 310 series */
427
428  	/* TW: The following is done for all bridge/chip types/series */
429
430  	tempax = tempbx & 0xFF00;
431  	tempbx = pushbx;
432  	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
433  	tempax |= (tempbx & 0xFF00);
434  	temp = (tempax & 0xFF00) >> 8;
435  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
436
437  	temp = tempcx & 0x00FF;
438  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
439
440  	/* 2. Vertical setup */
441
442  	tempcx = SiS_Pr->SiS_VGAVT - 1;
443  	temp = tempcx & 0x00FF;
444
445	/* TW: Matches 650/301LV, 650/LVDS, 630/LVDS(CLEVO), 630/LVDS(no-Ch7005) */
446        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
447	     if(HwDeviceExtension->jChipType < SIS_315H) {
448	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
449		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)) {
450		           temp--;
451		       }
452                  }
453	     } else {
454	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
455 		      temp--;
456                  }
457             }
458        } else if(HwDeviceExtension->jChipType >= SIS_315H) {
459	    /* TW: Inserted from 650/301LVx 1.10.6s */
460	    temp--;
461	}
462  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
463
464  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
465  	temp = tempbx & 0x00FF;
466  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
467
468  	temp = ((tempbx & 0xFF00) << 3) >> 8;
469  	temp |= ((tempcx & 0xFF00) >> 8);
470  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
471
472	/* TW: For 650/LVDS (1.10.07), 650/301LVx (1.10.6s) */
473	if(HwDeviceExtension->jChipType >= SIS_315H) {
474           tempbx++;
475   	   tempax = tempbx;
476	   tempcx++;
477	   tempcx -= tempax;
478	   tempcx >>= 2;
479	   tempbx += tempcx;
480	   if(tempcx < 4) tempcx = 4;
481	   tempcx >>= 2;
482	   tempcx += tempbx;
483	   tempcx++;
484	} else {
485	   /* TW: For 630/LVDS/301B: */
486  	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
487  	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
488	}
489
490  	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
491    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
492      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
493      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
494      		if(temp & 0x04) tempbx |= 0x0100;
495      		if(temp & 0x80) tempbx |= 0x0200;
496      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
497      		if(temp & 0x08) tempbx |= 0x0400;
498      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
499      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
500    	   }
501  	}
502  	temp = tempbx & 0x00FF;
503  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
504
505  	temp = ((tempbx & 0xFF00) >> 8) << 4;
506  	temp |= (tempcx & 0x000F);
507  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
508
509  	/* 3. Panel compensation delay */
510
511  	if (HwDeviceExtension->jChipType < SIS_315H ) {
512
513    	   /* ---------- 300 series -------------- */
514
515	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
516	        temp = 0x20;
517		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
518#ifdef oldHV        /* TW: Not in 630/301B BIOS */
519		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
520      		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
521      		    else temp = 0x20;
522    	        }
523#endif
524		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
525		    if(ROMAddr[0x220] & 0x80) {
526		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
527				temp = ROMAddr[0x221];
528			else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)
529				temp = ROMAddr[0x222];
530		        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
531				temp = ROMAddr[0x223];
532			else
533				temp = ROMAddr[0x224];
534			temp &= 0x3c;
535		    }
536		}
537		if(HwDeviceExtension->pdc) {
538			temp = HwDeviceExtension->pdc & 0x3c;
539		}
540	   } else {
541	        temp = 0x20;
542		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
543		if((ROMAddr) && SiS_Pr->SiS_UseROM) {
544		    if(ROMAddr[0x220] & 0x80) {
545		        temp = ROMAddr[0x220] & 0x3c;
546		    }
547		}
548		if(HwDeviceExtension->pdc) {
549			temp = HwDeviceExtension->pdc & 0x3c;
550		}
551	   }
552
553    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
554
555  	} else {
556
557      	   /* ----------- 310/325 series ---------------*/
558
559	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
560                temp = 0x10;
561                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
562    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
563    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
564		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)                     temp = 0x08;
565		tempbl = 0xF0;
566	   } else {
567	        temp = 0x00;
568		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
569		tempbl = 0xF0;
570		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
571	   }
572	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
573
574    	   tempax = 0;
575    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
576    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
577    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
578
579  	}
580
581     }  /* Slavemode */
582
583     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
584
585        /* TW: 630/301B BIOS sets up Panel Link, too! (650/LV does not) */
586        if( (HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
587	                       && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
588
589	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
590	                       HwDeviceExtension,RefreshRateTableIndex);
591
592        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
593
594    	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
595	                      HwDeviceExtension,RefreshRateTableIndex);
596        }
597
598     } else {
599
600        if(HwDeviceExtension->jChipType < SIS_315H) {
601	     SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
602	                        HwDeviceExtension,RefreshRateTableIndex);
603	} else {
604	    /* TW: For 650/LVDS */
605            if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
606    	         SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
607	                            HwDeviceExtension,RefreshRateTableIndex);
608            }
609	}
610
611     }
612   } /* LCDA */
613}
614
615/* TW: Checked against 650/301LV and 630/301B (II) BIOS */
616/* TW: Pass 2: Checked with 650/301LVx (1.10.6s) and 630/301B (2.04.5a) */
617void
618SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
619                  PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
620{
621  USHORT  push1,push2;
622  USHORT  tempax,tempbx,tempcx,temp;
623  USHORT  resinfo,modeflag;
624
625  if(ModeNo<=0x13) {
626    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
627    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
628  } else {
629    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
630    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
631  }
632
633  /* TW: The following is only done if bridge is in slave mode: */
634
635  tempax = 0xFFFF;
636  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
637
638  /* TW: 630/301B does not check this flag, assumes it is set */
639  /*     650/LV and 650/301LVx BIOS do not check this either; so we set it... */
640  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
641  	modeflag |= Charx8Dot;
642  }
643
644  if(modeflag & Charx8Dot) tempcx = 0x08;
645  else tempcx = 0x09;
646
647  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
648
649  if(modeflag & HalfDCLK) tempax >>= 1;
650
651  tempax = (tempax / tempcx) - 5;
652  tempbx = tempax & 0xFF;
653
654  temp = 0xFF;                                                  /* set MAX HT */
655  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
656
657  tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
658  if(modeflag & HalfDCLK) tempax >>= 1;
659  tempax = (tempax / tempcx) - 1;
660  tempbx |= ((tempax & 0x00FF) << 8);
661  temp = tempax & 0xFF;
662  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,temp);
663
664  temp = (tempbx & 0xFF00) >> 8;
665  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
666        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
667    	    temp += 2;
668        }
669#ifdef oldHV
670    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
671            if(resinfo == 7) temp -= 2;
672    	}
673#endif
674  }
675  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
676
677  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
678
679#ifdef oldHV
680  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
681    temp = (tempbx & 0x00FF) - 1;
682    if(!(modeflag & HalfDCLK)) {
683      temp -= 6;
684      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
685        temp -= 2;
686        if(ModeNo > 0x13) temp -= 10;
687      }
688    }
689  } else {
690#endif
691    tempcx = tempbx & 0x00FF;
692    tempbx = (tempbx & 0xFF00) >> 8;
693    tempcx = (tempcx + tempbx) >> 1;
694    temp = (tempcx & 0x00FF) + 2;
695    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
696       temp--;
697       if(!(modeflag & HalfDCLK)){
698          if((modeflag & Charx8Dot)){
699             temp += 4;
700             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
701	     /* TW: Inserted from 650/301 BIOS, 630/301B/301 don't do this */
702             if(HwDeviceExtension->jChipType >= SIS_315H) {
703	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
704             }
705          }
706       }
707    } else {
708       if(!(modeflag & HalfDCLK)) {
709         temp -= 4;
710         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
711           if(SiS_Pr->SiS_VGAHDE >= 800){
712             temp -= 7;
713	     if(HwDeviceExtension->jChipType < SIS_315H) {
714	       /* 650/301LV(x) does not do this, 630/301B does */
715               if(SiS_Pr->SiS_ModeType == ModeEGA){
716                 if(SiS_Pr->SiS_VGAVDE == 1024){
717                   temp += 15;
718                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) temp += 7;
719                 }
720               }
721	     }
722             if(SiS_Pr->SiS_VGAHDE >= 1280){
723               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
724                 if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) temp += 28;
725               }
726             }
727           }
728         }
729       }
730    }
731#ifdef oldHV
732  }
733#endif
734  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
735
736  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
737
738  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
739     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
740            if(ModeNo <= 1) {
741	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
742		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
743		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
744		} else {
745		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
746		}
747	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
748	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
749		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
750		} else {
751		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
752		}
753		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
754	    } else if(ModeNo <= 0x13) {
755	        if(modeflag & HalfDCLK) {
756		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
757		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
758			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
759		    } else {
760		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
761			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
762		    }
763		} else {
764		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
765		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
766		}
767	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
768	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
769	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
770		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
771		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
772		} else {
773		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
774		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
775		}
776	    }
777
778     }
779  }
780
781  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08    */
782
783  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
784
785  tempbx = SiS_Pr->SiS_VGAVT;
786  push1 = tempbx;
787
788  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
789
790  tempcx = 0x121;
791  tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
792  if(tempbx == 357) tempbx = 350;
793  if(tempbx == 360) tempbx = 350;
794  if(tempbx == 375) tempbx = 350;
795  if(tempbx == 405) tempbx = 400;
796  if(tempbx == 420) tempbx = 400;
797  if(tempbx == 525) tempbx = 480;
798  push2 = tempbx;
799  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
800    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
801      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
802        		if(tempbx == 350) tempbx += 5;
803        		if(tempbx == 480) tempbx += 5;
804      		}
805    	}
806  }
807  tempbx--;
808  temp = tempbx & 0x00FF;
809  tempbx--;
810  temp = tempbx & 0x00FF;
811  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
812
813  tempbx = push2;
814  tempbx--;
815  temp = tempbx & 0x00FF;
816  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
817
818  if(tempbx & 0x0100) {
819  	tempcx |= 0x0002;
820	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
821  }
822
823  tempax = 0x000B;
824  if(modeflag & DoubleScanMode) tempax |= 0x8000;
825
826  if(tempbx & 0x0200) {
827  	tempcx |= 0x0040;
828	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
829  }
830
831  if(SiS_Pr->SiS_VBType & VB_SIS301) {
832        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
833	      if(SiS_Pr->SiS_VGAVDE == 480) {
834	             tempax = (tempax & 0x00ff) | 0x2000;
835		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
836	      }
837	}
838  }
839
840  temp = (tempax & 0xFF00) >> 8;
841  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
842
843  if(tempbx & 0x0400) tempcx |= 0x0600;
844
845  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
846
847  tempax = push1;
848  tempax -= tempbx;
849  tempax >>= 2;
850  push1 = tempax;
851
852  if(HwDeviceExtension->jChipType >= SIS_315H) {
853        /* TW: Inserted from 650/301LVx 1.10.6s */
854        if(ModeNo > 0x13) {
855	    if(resinfo != 0x09) {
856	        tempax <<= 1;
857		tempbx += tempax;
858	    }
859	} else {
860	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
861	        tempax <<= 1;
862		tempbx += tempax;
863	    }
864	}
865  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
866    	tempax <<= 1;
867    	tempbx += tempax;
868  }
869#ifdef oldHV
870  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
871    	tempbx -= 10;
872  } else {
873#endif
874    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
875      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
876	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
877                    tempbx += 40;
878		    if(HwDeviceExtension->jChipType >= SIS_315H) {
879		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
880		    }
881      	       }
882	   }
883    	}
884#ifdef oldHV
885  }
886#endif
887  tempax = push1;
888  tempax >>= 2;
889  tempax++;
890  tempax += tempbx;
891  push1 = tempax;
892  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
893    	if(tempbx <= 513)  {
894      		if(tempax >= 513) tempbx = 513;
895    	}
896  }
897  temp = tempbx & 0x00FF;
898  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
899
900  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
901  	tempbx--;
902  	temp = tempbx & 0x00FF;
903  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
904
905	if(tempbx & 0x0100) tempcx |= 0x0008;
906
907  	if(tempbx & 0x0200) {
908    		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
909	}
910
911  	tempbx++;
912  }
913  if(tempbx & 0x0100) tempcx |= 0x0004;
914  if(tempbx & 0x0200) tempcx |= 0x0080;
915  if(tempbx & 0x0400) {
916        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
917  	else                               tempcx |= 0x0C00;
918  }
919
920  tempbx = push1;
921  temp = tempbx & 0x00FF;
922  temp &= 0x0F;
923  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
924
925  if(tempbx & 0x0010) tempcx |= 0x2000;
926
927  temp = tempcx & 0x00FF;
928  if(SiS_Pr->SiS_VBType & VB_SIS301) {
929	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
930	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
931	}
932  }
933  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                    		/* 0x0A CR07 */
934
935  temp = (tempcx & 0xFF00) >> 8;
936  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);                    		/* 0x17 SR0A */
937
938  tempax = modeflag;
939  temp = (tempax & 0xFF00) >> 8;
940  temp = (temp >> 1) & 0x09;
941  /* TW: Inserted from 630/301B and 650/301(LV/LVX) BIOS; not in 630/301 BIOS */
942  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
943       temp |= 0x01;
944  }
945  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);                    		/* 0x16 SR01 */
946
947  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00);                        		/* 0x0F CR14 */
948
949  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);                        		/* 0x12 CR17 */
950
951  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
952       if(HwDeviceExtension->jChipType >= SIS_315H) {
953           /* TW: Inserted from 650/301LVx 1.10.6s */
954           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
955	       temp = 0x80;
956	   }
957       } else temp = 0x80;
958  } else  temp = 0x00;
959  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                         	/* 0x1A SR0E */
960
961  return;
962}
963
964/* TW: Checked against 650/LVDS 1.10.07, 630/301B (I,II) and 630/LVDS BIOS */
965void
966SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
967		   USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
968		   USHORT RefreshRateTableIndex)
969{
970  USHORT modeflag, resinfo;
971  USHORT push1, push2, tempax, tempbx, tempcx, temp, pushcx;
972  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
973
974  if(ModeNo<=0x13) {
975    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
976    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
977  } else {
978    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
979    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
980  }
981
982#ifdef LINUX_XF86
983#ifdef TWDEBUG
984  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
985  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
986  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
987  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
988  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
989#endif
990#endif
991
992  /* TW: Set up Panel Link */
993
994  /* 1. Horizontal setup */
995
996  tempax = SiS_Pr->SiS_LCDHDES;
997
998  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
999  	tempax -= 8;
1000  }
1001
1002  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
1003
1004  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
1005
1006  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
1007    if(!SiS_Pr->SiS_IF_DEF_DSTN) {
1008 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx = 800;
1009    	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
1010	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW: not done in BIOS */
1011	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW: not done in BIOS */
1012	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280;  /* TW */
1013        else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)   tempbx = 1400;  /* TW */
1014    }
1015  }
1016  tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
1017
1018  push1 = tempax;
1019
1020  tempax += tempbx;
1021
1022  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
1023
1024  push2 = tempax;
1025
1026  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1027       if(!SiS_Pr->SiS_IF_DEF_DSTN){
1028     	  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
1029     	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
1030     	  else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
1031		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
1032	  	if(HwDeviceExtension->jChipType < SIS_315H) {
1033		     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1034		           tempcx = 0x0017;
1035#ifdef TWNEWPANEL
1036			   tempcx = 0x0018;
1037#endif
1038		     } else {
1039		           tempcx = 0x0017;  /* A901; other 301B BIOS 0x0018; */
1040		     }
1041		} else {
1042		     tempcx = 0x0018;
1043		}
1044	  }
1045	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
1046     	  else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)   tempcx = 0x0030;
1047       }
1048  }
1049
1050  tempcx += tempax;                              /* lcdhrs  */
1051  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
1052
1053  tempax = tempcx >> 3;                          /* BPLHRS */
1054  temp = tempax & 0x00FF;
1055  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
1056
1057  temp = (tempax & 0x00FF) + 10;
1058
1059  /* TW: Inserted this entire "if"-section from 650/LVDS BIOS */
1060  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1061      if(!SiS_Pr->SiS_IF_DEF_DSTN){
1062        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
1063	  temp += 6;
1064          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
1065	    temp++;
1066	    if(HwDeviceExtension->jChipType >= SIS_315H) {
1067	       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
1068	          temp -= 3;
1069	       }
1070	    }
1071	  }
1072        }
1073      }
1074  }
1075
1076  temp &= 0x1F;
1077  temp |= ((tempcx & 0x0007) << 5);
1078  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
1079  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
1080
1081  tempbx = push2;
1082  tempcx = push1;                                /* lcdhdes  */
1083
1084  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
1085  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
1086
1087  tempcx >>= 3;                                  /* BPLHDES */
1088  temp = (tempcx & 0x00FF);
1089  if(ModeNo == 0x5b) temp--;                     /* fix fstn mode=5b */
1090  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
1091
1092  if(HwDeviceExtension->jChipType < SIS_315H) {  /* TW: Not done in LVDS BIOS 1.10.07 */
1093     if(tempbx & 0x07) tempbx += 8;              /* TW: Done in 630/301B and 630/LVDS BIOSes */
1094  }
1095  tempbx >>= 3;                                  /* BPLHDEE  */
1096  temp = tempbx & 0x00FF;
1097  if(ModeNo == 0x5b) temp--;			 /* fix fstn mode=5b */
1098  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
1099
1100  /* 2. Vertical setup */
1101
1102  if(HwDeviceExtension->jChipType < SIS_315H) {
1103
1104      /* TW: This entire section from 630/301B and 630/LVDS/LVDS+CH BIOS */
1105      tempcx = SiS_Pr->SiS_VGAVT;
1106      tempbx = SiS_Pr->SiS_VGAVDE;
1107      if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
1108         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
1109	    tempbx = 600;
1110	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
1111	       tempbx = 768;
1112	       if( (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) &&
1113	           (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1152x768) ) {
1114	 	    tempbx = 600;
1115	       }
1116	    }
1117         }
1118      }
1119      tempcx -= tempbx;
1120
1121  } else {
1122
1123      tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
1124
1125  }
1126
1127  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
1128  push1 = tempbx;
1129
1130  tempax = SiS_Pr->SiS_VGAVDE;
1131
1132  if((SiS_Pr->SiS_IF_DEF_TRUMPION == 0) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))
1133                                && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
1134    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1135	    if(!SiS_Pr->SiS_IF_DEF_DSTN){
1136      		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax = 600;
1137      		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax = 768;
1138		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax = 600;   /* TW */
1139      		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax = 768;   /* TW */
1140		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024;  /* TW */
1141		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050;  /* TW */
1142		else                                                          tempax = 600;
1143            }
1144    	}
1145  }
1146
1147  tempbx += tempax;
1148  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
1149
1150  push2 = tempbx;
1151
1152  tempcx >>= 1;
1153
1154  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)){
1155     if(!SiS_Pr->SiS_IF_DEF_DSTN){
1156     	if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
1157	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) ) {   /* TW: @@@ TEST - not in BIOS! */
1158	     	tempcx = 0x0001;
1159     	} else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
1160	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
1161		if(HwDeviceExtension->jChipType < SIS_315H) {
1162		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1163			    tempcx = 0x0002;
1164#ifdef TWNEWPANEL
1165			    tempcx = 0x0003;
1166#endif
1167		      } else {
1168		            tempcx = 0x0002;   /* TW: A901; other 301B BIOS sets 0x0003; */
1169		      }
1170		} else tempcx = 0x0003;
1171        }
1172     	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
1173     	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
1174     	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
1175     	else 				                              tempcx = 0x0057;
1176     }
1177  }
1178
1179  tempbx += tempcx;			 	/* BPLVRS  */
1180
1181  if(HwDeviceExtension->jChipType < SIS_315H) {
1182      tempbx++;
1183  }
1184
1185  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
1186  temp = tempbx & 0x00FF;
1187  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
1188
1189  tempcx >>= 3;
1190
1191  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1192     if( (HwDeviceExtension->jChipType < SIS_315H) &&
1193         (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
1194     else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
1195     else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
1196     else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
1197     else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
1198     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
1199     		if(HwDeviceExtension->jChipType < SIS_315H) {
1200		        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1201				tempcx = 0x0004;
1202#ifdef TWNEWPANEL
1203				tempcx = 0x0005;
1204#endif
1205		        } else {
1206				tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
1207			}
1208		} else {
1209			tempcx = 0x0005;
1210		}
1211     }
1212  }
1213
1214  tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
1215  temp = tempcx & 0x000F;
1216  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
1217
1218  temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
1219  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
1220  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
1221  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)   {
1222      if(HwDeviceExtension->jChipType >= SIS_315H) {
1223         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {	/* TW: Inserted from 650/LVDS 1.10.07 */
1224            temp |= 0x80;
1225         }
1226      } else {
1227	 if( (HwDeviceExtension->jChipType == SIS_630) ||
1228	     (HwDeviceExtension->jChipType == SIS_730) ) {
1229	    if(HwDeviceExtension->jChipRevision >= 0x30) {
1230	       temp |= 0x80;
1231	    }
1232	 }
1233      }
1234  }         /* TW: in follwing line, 0x87 was 0x07 (modified according to 650/LVDS BIOS) */
1235  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
1236
1237  if (HwDeviceExtension->jChipType < SIS_315H) {
1238
1239        /* 300 series */
1240
1241        tempeax = SiS_Pr->SiS_VGAVDE << 6;
1242        temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
1243        tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
1244        if(temp != 0) tempeax++;
1245        tempebx = tempeax;                         /* BPLVCFACT  */
1246
1247  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
1248	     tempebx = 0x003F;
1249	}
1250
1251  	temp = (USHORT)(tempebx & 0x00FF);
1252  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
1253
1254  } else {
1255
1256        /* 310/325 series */
1257
1258	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
1259
1260	tempeax = SiS_Pr->SiS_VGAVDE << 18;
1261    	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
1262    	tempeax = tempeax / SiS_Pr->SiS_VDE;
1263    	if(temp != 0) tempeax++;
1264    	tempebx = tempeax;                         /* BPLVCFACT  */
1265        tempvcfact = tempeax;
1266    	temp = (USHORT)(tempebx & 0x00FF);
1267    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
1268    	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
1269    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
1270    	temp = (USHORT)((tempebx & 0x00030000) >> 16);
1271    	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
1272    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
1273
1274  }
1275
1276  tempbx = push2;                                  /* p bx temppush1 BPLVDEE  */
1277  tempcx = push1;
1278
1279  push1 = temp;					   /* TW: For 630/301B and 630/LVDS */
1280
1281  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1282   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
1283		if(HwDeviceExtension->jChipType < SIS_315H) {
1284			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
1285      				if(resinfo == 15) tempcx++;
1286				if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
1287					if(resinfo == 7) tempcx++;
1288		    		}
1289			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
1290      				if(resinfo == 7) tempcx++;
1291				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
1292			} else  if(resinfo == 8) tempcx++;
1293		} else {
1294			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
1295      				if(resinfo == 7) tempcx++;
1296			}
1297		}
1298	}
1299  }
1300
1301  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
1302     tempcx = SiS_Pr->SiS_VGAVDE;
1303     tempbx = SiS_Pr->SiS_VGAVDE - 1;
1304  }
1305
1306  temp = ((tempbx & 0x0700) >> 8) << 3;
1307  temp |= ((tempcx & 0x0700) >> 8);
1308  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
1309
1310  temp = tempbx & 0x00FF;
1311  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
1312  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
1313
1314  temp = tempcx & 0x00FF;
1315  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
1316
1317  /* 3. Additional horizontal setup (scaling, etc) */
1318
1319  tempecx = SiS_Pr->SiS_VGAHDE;
1320  if(HwDeviceExtension->jChipType >= SIS_315H) {
1321     if(modeflag & HalfDCLK)
1322        tempecx >>= 1;
1323  }
1324  tempebx = SiS_Pr->SiS_HDE;
1325  if(tempecx == tempebx) tempeax = 0xFFFF;
1326  else {
1327     tempeax = tempecx;
1328     tempeax <<= 16;
1329     temp = (USHORT)(tempeax % tempebx);
1330     tempeax = tempeax / tempebx;
1331     if(HwDeviceExtension->jChipType >= SIS_315H) {
1332         if(temp) tempeax++;
1333     }
1334  }
1335  tempecx = tempeax;
1336
1337  if (HwDeviceExtension->jChipType >= SIS_315H) {
1338      tempeax = SiS_Pr->SiS_VGAHDE;
1339      if(modeflag & HalfDCLK)
1340          tempeax >>= 1;
1341      tempeax <<= 16;
1342      tempeax = (tempeax / tempecx) - 1;
1343  } else {
1344      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
1345  }
1346  tempecx <<= 16;
1347  tempecx |= (tempeax & 0xFFFF);
1348  temp = (USHORT)(tempecx & 0x00FF);
1349  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
1350
1351  tempbx = SiS_Pr->SiS_VDE;
1352  if (HwDeviceExtension->jChipType >= SIS_315H) {
1353      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
1354      tempbx = (USHORT)(tempeax & 0x0FFFF);
1355  } else {
1356      tempax = SiS_Pr->SiS_VGAVDE << 6;
1357      tempbx = push1;
1358      tempbx &= 0x3f;
1359      if(tempbx == 0) tempbx = 64;
1360      tempax = tempax / tempbx;
1361      tempbx = tempax;
1362  }
1363  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
1364  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
1365
1366  temp = ((tempbx & 0xFF00) >> 8) << 3;
1367  temp |= (USHORT)((tempecx & 0x0700) >> 8);
1368  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
1369
1370  temp = tempbx & 0x00FF;
1371  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
1372
1373  tempecx >>= 16;                               /* BPLHCFACT  */
1374  if(HwDeviceExtension->jChipType < SIS_315H) {
1375      if(modeflag & HalfDCLK) tempecx >>= 1;
1376  }
1377  temp = (USHORT)((tempecx & 0xFF00) >> 8);
1378  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
1379
1380  temp = (USHORT)(tempecx & 0x00FF);
1381  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
1382
1383  /* 630/301B and 630/LVDS do something for 640x480 panels here */
1384
1385  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
1386  if(SiS_Pr->SiS_IF_DEF_DSTN){
1387     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
1388     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
1389     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
1390     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
1391     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
1392     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
1393     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
1394     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
1395     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
1396     	temp = tempbx & 0x00FF;
1397     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
1398     	temp=((tempbx & 0xFF00) >> 8) << 3;
1399     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
1400     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
1401     	temp = tempbx & 0x00FF;
1402     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
1403     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
1404     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
1405     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
1406     	tempbx = SiS_Pr->SiS_VDE / 2;
1407     	temp = tempbx & 0x00FF;
1408     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
1409     	temp = ((tempbx & 0xFF00) >> 8) << 3;
1410     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
1411     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
1412     	tempebx = 128;
1413     	temp = (USHORT)(tempeax % tempebx);
1414     	tempeax = tempeax / tempebx;
1415     	if(temp != 0)  tempeax++;
1416     	temp = (USHORT)(tempeax & 0x003F);
1417     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
1418     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
1419     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
1420     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
1421     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
1422     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
1423     	pushcx = tempax;
1424     	temp = tempax & 0x00FF;
1425     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
1426     	temp = ((tempax & 0xFF00) >> 8) << 3;
1427     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
1428     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
1429     	tempeax = (tempax * pushcx);
1430     	tempebx = 0x00100000 + tempeax;
1431     	temp = (USHORT)tempebx & 0x000000FF;
1432     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
1433     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
1434     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
1435     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
1436     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
1437     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
1438     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
1439     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
1440     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
1441     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
1442     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
1443     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
1444     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
1445     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
1446     	if(SiS_Pr->SiS_IF_DEF_FSTN){
1447         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
1448         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
1449         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
1450         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
1451         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
1452         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
1453         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
1454         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
1455         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
1456     	}
1457     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
1458     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
1459     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
1460  }
1461
1462  return;
1463
1464}
1465
1466#ifdef SIS315H
1467void
1468SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr)
1469{
1470  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
1471}
1472#endif
1473
1474
1475/* TW: For LVDS / 302b/lv - LCDA (this must only be called on 310/325 series!) */
1476/* TW: Double-checked against 650/LVDS and 650/301 BIOS */
1477void
1478SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
1479                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
1480{
1481  USHORT modeflag,resinfo;
1482  USHORT push1,push2,tempax,tempbx,tempcx,temp;
1483  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
1484
1485  if(SiS_Pr->SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS BIOS */
1486      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* TW: From 650/LVDS BIOS */
1487
1488  if(SiS_Pr->SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS 1.10.07 */
1489     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);			/* TW: From 650/LVDS 1.10.07 */
1490  else
1491     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);			/* TW: From 650/301Lvx 1.10.6s */
1492
1493  if(ModeNo<=0x13) {
1494    modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1495    resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
1496  } else {
1497    modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1498    resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1499  }
1500
1501  tempax = SiS_Pr->SiS_LCDHDES;
1502  tempbx = SiS_Pr->SiS_HDE;
1503  tempcx = SiS_Pr->SiS_HT;
1504
1505  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
1506        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
1507	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
1508	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
1509	else 							      tempbx = 1280;
1510
1511  }
1512  tempcx -= tempbx;                        	            	/* HT-HDE  */
1513  push1 = tempax;
1514  tempax += tempbx;	                                    	/* lcdhdee  */
1515  tempbx = SiS_Pr->SiS_HT;
1516  if(tempax >= tempbx)	tempax -= tempbx;
1517
1518  push2 = tempax;						/* push ax   lcdhdee  */
1519
1520  tempcx >>= 2;
1521
1522  /* TW: Inserted from 650/301LVx 1.10.6s */
1523  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1524      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
1525          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
1526	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
1527	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
1528	  else                                                          tempcx = 0x30;
1529      }
1530  }
1531
1532  tempcx += tempax;  	                                  	/* lcdhrs  */
1533  if(tempcx >= tempbx) tempcx -= tempbx;
1534                                                           	/* v ah,cl  */
1535  tempax = tempcx;
1536  tempax >>= 3;   	                                     	/* BPLHRS */
1537  temp = tempax & 0x00FF;
1538  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);                 	/* Part1_14h  */
1539
1540  temp += 10;
1541  temp &= 0x1F;
1542  temp |= ((tempcx & 0x07) << 5);
1543  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
1544
1545  tempbx = push2;                                          	/* lcdhdee  */
1546  tempcx = push1;                                          	/* lcdhdes  */
1547  temp = (tempcx & 0x00FF);
1548  temp &= 0x07;                                  		/* BPLHDESKEW  */
1549  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
1550
1551  tempcx >>= 3;   	                                     	/* BPLHDES */
1552  temp = tempcx & 0x00FF;
1553  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
1554
1555  if(tempbx & 0x07) tempbx += 8;
1556  tempbx >>= 3;                                        		/* BPLHDEE  */
1557  temp = tempbx & 0x00FF;
1558  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
1559
1560  tempcx = SiS_Pr->SiS_VGAVT;
1561  tempbx = SiS_Pr->SiS_VGAVDE;
1562  tempcx -= tempbx; 	                                   	/* GAVT-VGAVDE  */
1563  tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
1564  push1 = tempbx;                                      		/* push bx temppush1 */
1565  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0){
1566    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
1567    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
1568    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
1569    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
1570    else                                                           tempax = 960;
1571  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
1572
1573  tempbx += tempax;
1574  tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
1575  if(tempbx >= tempax)  tempbx -= tempax;
1576
1577  push2 = tempbx;                                      		/* push bx  temppush2  */
1578  tempcx >>= 2;	/* TO CHECK - was 1 */
1579
1580  /* TW: Inserted from 650/301LVx 1.10.6s */
1581  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1582      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
1583          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
1584	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
1585	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
1586	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
1587	  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
1588	  else                                                           tempcx = 0x0057;
1589      }
1590  }
1591
1592  tempbx += tempcx;
1593  tempbx++;                                                	/* BPLVRS  */
1594  if(tempbx >= tempax)   tempbx -= tempax;
1595  temp = tempbx & 0x00FF;
1596  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);                         /* Part1_18h  */
1597
1598  tempcx >>= 3;
1599  tempcx += tempbx;
1600  tempcx++;                                                	/* BPLVRE  */
1601  temp = tempcx & 0x00FF;
1602  temp &= 0x0F;
1603  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1604     /* TW: Inserted from 650/LVDS BIOS */
1605     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp);
1606  } else {
1607     /* TW: Inserted from 650/301LVx 1.10.6s */
1608     temp |= 0xC0;
1609     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
1610  }
1611
1612  temp = (tempbx & 0xFF00) >> 8;
1613  temp &= 0x07;
1614  temp <<= 3;  		                               		/* BPLDESKEW =0 */
1615  tempbx = SiS_Pr->SiS_VGAVDE;
1616  if(tempbx != SiS_Pr->SiS_VDE)              temp |= 0x40;
1617  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
1618  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1619      /* TW: Inserted from 650/LVDS 1.10.07 */
1620      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;
1621      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
1622  } else {
1623      /* TW: Inserted from 650/301LVx 1.10.6s */
1624      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
1625          if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
1626      }
1627      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
1628  }
1629
1630  tempbx = push2;                                      		/* p bx temppush2 BPLVDEE  */
1631  tempcx = push1;                                      		/* pop cx temppush1 NPLVDES */
1632  push1 = (USHORT)(tempeax & 0xFFFF);
1633
1634  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1635    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
1636      if(resinfo == 7) tempcx++;
1637    }
1638    /* TW: Inserted from 650/301LVx+LVDS BIOSes */
1639    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
1640        tempbx = SiS_Pr->SiS_VGAVDE;
1641	tempcx = tempbx;
1642        tempbx--;
1643    }
1644  }
1645
1646  temp = (tempbx & 0xFF00) >> 8;
1647  temp &= 0x07;
1648  temp <<= 3;
1649  temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
1650  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
1651
1652  temp = tempbx & 0x00FF;
1653  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
1654
1655  temp = tempcx & 0x00FF;
1656  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
1657
1658  tempecx = SiS_Pr->SiS_VGAVT;
1659  tempebx = SiS_Pr->SiS_VDE;
1660  tempeax = SiS_Pr->SiS_VGAVDE;
1661  tempecx -= tempeax;    	                             	/* VGAVT-VGAVDE  */
1662  tempeax <<= 18;
1663  temp = (USHORT)(tempeax % tempebx);
1664  tempeax = tempeax / tempebx;
1665  if(temp != 0)  tempeax++;
1666  tempebx = tempeax;                                        	/* BPLVCFACT  */
1667  tempvcfact = tempeax;
1668  temp = (USHORT)(tempebx & 0x00FF);
1669  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);
1670
1671  temp = (USHORT)((tempebx & 0x00FF00) >> 8);
1672  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);
1673
1674  temp = (USHORT)((tempebx & 0x00030000) >> 16);
1675  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
1676  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);
1677
1678  tempecx = SiS_Pr->SiS_VGAHDE;
1679  tempebx = SiS_Pr->SiS_HDE;
1680  tempeax = tempecx;
1681  tempeax <<= 16;
1682  temp = tempeax % tempebx;
1683  tempeax = tempeax / tempebx;
1684  if(temp) tempeax++;
1685  if(tempebx == tempecx)  tempeax = 0xFFFF;
1686  tempecx = tempeax;
1687  tempeax = SiS_Pr->SiS_VGAHDE;
1688  tempeax <<= 16;
1689  tempeax = tempeax / tempecx;
1690  tempecx <<= 16;
1691  tempeax--;
1692  tempecx = tempecx | (tempeax & 0xFFFF);
1693  temp = (USHORT)(tempecx & 0x00FF);
1694  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
1695
1696  tempeax = SiS_Pr->SiS_VGAVDE;
1697  tempeax <<= 18;
1698  tempeax = tempeax / tempvcfact;
1699  tempbx = (USHORT)(tempeax & 0x0FFFF);
1700
1701  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
1702
1703  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
1704
1705  temp = ((tempbx & 0xFF00) >> 8) << 3;
1706  temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
1707  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
1708
1709  temp = tempbx & 0x00FF;
1710  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
1711
1712  tempecx >>= 16;   	                                  	/* BPLHCFACT  */
1713  if(modeflag & HalfDCLK) tempecx >>= 1;
1714  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
1715  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
1716
1717  temp=(USHORT)(tempecx & 0x000000FF);
1718  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
1719
1720
1721  /* TW: Only for 650/LVDS and 30xLV/30xLVX */
1722  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & (VB_SIS30xLV|VB_SIS30xNEW))){
1723  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
1724  }
1725
1726  return;
1727}
1728
1729/* TW: Double-checked against 650/LVDS (1.10.07) and 650/301 BIOS */
1730void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
1731                       USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
1732		       PSIS_HW_DEVICE_INFO HwDeviceExtension)
1733{
1734  USHORT offset;
1735  UCHAR temp;
1736
1737  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
1738
1739  offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
1740                         HwDeviceExtension);
1741  temp = (UCHAR)(offset & 0xFF);
1742  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
1743  temp = (UCHAR)((offset & 0xFF00) >> 8);
1744  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,temp);
1745  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
1746  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
1747}
1748
1749/* TW: Checked with 650/LVDS and 650/301 BIOS */
1750USHORT
1751SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
1752              USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
1753{
1754  USHORT temp,colordepth;
1755  USHORT modeinfo,index,infoflag;
1756
1757  modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
1758  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1759  if (HwDeviceExtension->jChipType < SIS_315H ) {
1760    	index = (modeinfo >> 4) & 0xFF;
1761  } else {
1762    	index = (modeinfo >> 8) & 0xFF;
1763  }
1764
1765        temp = SiS_Pr->SiS_ScreenOffset[index];
1766        colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
1767
1768  if(infoflag & InterlaceMode) temp <<= 1;
1769
1770  temp *= colordepth;
1771
1772  /* TW: For 1400x1050 */
1773  if((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
1774        colordepth >>= 1;
1775	temp += colordepth;
1776  }
1777
1778  return(temp);
1779}
1780
1781/* TW: Checked with 650/LVDS BIOS */
1782USHORT
1783SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
1784{
1785  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
1786  SHORT  index;
1787  USHORT modeflag;
1788
1789  if(ModeNo <= 0x13)
1790    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1791  else
1792    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1793
1794  index = (modeflag & ModeInfoFlag) - ModeEGA;
1795  if(index < 0) index = 0;
1796  return(ColorDepth[index]);
1797}
1798
1799/* TW: Checked against 630/301/301B/LVDS, 650/301LVx/LVDS */
1800void
1801SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
1802                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
1803{
1804  USHORT tempah=0,tempbl,infoflag,flag;
1805
1806  flag = 0;
1807  tempbl = 0xC0;
1808
1809  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1810
1811  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
1812
1813    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1814      tempah = SiS_Pr->SiS_LCDInfo;
1815      if(HwDeviceExtension->jChipType >= SIS_315H) {
1816          tempbl = tempah & 0xc0;
1817      }
1818      if(SiS_Pr->SiS_LCDInfo & LCDSync) {
1819          flag = 1;
1820      }
1821    }
1822    if(flag != 1) tempah = infoflag >> 8;
1823    tempah &= 0xC0;
1824    tempah |= 0x20;
1825    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
1826
1827    if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
1828		/* TW: BIOS does something here @@@ */
1829    }
1830
1831    tempah &= 0x3f;
1832    tempah |= tempbl;
1833    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
1834
1835  } else {
1836
1837     if(HwDeviceExtension->jChipType < SIS_315H) {
1838
1839        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B */
1840
1841            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1842               tempah = SiS_Pr->SiS_LCDInfo;
1843	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
1844                  flag = 1;
1845               }
1846            }
1847            if(flag != 1) tempah = infoflag >> 8;
1848            tempah &= 0xC0;
1849            tempah |= 0x20;
1850
1851            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
1852
1853            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
1854	       	/* TW: BIOS does something here @@@ */
1855            }
1856
1857 	    tempah &= 0x3f;
1858  	    tempah |= tempbl;
1859            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
1860
1861         } else {							/* 630 - 301 */
1862
1863            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1864               tempah = SiS_Pr->SiS_LCDInfo;
1865	       if(SiS_Pr->SiS_LCDInfo & LCDNonExpandingShift) { /* ! */
1866	          flag = 1;
1867	       }
1868            }
1869            if(flag != 1) tempah = infoflag >> 8;
1870            tempah &= 0xC0;
1871            tempah |= 0x30;
1872            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
1873
1874         }
1875
1876      } else {
1877
1878         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 310/325 - 301B et al */
1879
1880            tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
1881            tempah &= 0xC0;
1882            tempah |= 0x20;
1883            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
1884            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
1885
1886         } else {							/* 310/325 - 301 */
1887
1888            tempah = infoflag >> 8;
1889            tempah &= 0xC0;
1890            tempah |= 0x20;
1891
1892            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
1893
1894            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
1895		/* TW: BIOS does something here @@@ */
1896            }
1897
1898            tempah &= 0x3f;
1899            tempah |= tempbl;
1900            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
1901
1902         }
1903      }
1904   }
1905}
1906
1907/* TW: Set FIFO on 630/730 - not to be called on SiS300 */
1908/* TW: Checked against 630/301B BIOS; does not set PCI registers */
1909void
1910SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
1911                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
1912{
1913  USHORT temp,index;
1914  USHORT modeidindex,refreshratetableindex;
1915  USHORT VCLK,MCLK,colorth=0,data2;
1916  ULONG  data,eax;
1917  UCHAR  LatencyFactor[] = {
1918  	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
1919        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
1920        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
1921        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
1922        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
1923        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
1924        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
1925        00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
1926
1927  SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&modeidindex);
1928  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
1929  SiS_Pr->SiS_SelectCRT2Rate = 0;
1930  refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,modeidindex,HwDeviceExtension);
1931
1932  if(ModeNo >= 0x13) {
1933    index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
1934    index &= 0x3F;
1935    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
1936    index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
1937    index &= 0x07;
1938    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
1939    data2 = SiS_Pr->SiS_ModeType - 0x02;
1940    switch (data2) {
1941      case 0 : 	colorth = 1; break;
1942      case 1 : 	colorth = 1; break;
1943      case 2 : 	colorth = 2; break;
1944      case 3 : 	colorth = 2; break;
1945      case 4 : 	colorth = 3; break;
1946      case 5 : 	colorth = 4; break;
1947    }
1948    data2 = (colorth * VCLK) / MCLK;
1949
1950    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1951    temp = ((temp&0x00FF)>>6)<<1;
1952    if(temp == 0) temp=1;
1953    temp <<= 2;
1954
1955    data2 = temp - data2;
1956
1957    if((28*16) % data2) {
1958      	data2 = (28 * 16) / data2;
1959      	data2++;
1960    } else {
1961      	data2 = (28 * 16) / data2;
1962    }
1963
1964    index = 0;
1965    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1966    if(temp & 0x0080) index += 12;
1967
1968#ifndef LINUX_XF86
1969    SiS_SetReg4(0xcf8,0x800000A0);
1970    eax=SiS_GetReg3(0xcfc);
1971#else
1972  /* TW: We use pci functions X offers. We use tag 0, because
1973   * we want to read/write to the host bridge (which is always
1974   * 00:00.0 on 630, 730 and 540), not the VGA device.
1975   */
1976    eax = pciReadLong(0x00000000, 0xA0);
1977#endif
1978    temp=(USHORT)(eax>>24);
1979    if(!(temp&0x01)) index += 24;
1980
1981#ifndef LINUX_XF86
1982    SiS_SetReg4(0xcf8,0x80000050);
1983    eax=SiS_GetReg3(0xcfc);
1984#else
1985    eax = pciReadLong(0x00000000, 0x50);
1986#endif
1987    temp=(USHORT)(eax >> 24);
1988    if(temp & 0x01) index += 6;
1989
1990    temp = (temp & 0x0F) >> 1;
1991    index += temp;
1992    data = LatencyFactor[index];
1993    data += 15;
1994    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1995    if(!(temp & 0x80)) data += 5;
1996
1997    data += data2;
1998
1999    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2000
2001    data = data * VCLK * colorth;
2002    if(data % (MCLK << 4)) {
2003      	data = data / (MCLK << 4);
2004      	data++;
2005    } else {
2006      	data = data / (MCLK << 4);
2007    }
2008
2009    /* TW: Inserted this entire section */
2010    temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x01);
2011    if( ( (HwDeviceExtension->jChipType == SIS_630) ||
2012         (HwDeviceExtension->jChipType == SIS_730) ) &&
2013       (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
2014    {
2015	temp = (temp & (~0x1F)) | 0x1b;
2016    } else {
2017	temp = (temp & (~0x1F)) | 0x16;
2018    }
2019    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
2020
2021    if(data <= 6) data = 6;
2022    if(data > 0x14) data = 0x14;
2023    if( (HwDeviceExtension->jChipType == SIS_630) &&
2024        (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
2025    {
2026   	if(data > 0x13) data = 0x13;
2027    }
2028    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x01F,data);
2029   /* TW end */
2030  }
2031}
2032
2033/* TW: Set FIFO on 310 series */
2034#ifdef SIS315H
2035void
2036SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
2037                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
2038{
2039
2040  UCHAR CombCode[]  = { 1, 1, 1, 4, 3, 1, 3, 4,
2041                        4, 1, 4, 4, 5, 1, 5, 4};
2042  UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
2043                        55, 87, 84,116,103,135,119,151};
2044  USHORT temp3,tempax,tempbx,tempcx;
2045  USHORT tempcl, tempch;
2046  USHORT index;
2047  USHORT CRT1ModeNo,CRT2ModeNo;
2048  USHORT ModeIdIndex;
2049  USHORT RefreshRateTableIndex;
2050  USHORT SelectRate_backup;
2051
2052  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
2053
2054  CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                             /* get CRT1 ModeNo */
2055  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex);
2056
2057  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
2058  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
2059  SiS_Pr->SiS_SelectCRT2Rate = 0;
2060
2061  /* Set REFIndex for crt1 refreshrate */
2062  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
2063                                             ModeIdIndex,HwDeviceExtension);
2064
2065  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
2066                          RefreshRateTableIndex,HwDeviceExtension);
2067  tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                         /* Get DCLK (VCLK?) */
2068
2069  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
2070  tempbx >>= 1;
2071  if(!tempbx) tempbx++;
2072
2073  tempax *= tempbx;
2074
2075  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);     /* Get MCLK */
2076
2077  tempax /= tempbx;
2078
2079  tempbx = tempax;
2080
2081  tempax = 16;
2082
2083  tempax -= tempbx;
2084
2085  tempbx = tempax;    /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */
2086
2087  tempax = ((52 * 16) / tempbx);
2088
2089  if ((52*16 % tempbx) != 0) {
2090    	tempax++;
2091  }
2092  tempcx = tempax;
2093  tempcx += 40;
2094
2095  /* get DRAM latency */
2096  tempcl = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 3) & 0x7;     /* SR17[5:3] DRAM Queue depth */
2097  tempch = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 6) & 0x3;     /* SR17[7:6] DRAM Grant length */
2098
2099  for (temp3 = 0; temp3 < 16; temp3 += 2) {
2100    if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
2101      temp3 = CRT2ThLow[temp3 >> 1];
2102    }
2103  }
2104
2105  tempcx +=  temp3;                                      /* CRT1 Request Period */
2106
2107  CRT2ModeNo = ModeNo;                                   /* get CRT2 ModeNo */
2108  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);    /* Get ModeID Table */
2109
2110  SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2111  SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
2112
2113  RefreshRateTableIndex=SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
2114                                           ModeIdIndex,HwDeviceExtension);
2115
2116  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
2117                          RefreshRateTableIndex,HwDeviceExtension);
2118  tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                          /* Get VCLK  */
2119
2120  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);  /* Get colordepth */
2121  tempbx >>= 1;
2122  if(!tempbx) tempbx++;
2123
2124  tempax *= tempbx;
2125
2126  tempax *= tempcx;
2127
2128  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);	       /* Get MCLK */
2129  tempbx <<= 4;
2130
2131  tempcx = tempax;
2132  tempax /= tempbx;
2133  if(tempcx % tempbx) tempax++;		/* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */
2134
2135  if (tempax > 0x37)  tempax = 0x37;
2136
2137  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV overrule calculated value; 315 does not */
2138  if(HwDeviceExtension->jChipType == SIS_650) {
2139  	tempax = 0x04;
2140  }
2141
2142  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
2143}
2144
2145USHORT
2146SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
2147{
2148  USHORT index;
2149
2150  index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
2151  if(index >= 4) {
2152    index -= 4;
2153    return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
2154  } else {
2155    return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
2156  }
2157}
2158#endif
2159
2160/* TW: Checked against 650/LVDS 1.10.07 BIOS */
2161void
2162SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2163                   USHORT RefreshRateTableIndex,
2164		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
2165{
2166  USHORT modeflag;
2167  USHORT PanelIndex,ResIndex;
2168  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
2169
2170  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
2171
2172     SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2173                        &PanelIndex,&ResIndex);
2174     switch (PanelIndex)
2175     {
2176     	case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
2177     	case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
2178	case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
2179	case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
2180     	case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
2181     	case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
2182	case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
2183	case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
2184     }
2185
2186  } else {
2187
2188     SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2189                       &PanelIndex,&ResIndex,HwDeviceExtension);
2190
2191     switch (PanelIndex)
2192     {
2193     	case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break; /* --- expanding --- | Gericom 1st supersonic (310) */
2194     	case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
2195     	case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
2196     	case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
2197     	case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
2198     	case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
2199     	case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
2200     	case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
2201     	case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
2202     	case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
2203     	case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
2204     	case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
2205     	case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;	/* TW: Clevo 2202 (300)  */
2206     	case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
2207     	case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;	/* TW: Uniwill N271S2 (300) */
2208     	case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
2209     	case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;  /* --- non-expanding --- */
2210     	case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
2211     	case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
2212     	case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
2213     	case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
2214     	case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
2215     	case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
2216     	case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
2217     	case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
2218     	case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
2219     	case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
2220     	case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
2221     	case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;     /* TW: Gericom 2200C (300) */
2222     	case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
2223     	case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
2224     	case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
2225     	case 32: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break;
2226     	case 33: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
2227     	case 34: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
2228     	case 35: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
2229     }
2230  }
2231  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
2232  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
2233
2234  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding){
2235    if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2236      if(ModeNo <= 0x13) {
2237        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2238	if(!(modeflag & HalfDCLK)) {
2239	  SiS_Pr->SiS_LCDHDES = 632;
2240	}
2241      }
2242    } else {
2243      if(!(SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
2244        if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {  /* TW: New from 650/LVDS 1.10.07 */
2245          if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
2246            if(ModeNo <= 0x13) {
2247	      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2248	      if(HwDeviceExtension->jChipType < SIS_315H) {
2249	         if(!(modeflag & HalfDCLK)) {
2250                     SiS_Pr->SiS_LCDHDES = 320;
2251		 }
2252	      } else {
2253	         /* TW: New from 650/LVDS 1.10.07 */
2254	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
2255	             SiS_Pr->SiS_LCDHDES = 480;
2256                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
2257	             SiS_Pr->SiS_LCDHDES = 804;
2258                 if(!(modeflag & HalfDCLK)) {
2259                     SiS_Pr->SiS_LCDHDES = 320;
2260	             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
2261	                SiS_Pr->SiS_LCDHDES = 632;
2262                 }
2263              }
2264            }
2265          }
2266        }
2267      }
2268    }
2269  }
2270  return;
2271}
2272
2273/* TW: Checked against 630/LVDS (2.04.5c) and 650/LVDS (1.10.07) BIOS */
2274void
2275SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2276                  USHORT RefreshRateTableIndex,USHORT *PanelIndex,
2277		  USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
2278{
2279  USHORT tempbx,tempal,modeflag;
2280
2281  if(ModeNo<=0x13) {
2282    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2283	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2284  } else {
2285    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2286	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2287  }
2288
2289  tempbx = 0;
2290  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2291    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2292      tempbx = 32;
2293      if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx += 2;
2294      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
2295    }
2296  }
2297  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2298    tempbx = SiS_Pr->SiS_LCDTypeInfo;
2299    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
2300    /* TW: Inserted from 650/LVDS (1.10.07) BIOS */
2301    if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2302       if(modeflag & HalfDCLK) tempbx += 16;
2303    }
2304  }
2305  /* TW: Inserted from 630/LVDS and 650/LVDS (1.10.07) BIOS */
2306  if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
2307    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
2308       tempal = 0x07;
2309       if(HwDeviceExtension->jChipType < SIS_315H) {
2310          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2311       }
2312    }
2313  }
2314
2315  *PanelIndex = tempbx;
2316  *ResIndex = tempal & 0x1F;
2317}
2318
2319void
2320SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2321                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,
2322		   USHORT *ResIndex)
2323{
2324  USHORT tempbx=0,tempal;
2325
2326  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2327       tempbx = 3;
2328  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
2329       tempbx = 4;
2330  } else tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
2331
2332  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx += 4;
2333
2334  if(ModeNo<=0x13)
2335    	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2336  else
2337    	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2338
2339  *PanelIndex = tempbx;
2340  *ResIndex = tempal & 0x1F;
2341}
2342
2343/* TW: Checked against 650/LVDS (1.10.07), 650/301LV, 650/301LVx (!), 630/301 and 630/301B (II) BIOS */
2344void
2345SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex,
2346                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
2347{
2348  USHORT i,j,modeflag;
2349  USHORT tempcl,tempah,tempbl,temp;
2350
2351  if(ModeNo<=0x13) {
2352    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2353  } else {
2354    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2355  }
2356
2357  /* TW: BIOS does not do this (neither 301 nor LVDS) */
2358  /*     (But it's harmless; see SetCRT2Offset) */
2359  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
2360
2361  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
2362  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2363
2364	/* TW:   1. for LVDS/302B/302LV **LCDA** */
2365
2366      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
2367      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2368
2369  } else {
2370
2371    for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0);
2372
2373    tempcl = SiS_Pr->SiS_ModeType;
2374
2375    if(HwDeviceExtension->jChipType < SIS_315H) {
2376
2377      /* ---- 300 series ---- */
2378
2379      /* TW: Inserted entire if-section from 630/301B BIOS */
2380      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2381	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
2382	  temp &= 0xef;
2383	  temp |= 0x02;
2384	  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2385	     temp |= 0x10;
2386	     temp &= 0xfd;
2387	  }
2388	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
2389      }
2390
2391      if(ModeNo > 0x13) {
2392        tempcl -= ModeVGA;
2393        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
2394           tempah = ((0x10 >> tempcl) | 0x80);
2395        }
2396      } else  tempah = 0x80;
2397
2398      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2399
2400    } else {
2401
2402    /* ---- 310 series ---- */
2403
2404      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2405        if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
2406	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2407        }
2408      }
2409
2410      if(ModeNo > 0x13) {
2411        tempcl -= ModeVGA;
2412        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
2413           tempah = (0x08 >> tempcl);
2414           if (tempah == 0) tempah = 1;
2415           tempah |= 0x40;
2416        }
2417      } else  tempah = 0x40;
2418
2419      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
2420
2421    }
2422
2423    if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
2424
2425    if(HwDeviceExtension->jChipType < SIS_315H) {
2426        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
2427    } else {
2428        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
2429    }
2430
2431    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
2432
2433	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
2434
2435    	tempah = 0x01;
2436    	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2437      		tempah |= 0x02;
2438    	}
2439    	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2440      		tempah ^= 0x05;
2441      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2442        		tempah ^= 0x01;
2443      		}
2444    	}
2445
2446	if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
2447
2448    	if(HwDeviceExtension->jChipType < SIS_315H) {
2449
2450		/* --- 300 series --- */
2451
2452      		tempah = (tempah << 5) & 0xFF;
2453      		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
2454      		tempah = (tempah >> 5) & 0xFF;
2455
2456    	} else {
2457
2458		/* --- 310 series --- */
2459
2460      		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2461
2462    	}
2463
2464    	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2465      		tempah |= 0x10;
2466	}
2467
2468	/* TW: Inserted from 630/301 BIOS */
2469	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2470		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
2471			tempah |= 0x80;
2472		}
2473	} else {
2474		tempah |= 0x80;
2475	}
2476
2477    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)){
2478      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2479          		tempah |= 0x20;
2480      		}
2481    	}
2482
2483    	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2484
2485    	tempah = 0;
2486    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2487      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2488       			if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2489            			SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
2490            			tempah |= 0x40;
2491       			} else {
2492        			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) {
2493#ifdef oldHV
2494          				if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
2495#endif
2496            					SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
2497            					tempah |= 0x40;
2498#ifdef oldHV
2499          				}
2500#endif
2501        			}
2502      			}
2503     		} else {
2504        		SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
2505        		tempah |= 0x40;
2506      		}
2507    	}
2508	/* TW: Inserted from 630/301LVx BIOS 1.10.6s */
2509	if(HwDeviceExtension->jChipType >= SIS_315H) {
2510	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2511	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
2512		    tempah |= 0x40;
2513	    }
2514	}
2515
2516	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024 ||
2517	            SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
2518		tempah |= 0x80;
2519	}
2520
2521    	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2522
2523    } else {
2524
2525    	/* TW: 3. for LVDS */
2526
2527	/* TW: Inserted if-statement - Part1Port 0x2e not assigned on 300 series */
2528	if(HwDeviceExtension->jChipType >= SIS_315H) {
2529
2530	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
2531	    *     (LVDS can only be slave in 8bpp modes)
2532	    */
2533	   tempah = 0x80;
2534	   if( (modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2535	       if (SiS_Pr->SiS_VBInfo & DriverMode) {
2536	           tempah |= 0x02;
2537	       }
2538	   }
2539
2540	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2541               tempah |= 0x02;
2542    	   }
2543
2544	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2545	       tempah ^= 0x01;
2546	   }
2547
2548	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2549	       tempah = 1;
2550	   }
2551
2552    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2553
2554	} else {
2555
2556	   /* TW: Inserted entire section from 630/LVDS BIOS (added ModeType check) */
2557	   tempah = 0;
2558	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2559               	  tempah |= 0x02;
2560    	   }
2561	   tempah <<= 5;
2562
2563	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2564
2565	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
2566
2567	}
2568
2569    }
2570
2571  }
2572
2573  /* TW: Inserted the entire following section */
2574
2575  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
2576
2577      if(HwDeviceExtension->jChipType >= SIS_315H) {
2578
2579#ifdef SIS650301NEW        /* TW: This is done in 650/301LVx 1.10.6s BIOS */
2580         tempah = 0x04;
2581         tempbl = 0xfb;
2582         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2583            tempah = 0x00;
2584	    if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
2585	       tempbl = 0xff;
2586         }
2587         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2588
2589	 /* TW: This in order to fix "TV-blue-bug" on 315+301 */
2590         if(SiS_Pr->SiS_VBType & VB_SIS301) {
2591	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);           /* RIGHT for 315+301 */
2592	 } else {
2593	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);    /* WRONG for 315+301 */
2594	 }
2595
2596	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
2597
2598	 tempah = 0x00;
2599         tempbl = 0x7f;
2600         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2601            tempbl = 0xff;
2602	    if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
2603	       tempah |= 0x80;
2604         }
2605         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2606
2607#else
2608         /* This is done in 650/301LV BIOS instead: */
2609         tempah = 0x30;
2610	 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2611	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2612
2613	 tempah = 0xc0;
2614	 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2615	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempah);
2616
2617	 tempah = 0x80;
2618	 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2619	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7F,tempah);
2620#endif
2621
2622      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2623
2624         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2625
2626         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | DisableCRT2Display))
2627	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2628	 else
2629	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2630
2631      }
2632
2633  } else {  /* LVDS */
2634
2635      if(HwDeviceExtension->jChipType >= SIS_315H) {
2636         tempah = 0x04;
2637	 tempbl = 0xfb;
2638         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2639            tempah = 0x00;
2640	    if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
2641	       tempbl = 0xff;
2642         }
2643	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2644
2645	 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
2646	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
2647
2648	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
2649      }
2650
2651  }
2652
2653}
2654
2655void
2656SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2657                USHORT RefreshRateTableIndex,
2658		PSIS_HW_DEVICE_INFO HwDeviceExtension)
2659{
2660  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
2661     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2662        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2663          SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2664	                      HwDeviceExtension);
2665        } else {
2666	  if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)){
2667              SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2668	                         HwDeviceExtension);
2669	      /* TW: Need LVDS Data for LCD on 630/301B! */
2670	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2671	                          HwDeviceExtension);
2672	  } else {
2673	      SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2674	                         HwDeviceExtension);
2675          }
2676        }
2677     } else
2678     	SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2679	                   HwDeviceExtension);
2680  } else {
2681     SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2682                         HwDeviceExtension);
2683  }
2684}
2685
2686/* Checked with 650/LVDS 1.10.07 BIOS */
2687void
2688SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2689                    USHORT RefreshRateTableIndex,
2690		    PSIS_HW_DEVICE_INFO HwDeviceExtension)
2691{
2692   USHORT CRT2Index, ResIndex;
2693   const SiS_LVDSDataStruct *LVDSData = NULL;
2694
2695   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2696
2697   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2698
2699      SiS_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2700                      &CRT2Index,&ResIndex);
2701
2702      switch (CRT2Index) {
2703      	case  0:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;    break;
2704      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;   break;
2705        case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_1;    break;
2706	case  3:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1;   break;
2707	case  4:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1;   break;
2708      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;    break;
2709      	case  6:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;   break;
2710      	case  7:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_2;    break;
2711	case  8:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2;   break;
2712	case  9:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2;   break;
2713      }
2714
2715   } else {
2716
2717      /* TW: SiS630/301B needs LVDS Data! */
2718      if( (HwDeviceExtension->jChipType < SIS_315H) &&
2719          (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
2720	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) )
2721              SiS_Pr->SiS_IF_DEF_LVDS = 1;
2722
2723      SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2724                     &CRT2Index,&ResIndex,HwDeviceExtension);
2725
2726      /* TW: SiS630/301B needs LVDS Data! */
2727      if( (HwDeviceExtension->jChipType < SIS_315H) &&
2728          (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
2729	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) )
2730              SiS_Pr->SiS_IF_DEF_LVDS = 0;
2731
2732      switch (CRT2Index) {
2733      	case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
2734      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
2735      	case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
2736      	case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
2737      	case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
2738      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
2739	case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
2740        case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;  /* TW: New */
2741	case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;  /* TW: New */
2742	case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;  /* TW: New */
2743      	case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
2744      	case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
2745      	case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
2746      	case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
2747      	case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
2748	case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;  /* TW: New */
2749	case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;  /* TW: New */
2750	case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;  /* TW: New */
2751	case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;  /* TW: New */
2752     }
2753   }
2754
2755   SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
2756   SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
2757   SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
2758   SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
2759
2760  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
2761
2762    if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)){
2763         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
2764           SiS_Pr->SiS_HDE = 1024;
2765           SiS_Pr->SiS_VDE = 768;
2766         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
2767           SiS_Pr->SiS_HDE = 1280;
2768           SiS_Pr->SiS_VDE = 1024;
2769	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
2770           SiS_Pr->SiS_HDE = 1400;
2771           SiS_Pr->SiS_VDE = 1050;
2772	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
2773           SiS_Pr->SiS_HDE = 1600;
2774           SiS_Pr->SiS_VDE = 1200;
2775         } else {
2776	   SiS_Pr->SiS_HDE = 1280;
2777	   SiS_Pr->SiS_VDE = 960;
2778	 }
2779    }
2780
2781  } else {
2782
2783    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2784      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
2785        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
2786          if((!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) || (SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
2787            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
2788              SiS_Pr->SiS_HDE = 800;
2789              SiS_Pr->SiS_VDE = 600;
2790            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
2791              SiS_Pr->SiS_HDE = 1024;
2792              SiS_Pr->SiS_VDE = 768;
2793            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
2794              SiS_Pr->SiS_HDE = 1280;
2795              SiS_Pr->SiS_VDE = 1024;
2796            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
2797	      SiS_Pr->SiS_HDE = 1024;
2798              SiS_Pr->SiS_VDE = 600;
2799	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2800	      SiS_Pr->SiS_HDE = 1400;
2801              SiS_Pr->SiS_VDE = 1050;
2802	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
2803	      SiS_Pr->SiS_HDE = 1152;
2804	      SiS_Pr->SiS_VDE = 768;
2805	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
2806	      SiS_Pr->SiS_HDE = 1152;
2807	      SiS_Pr->SiS_VDE = 864;
2808	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
2809	      SiS_Pr->SiS_HDE = 1280;
2810	      SiS_Pr->SiS_VDE = 768;
2811	    } else {
2812	      SiS_Pr->SiS_HDE = 1600;
2813	      SiS_Pr->SiS_VDE = 1200;
2814	    }
2815            if(SiS_Pr->SiS_IF_DEF_FSTN) {
2816              SiS_Pr->SiS_HDE = 320;
2817              SiS_Pr->SiS_VDE = 480;
2818            }
2819          }
2820        }
2821      }
2822    }
2823  }
2824}
2825
2826/* TW: Checked against 630/301B BIOS; does not check VDE values for LCD */
2827void
2828SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2829                   USHORT RefreshRateTableIndex,
2830		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
2831{
2832  USHORT tempax,tempbx,modeflag;
2833  USHORT resinfo;
2834  USHORT CRT2Index,ResIndex;
2835  const SiS_LCDDataStruct *LCDPtr = NULL;
2836  const SiS_TVDataStruct  *TVPtr  = NULL;
2837
2838  if(ModeNo<=0x13) {
2839    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2840    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2841  } else {
2842    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2843    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2844  }
2845  SiS_Pr->SiS_NewFlickerMode = 0;
2846  SiS_Pr->SiS_RVBHRS = 50;
2847  SiS_Pr->SiS_RY1COE = 0;
2848  SiS_Pr->SiS_RY2COE = 0;
2849  SiS_Pr->SiS_RY3COE = 0;
2850  SiS_Pr->SiS_RY4COE = 0;
2851
2852  SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2853
2854  /* TW: For VGA2 ("RAMDAC2") */
2855
2856  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
2857     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2858                        HwDeviceExtension);
2859     return;
2860  }
2861
2862  /* TW: For TV */
2863
2864  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2865
2866    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2867                   &CRT2Index,&ResIndex,HwDeviceExtension);
2868
2869    switch (CRT2Index) {
2870#ifdef oldHV
2871      case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
2872      case  7:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
2873      case 12:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
2874#endif
2875      case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
2876      case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
2877      case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
2878      case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
2879      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
2880    }
2881
2882    SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
2883    SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
2884    SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
2885    SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
2886    SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
2887    SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
2888    SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
2889    SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
2890
2891    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {   /* TW: NOT oldHV! */
2892
2893      	if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
2894      	if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
2895	if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
2896
2897        if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_SetFlag |= TVSimuMode;
2898
2899        SiS_Pr->SiS_HT = ExtHiTVHT;
2900        SiS_Pr->SiS_VT = ExtHiTVVT;
2901        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2902          if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
2903            SiS_Pr->SiS_HT = StHiTVHT;
2904            SiS_Pr->SiS_VT = StHiTVVT;
2905            if(!(modeflag & Charx8Dot)){
2906              SiS_Pr->SiS_HT = StHiTextTVHT;
2907              SiS_Pr->SiS_VT = StHiTextTVVT;
2908            }
2909          }
2910        }
2911
2912    } else {
2913
2914      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
2915      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
2916      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
2917      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
2918
2919      if(modeflag & HalfDCLK) {
2920         SiS_Pr->SiS_RY1COE = 0x00;
2921         SiS_Pr->SiS_RY2COE = 0xf4;
2922         SiS_Pr->SiS_RY3COE = 0x10;
2923         SiS_Pr->SiS_RY4COE = 0x38;
2924      }
2925
2926      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
2927        SiS_Pr->SiS_HT = NTSCHT;
2928        SiS_Pr->SiS_VT = NTSCVT;
2929      } else {
2930        SiS_Pr->SiS_HT = PALHT;
2931        SiS_Pr->SiS_VT = PALVT;
2932      }
2933
2934    }
2935
2936    return;
2937  }
2938
2939  /* TW: For LCD */
2940  /* TW: Checked against 650/301LV; CRT2Index different (but does not matter) */
2941
2942  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2943
2944    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
2945                   &CRT2Index,&ResIndex,HwDeviceExtension);
2946
2947    switch (CRT2Index) {
2948      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
2949      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
2950      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
2951      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
2952      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
2953      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
2954      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
2955      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
2956      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
2957      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
2958      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding */
2959      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing */
2960      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
2961      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
2962      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
2963      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
2964    }
2965
2966    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
2967    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
2968    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
2969    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
2970    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
2971    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
2972
2973    tempax = 1024;
2974    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2975      if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
2976      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
2977      else                               tempbx = 768;
2978    } else {
2979      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
2980      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
2981      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
2982      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
2983      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
2984      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
2985      else                               tempbx = 768;
2986    }
2987    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
2988      tempax = 1280;
2989      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
2990      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
2991      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
2992      else                               tempbx = 1024;
2993    }
2994    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960){
2995      tempax = 1280;
2996      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
2997      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
2998      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
2999      else                                tempbx = 960;
3000    }
3001    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
3002      tempax = 1400;
3003      tempbx = 1050;
3004    }
3005    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
3006       tempax = SiS_Pr->SiS_VGAHDE;
3007       tempbx = SiS_Pr->SiS_VGAVDE;
3008    }
3009    SiS_Pr->SiS_HDE = tempax;
3010    SiS_Pr->SiS_VDE = tempbx;
3011    return;
3012  }
3013}
3014
3015USHORT
3016SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
3017{
3018  USHORT resindex;
3019
3020  if(ModeNo<=0x13)
3021    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3022  else
3023    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3024
3025  return(resindex);
3026}
3027
3028/* TW: Checked against 650/301LV, 650/LVDS, 630/LVDS, 630/301 and 630/301B BIOS */
3029void
3030SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3031                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
3032{
3033  USHORT xres,yres,modeflag=0,resindex;
3034
3035  resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
3036
3037  if(ModeNo <= 0x13) {
3038    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3039    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3040  } else {
3041	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3042    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3043    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3044  }
3045
3046  /* TW: Inserted entire if-section from 650/LVDS BIOS 1.10.07: */
3047  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3048      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
3049          if(yres == 350) yres = 400;
3050      }
3051      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3052 	  if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34) == 0x12)
3053	      yres = 400;
3054      }
3055  }
3056
3057  if(ModeNo > 0x13) {
3058      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
3059            xres *= 2;
3060            yres *= 2;
3061      } else {
3062  	    if(modeflag & HalfDCLK)       xres *= 2;
3063  	    if(modeflag & DoubleScanMode) yres *= 2;
3064      }
3065  }
3066
3067  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3068        /* TW: Inserted from 650/301LV BIOS */
3069        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3070                if(xres == 720) xres = 640;
3071	} else {
3072	   if(xres == 720) xres = 640;
3073    	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
3074      		if(yres == 400) yres = 405;
3075      		if(yres == 350) yres = 360;
3076      		if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3077        		if(yres == 360) yres = 375;
3078      		}
3079   	   }
3080    	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
3081      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3082        		if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
3083          			if(yres == 350) yres = 357;
3084          			if(yres == 400) yres = 420;
3085            			if(yres == 480) yres = 525;
3086        		}
3087      		}
3088    	   }
3089	   /* TW: Inserted for 630/301B */
3090	   if(HwDeviceExtension->jChipType < SIS_315H) {
3091	      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3092                  if(xres == 720) xres = 640;
3093	      }
3094	   }
3095	}
3096  } else {
3097    	if(xres == 720) xres = 640;
3098	/* TW: Inserted from 650/LVDS and 630/LVDS BIOS */
3099	if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
3100	      yres = 400;
3101	      if(HwDeviceExtension->jChipType >= SIS_315H) {
3102	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3103	      } else {
3104	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3105	      }
3106	}
3107  }
3108  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3109  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3110}
3111
3112/* TW: Checked against 650/301 and 650/LVDS (1.10.07) BIOS; modified for new panel resolutions */
3113/* TW: Done differently in 630/301B BIOS; but same effect; checked against 630/301 */
3114void
3115SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3116	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
3117	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
3118{
3119  USHORT tempbx=0,tempal=0;
3120  USHORT Flag,resinfo=0;
3121
3122  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3123    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
3124	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
3125			tempbx = 15;
3126		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
3127		        tempbx = 20;
3128			if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx = 21;
3129			if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
3130		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
3131		        tempbx = 23;
3132			if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx = 24;
3133			if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
3134		} else if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
3135			tempbx = 13;
3136			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
3137		} else {
3138      		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
3139      		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3140        		tempbx += 5;
3141                        /* GetRevisionID();  */
3142			/* TW: BIOS only adds 5 once */
3143        		tempbx += 5;
3144       		   }
3145	        }
3146     	} else {
3147#ifdef oldHV					               /* TV */
3148       		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV){
3149         		if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode); /* TW: Was "(!TVSimuMode)" - WRONG */
3150         		tempbx = 2;
3151         		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3152            			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12;  /* TW: Was 10! - WRONG */
3153         		}
3154       		} else {
3155#endif
3156         		if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
3157         		else tempbx = 4;
3158         		if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5;
3159#ifdef oldHV
3160       		}
3161#endif
3162     	}
3163
3164     	if(ModeNo <= 0x13)
3165       		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3166     	else
3167       		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3168
3169     	tempal &= 0x3F;
3170
3171      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
3172                     && (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {  /* TW: Added -Hivision (BIOS) */
3173      		if(tempal == 0x06) tempal = 0x07;
3174        }
3175
3176        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3177            if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
3178	}
3179
3180     	*CRT2Index = tempbx;
3181     	*ResIndex = tempal;
3182
3183  } else {   /* LVDS */
3184
3185    	Flag = 1;
3186    	tempbx = 0;
3187    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3188      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3189        		Flag = 0;
3190        		tempbx = 10;
3191        		if(SiS_Pr->SiS_VBInfo & SetPALTV)        tempbx += 2;
3192        		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
3193      		}
3194    	}
3195
3196    	if(Flag == 1) {
3197      		tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
3198		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
3199   	      	    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
3200		} else {
3201		    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
3202			tempbx = 8;
3203			if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx++;
3204		    }
3205        	    if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3206			tempbx = 7;
3207        	    }
3208
3209     		    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480)  tempbx = 6;
3210
3211		    /* TW: Inserted from 630/LVDS 2.04.5c BIOS */
3212		    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
3213			tempbx = 15;
3214  		        if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
3215		    }
3216		    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
3217		        tempbx = 16;
3218			if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
3219		    }
3220		 }
3221	}
3222
3223    	if(ModeNo <= 0x13)
3224      		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3225    	else {
3226      		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3227		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3228	}
3229
3230	if(SiS_Pr->SiS_IF_DEF_FSTN){
3231       	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
3232         		tempbx = 14;
3233         		tempal = 6;
3234        	}
3235    	}
3236
3237	/* TW: Inserted from 650/LVDS BIOS */
3238	if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
3239	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
3240		if(HwDeviceExtension->jChipType < SIS_315H) {
3241		    /* TW: Inserted from 630/LVDS (2.04.5c) and 630/301B (II) BIOS */
3242		    if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
3243		}
3244
3245	}
3246
3247	/* TW: Inserted from 630/301B BIOS */
3248	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3249	    if(ModeNo > 0x13) {
3250	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
3251		    tempal = 6;
3252	    }
3253	}
3254
3255    	*CRT2Index = tempbx;
3256    	*ResIndex = tempal & 0x1F;
3257  }
3258}
3259
3260void
3261SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3262		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
3263		USHORT *ResIndex)
3264{
3265  USHORT tempbx,tempal;
3266
3267  tempbx = SiS_Pr->SiS_LCDResInfo;
3268
3269  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
3270       tempbx = 4;
3271  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
3272       tempbx = 3;
3273  } else {
3274       tempbx -= SiS_Pr->SiS_Panel1024x768;
3275  }
3276
3277  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx += 5;
3278
3279  if(ModeNo <= 0x13)
3280      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3281  else
3282      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3283
3284  *CRT2Index = tempbx;
3285  *ResIndex = tempal & 0x1F;
3286}
3287
3288/* TW: New from 650/301LVx BIOS */
3289void
3290SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3291		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
3292		    USHORT *ResIndex)
3293{
3294  USHORT tempbx,tempal;
3295
3296  if(ModeNo <= 0x13)
3297      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3298  else
3299      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3300
3301  tempbx = SiS_Pr->SiS_LCDResInfo;
3302
3303  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)    tempbx += 16;
3304  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
3305
3306  *CRT2Index = tempbx;
3307  *ResIndex = tempal & 0x3F;
3308}
3309
3310/* TW: Checked against all (incl 650/LVDS (1.10.07), 630/301B, 630/301) BIOSes */
3311USHORT
3312SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
3313                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
3314{
3315  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
3316                               0x01, 0x01, 0x01, 0x01,
3317			       0x01, 0x01, 0x01, 0x01,
3318			       0x01, 0x01, 0x01, 0x01 };
3319  USHORT RefreshRateTableIndex,i,backup_i;
3320  USHORT modeflag,index,temp,backupindex;
3321
3322  if (ModeNo <= 0x13)
3323    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3324  else
3325    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3326
3327  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3328    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3329      		if(modeflag & HalfDCLK) return(0);
3330    	}
3331  }
3332
3333  if(ModeNo < 0x14) return(0xFFFF);
3334
3335 /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
3336  *     On LVDS machines, CRT2 index is always 0 and will be
3337  *     set to 0 by the following code; this causes the function
3338  *     to take the first non-interlaced mode in SiS_Ext2Struct
3339  */
3340
3341  index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33);
3342  index >>= SiS_Pr->SiS_SelectCRT2Rate;
3343  index &= 0x0F;
3344  backupindex = index;
3345
3346  if(index > 0) index--;
3347
3348  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
3349      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3350        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
3351      } else {
3352        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3353	    if(HwDeviceExtension->jChipType < SIS_315H)    index = 0;
3354	    else if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) index = backupindex = 0;
3355	}
3356      }
3357  }
3358
3359  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
3360    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3361      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3362        		index = 0;
3363      		}
3364    	}
3365    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
3366      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3367		        /* TW: This is not done in 630/301B BIOS */
3368           		temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
3369        		if(index > temp) index = temp;
3370      		} else {
3371        		index = 0;
3372      		}
3373    	}
3374  }
3375
3376  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
3377  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
3378
3379  /* TW: Inserted from 650/LVDS 1.10.07, 650/301LVx 1.10.6s */
3380  if(HwDeviceExtension->jChipType >= SIS_315H) {
3381    if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
3382      if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
3383          (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
3384            if(backupindex <= 1)
3385	       RefreshRateTableIndex++;
3386      }
3387    }
3388  }
3389
3390  i = 0;
3391  do {
3392    	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
3393    	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
3394    	temp &= ModeInfoFlag;
3395    	if(temp < SiS_Pr->SiS_ModeType) break;
3396    	i++;
3397    	index--;
3398  } while(index != 0xFFFF);
3399
3400  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
3401    	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3402      		temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
3403      		if(temp & InterlaceMode) {
3404        		i++;
3405      		}
3406    	}
3407  }
3408
3409  i--;
3410
3411  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
3412    	backup_i = i;
3413    	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
3414	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
3415		/* TW: This is for avoiding random data to be used; i is
3416		 *     in an undefined state if no matching CRT2 mode is
3417		 *     found.
3418		 */
3419		i = backup_i;
3420	}
3421  }
3422
3423  return(RefreshRateTableIndex + i);
3424}
3425
3426/* Checked against all (incl 650/LVDS (1.10.07), 630/301) BIOSes */
3427BOOLEAN
3428SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3429                   USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension)
3430{
3431  USHORT tempax,tempbx,resinfo;
3432  USHORT modeflag,infoflag;
3433
3434  if (ModeNo <= 0x13)
3435    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3436  else
3437    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3438
3439  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3440  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
3441
3442  tempax = 0;
3443  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3444  	/* TW: For 301, 301B, 302B, 301LV, 302LV */
3445    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3446      		tempax |= SupportRAMDAC2;
3447		if(HwDeviceExtension->jChipType >= SIS_315H) {
3448		    tempax |= SupportTV;
3449		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3450		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3451			    if(resinfo == 0x0a) tempax |= SupportTV1024;
3452			}
3453		    }
3454		}
3455    	}
3456    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
3457      		tempax |= SupportLCD;
3458		if(HwDeviceExtension->jChipType >= SIS_315H) {
3459                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
3460		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
3461		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
3462			    tempax |= SupportAllCRT2;
3463			    (*i) = 0;   /* TW: Restore RefreshTableIndex (BIOS 650/301LVx 1.10.6s) */
3464                            return(1);
3465		         } else {
3466      		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
3467        		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
3468           			if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
3469				    return(0);
3470				} else {
3471             			    if((resinfo >= 9) && (resinfo != 0x14)) {
3472               				tempax = 0;
3473               				return(0);
3474             			    }
3475           			}
3476        		      }
3477		            }
3478		         }
3479		      }
3480      		   }
3481		} else {
3482		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
3483		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
3484		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
3485		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
3486		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
3487		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
3488		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
3489		     if(resinfo > 9) return(0);
3490		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3491		     if(resinfo > 8) return(0);
3492		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
3493		     if((resinfo == 4) || (resinfo > 7)) return(0);
3494		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
3495		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
3496		  }
3497		}
3498    	}
3499#ifdef oldHV
3500    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {    /* for HiTV */
3501      		tempax |= SupportHiVisionTV;
3502      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
3503        		if(resinfo == 4) return(0);
3504        		if(resinfo == 3) {
3505          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
3506        		}
3507        		if(resinfo > 7) return(0);
3508      		}
3509    	} else {
3510#endif
3511      	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
3512        	tempax |= SupportTV;
3513		tempax |= SupportTV1024;
3514		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3515		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3516		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
3517			     if(resinfo != 8) {
3518			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3519				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
3520				     tempax &= ~(SupportTV1024);
3521				     if(HwDeviceExtension->jChipType >= SIS_315H) {
3522                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3523				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3524			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
3525			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
3526		                             }
3527				         }
3528		                     } else {
3529				         if( (resinfo != 3) ||
3530					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
3531					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
3532					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
3533						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3534						     if(resinfo == 3) return(0);
3535						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
3536						 }
3537		                             }
3538                                         } else return(0);
3539				     }
3540				 }
3541			     }
3542			} else {
3543			    tempax &= ~(SupportTV1024);
3544			    if(HwDeviceExtension->jChipType >= SIS_315H) {
3545			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3546			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3547			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
3548			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
3549		                    }
3550		                }
3551			    } else {
3552			        if( (resinfo != 3) ||
3553				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
3554				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
3555				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
3556					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3557					     if(resinfo == 3) return(0);
3558					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
3559					 }
3560		                     }
3561                                } else return(0);
3562                            }
3563			}
3564		    } else {  /* slavemode */
3565			if(resinfo != 8) {
3566			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3567			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
3568				 tempax &= ~(SupportTV1024);
3569				 if(HwDeviceExtension->jChipType >= SIS_315H) {
3570				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3571				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3572			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
3573			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
3574		                         }
3575		                     }
3576			        } else {
3577				    if( (resinfo != 3) ||
3578				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
3579				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
3580				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
3581					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3582					         if(resinfo == 3) return(0);
3583					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
3584					     }
3585		                         }
3586                                    } else return(0);
3587				}
3588			    }
3589			}
3590		    }
3591		} else {   /* 301 */
3592		    tempax &= ~(SupportTV1024);
3593		    if(HwDeviceExtension->jChipType >= SIS_315H) {
3594		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3595		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
3596			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
3597			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
3598		            }
3599		        }
3600		    } else {
3601		        if( (resinfo != 3) ||
3602			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
3603			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
3604			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
3605			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
3606				    if(resinfo == 3) return(0);
3607				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
3608				}
3609		            }
3610                        } else return(0);
3611		    }
3612		}
3613        }
3614#ifdef oldHV
3615    	}
3616#endif
3617  } else {	/* TW: for LVDS  */
3618
3619    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3620      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3621        		tempax |= SupportCHTV;
3622      		}
3623    	}
3624    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3625      		tempax |= SupportLCD;
3626		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
3627		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
3628		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
3629		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
3630		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
3631		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
3632		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
3633		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
3634		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
3635                     if(resinfo > 0x09) return(0);
3636                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
3637		     if(resinfo > 0x08) return(0);
3638		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
3639		     if(resinfo > 0x07) return(0);
3640		     if(resinfo == 0x04) return(0);
3641		}
3642    	}
3643  }
3644  /* TW: Look backwards in table for matching CRT2 mode */
3645  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
3646     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
3647     	if(infoflag & tempax) {
3648       		return(1);
3649     	}
3650     	if ((*i) == 0) break;
3651  }
3652  /* TW: Look through the whole mode-section of the table from the beginning
3653   *     for a matching CRT2 mode if no mode was found yet.
3654   */
3655  for((*i) = 0; ; (*i)++) {
3656     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
3657     	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
3658       		return(0);
3659     	}
3660     	if(infoflag & tempax) {
3661       		return(1);
3662     	}
3663  }
3664  return(1);
3665}
3666
3667/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
3668void
3669SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
3670{
3671  USHORT temp1,temp2;
3672
3673  /* TW: We store CRT1 ModeNo in CR34 */
3674  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
3675  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
3676  temp2 = ~(SetInSlaveMode >> 8);
3677  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
3678}
3679
3680/* TW: Checked against 650+301, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */
3681void
3682SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
3683              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
3684{
3685  USHORT tempax,tempbx,temp;
3686  USHORT modeflag, resinfo=0;
3687  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
3688
3689  if (ModeNo<=0x13)
3690    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3691  else {
3692   	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3693	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3694  }
3695
3696  SiS_Pr->SiS_SetFlag = 0;
3697
3698  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
3699
3700  tempbx = 0;
3701  if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {              /* TW: "== 0" inserted from 630/301B BIOS */
3702    	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
3703	if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/301LVx 1.10.6s */
3704	     temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
3705	     temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
3706	}
3707	if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/301LVx 1.10.6s */
3708	     temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
3709	     temp |= SetCRT2ToSVIDEO;  						/* 0x08 */
3710	}
3711    	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
3712       		temp = (SetCRT2ToLCD | SetSimuScanMode);
3713       		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
3714    	}
3715    	tempbx |= temp;
3716    	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
3717	tempax = temp << 8;
3718        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch |        /* TW: Inserted from 650/LVDS+301LV BIOS */
3719		         SetNotSimuMode | SetPALTV);                    /* TW: Inserted from 650/LVDS+301LV BIOS */
3720    	tempbx |= tempax;
3721    	temp = SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display;
3722   	temp = 0xFFFF ^ temp;
3723    	tempbx &= temp;
3724#ifdef SIS315H
3725	if(HwDeviceExtension->jChipType >= SIS_315H) {
3726	   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
3727    	   if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS30xLV | VB_SIS30xNEW)) {
3728                if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) {
3729		    if(tempbx & SetCRT2ToLCD) {
3730		        if(ModeNo <= 0x13) {
3731			     if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr)) {
3732			          if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (SetNotSimuMode >> 8))) {
3733				      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,0x03);
3734				  }
3735			     }
3736			}
3737		    }
3738		}
3739       		if((temp & (EnableDualEdge | SetToLCDA))
3740		          == (EnableDualEdge | SetToLCDA))   /* TW: BIOS only tests these bits, added "& ..." */
3741          		tempbx |= SetCRT2ToLCDA;
3742    	   }
3743	   /* TW: Inserted from 650/LVDS 1.10.07 BIOS: */
3744	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3745	        if(temp & SetToLCDA)
3746		        tempbx |= SetCRT2ToLCDA;
3747	        if(temp & EnableLVDSHiVision)
3748		        tempbx |= SetCRT2ToHiVisionTV;
3749	   }
3750	}
3751#endif
3752    	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3753	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD |
3754		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO; /* = 0x807C; */
3755      		if(SiS_Pr->SiS_IF_DEF_HiVision == 1)
3756                     temp |= SetCRT2ToHiVisionTV; /* = 0x80FC; */
3757    	} else {
3758                if(HwDeviceExtension->jChipType >= SIS_315H) {
3759                    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
3760        		temp = SetCRT2ToLCDA   | SetCRT2ToSCART |
3761			       SetCRT2ToLCD    | SetCRT2ToHiVisionTV |
3762			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;  /* = 0x80bc */
3763      		    else
3764        		temp = SetCRT2ToLCDA | SetCRT2ToLCD;
3765		} else {
3766      		    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
3767        		temp = SetCRT2ToTV | SetCRT2ToLCD;
3768      		    else
3769        		temp = SetCRT2ToLCD;
3770		}
3771    	}
3772
3773    	if(!(tempbx & temp)) {
3774      		tempax = DisableCRT2Display;
3775      		tempbx = 0;
3776    	}
3777
3778   	if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
3779      		if(tempbx & SetCRT2ToLCDA) {
3780        		tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
3781      		} else if(tempbx & SetCRT2ToRAMDAC) {
3782        		tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
3783      		} else if((tempbx & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD)) ){
3784        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
3785      		} else if(tempbx & SetCRT2ToSCART){
3786        		tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
3787        		tempbx |= SetPALTV;
3788		}
3789   	} else { /* LVDS */
3790	        if(HwDeviceExtension->jChipType >= SIS_315H) {
3791		    if(tempbx & SetCRT2ToLCDA)
3792		        tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
3793		}
3794      		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3795        	    if(tempbx & SetCRT2ToTV)
3796          		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
3797      		}
3798      		if(tempbx & SetCRT2ToLCD) {
3799        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
3800		}
3801	        if(HwDeviceExtension->jChipType >= SIS_315H) {
3802		    if(tempbx & SetCRT2ToLCDA)
3803		        tempbx |= SetCRT2ToLCD;
3804		}
3805	}
3806    	if(tempax & DisableCRT2Display) {
3807      		if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
3808        		tempbx = SetSimuScanMode | DisableCRT2Display;
3809      		}
3810    	}
3811    	if(!(tempbx & DriverMode)){
3812      		tempbx |= SetSimuScanMode;
3813    	}
3814
3815	/* TW: LVDS (LCD/TV) and 630+301B (LCD) can only be slave in 8bpp modes */
3816	if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_ModeType <= ModeVGA) ) {
3817		modeflag &= (~CRT2Mode);
3818	}
3819	if( (HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
3820	        if(SiS_Pr->SiS_ModeType <= ModeVGA) {
3821			if(tempbx & SetCRT2ToLCD) {
3822		    		modeflag &= (~CRT2Mode);
3823			}
3824	        }
3825	}
3826	/* TW end */
3827
3828    	if(!(tempbx & SetSimuScanMode)){
3829      		if(tempbx & SwitchToCRT2) {
3830        	    if(!(modeflag & CRT2Mode)) {
3831			if( (HwDeviceExtension->jChipType >= SIS_315H) &&
3832			        (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
3833			    if(resinfo != 0x0a)
3834                                tempbx |= SetSimuScanMode;
3835			} else {
3836            			tempbx |= SetSimuScanMode;
3837	                }
3838        	    }
3839      		} else {
3840        	    if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) {
3841          		if(!(tempbx & DriverMode)) {
3842            		    if(SiS_BridgeInSlave(SiS_Pr)) {
3843				tempbx |= SetSimuScanMode; /* TW: from BIOS 650/301/301LV/LVDS */
3844            		    }
3845                        }
3846                    }
3847      		}
3848    	}
3849
3850    	if(!(tempbx & DisableCRT2Display)) {
3851            if(tempbx & DriverMode) {
3852                if(tempbx & SetSimuScanMode) {
3853          	    if(!(modeflag & CRT2Mode)) {
3854	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
3855			       (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
3856			     if(resinfo != 0x0a) {  /* TW: Inserted from 650/301 BIOS */
3857			          tempbx |= SetInSlaveMode;
3858            		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3859              		 	     if(tempbx & SetCRT2ToTV) {
3860                		         if(!(tempbx & SetNotSimuMode))
3861					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
3862              			     }
3863                                  }
3864			     }                      /* TW: Inserted from 650/301 BIOS */
3865		        } else {
3866            		    tempbx |= SetInSlaveMode;
3867            		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3868              		        if(tempbx & SetCRT2ToTV) {
3869                		    if(!(tempbx & SetNotSimuMode))
3870					SiS_Pr->SiS_SetFlag |= TVSimuMode;
3871              			}
3872            		    }
3873                        }
3874	            }
3875                }
3876            } else {
3877                tempbx |= SetInSlaveMode;
3878        	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3879          	    if(tempbx & SetCRT2ToTV) {
3880            		if(!(tempbx & SetNotSimuMode))
3881			    SiS_Pr->SiS_SetFlag |= TVSimuMode;
3882          	    }
3883        	}
3884      	    }
3885    	}
3886
3887	if(SiS_Pr->SiS_CHOverScan) {
3888    	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
3889      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
3890      		if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1) )
3891		      tempbx |= SetCHTVOverScan;
3892    	   }
3893	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
3894      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
3895      		if( (temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1) )
3896		      tempbx |= SetCHTVOverScan;
3897    	   }
3898	}
3899  }
3900
3901  if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
3902#ifdef SIS300
3903     	if((HwDeviceExtension->jChipType==SIS_630)||
3904           (HwDeviceExtension->jChipType==SIS_730)) {
3905	   	if(ROMAddr && SiS_Pr->SiS_UseROM) {
3906			OutputSelect = ROMAddr[0xfe];
3907                }
3908           	if(!(OutputSelect & EnablePALMN))
3909             		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F);
3910           	if(tempbx & SetCRT2ToTV) {
3911              		if(tempbx & SetPALTV) {
3912                  		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
3913				/* temp &= 0xC0;  */ /* TW: BIOS only tests 0x40, not 0x80 */
3914                  		if(temp & 0x40)
3915                    			tempbx &= (~SetPALTV);
3916             		}
3917          	}
3918      	}
3919#endif
3920#ifdef SIS315H
3921     	if(HwDeviceExtension->jChipType >= SIS_315H) {
3922	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
3923			OutputSelect = ROMAddr[0xf3];
3924                }
3925		if(!(OutputSelect & EnablePALMN))
3926        		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F);
3927   		if(tempbx & SetCRT2ToTV) {
3928    			if(tempbx & SetPALTV) {
3929               			temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
3930               			if(temp & 0x40)
3931               				tempbx &= (~SetPALTV);
3932              		}
3933        	}
3934  	}
3935#endif
3936  }
3937
3938  SiS_Pr->SiS_VBInfo=tempbx;
3939
3940#ifdef TWDEBUG
3941#ifdef LINUX_KERNEL
3942  printk(KERN_INFO "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n", SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
3943#endif
3944#ifdef LINUX_XF86
3945  xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
3946#endif
3947#endif
3948
3949
3950  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
3951
3952}
3953
3954void
3955SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3956                   USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
3957{
3958  USHORT tempax,tempbx,temp;
3959  USHORT temp1,temp2,modeflag=0,tempcx;
3960  USHORT StandTableIndex,CRT1Index;
3961  USHORT ResInfo,DisplayType;
3962  const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
3963
3964  SiS_Pr->SiS_RVBHCMAX  = 1;
3965  SiS_Pr->SiS_RVBHCFACT = 1;
3966
3967  if(ModeNo <= 0x13){
3968
3969    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3970    	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
3971    	tempax = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[0];
3972    	tempbx = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[6];
3973    	temp1 = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[7];
3974
3975  } else {
3976
3977     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
3978
3979    	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
3980			RefreshRateTableIndex,&ResInfo,&DisplayType);
3981
3982    	if(temp == 0)  return;
3983
3984    	switch(DisplayType) {
3985    		case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;		break;
3986    		case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
3987    		case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
3988    		case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
3989    		case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
3990    		case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
3991    		case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
3992    		case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
3993    		case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
3994    		case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
3995    		case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
3996    		case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
3997		case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
3998		case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
3999		case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
4000		case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
4001		case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
4002		case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
4003    		case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
4004    		case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
4005    		case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
4006    		case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
4007    		case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break;
4008		case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
4009    		case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
4010    		case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
4011    		case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
4012    		case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
4013    		case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
4014    		case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
4015    		case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
4016		case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
4017		case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
4018		case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
4019		case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
4020    	}
4021    	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[0];
4022    	temp2  = (LVDSCRT1Ptr+ResInfo)->CR[14];
4023    	tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
4024    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
4025    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13]<<8;
4026    	tempcx = tempcx & 0x0100;
4027    	tempcx = tempcx << 2;
4028    	tempbx = tempbx | tempcx;
4029    	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
4030
4031    } else {
4032
4033    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4034    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
4035	if(HwDeviceExtension->jChipType < SIS_315H) {
4036    	   CRT1Index &= 0x3F;
4037	}
4038    	temp1  = (USHORT)SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
4039    	temp2  = (USHORT)SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
4040    	tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
4041    	tempbx = (USHORT)SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
4042    	tempcx = (USHORT)SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]<<8;
4043    	tempcx = tempcx & 0x0100;
4044    	tempcx = tempcx << 2;
4045    	tempbx = tempbx | tempcx;
4046    	temp1  = (USHORT)SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
4047
4048    }
4049
4050  }
4051
4052  if(temp1 & 0x01) tempbx |= 0x0100;
4053  if(temp1 & 0x20) tempbx |= 0x0200;
4054  tempax += 5;
4055
4056  /* Charx8Dot is no more used (and assumed), so we set it */
4057  modeflag |= Charx8Dot;
4058
4059  if(modeflag & Charx8Dot) tempax *= 8;
4060  else                     tempax *= 9;
4061
4062  /* TW: From 650/301LVx 1.10.6s */
4063  if(modeflag & HalfDCLK)  tempax <<= 1;
4064
4065  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
4066  tempbx++;
4067  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
4068}
4069
4070void
4071SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
4072{
4073  if(HwDeviceExtension->jChipType >= SIS_315H)
4074    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
4075  else
4076    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
4077}
4078
4079void
4080SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
4081{
4082  if(HwDeviceExtension->jChipType >= SIS_315H)
4083    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
4084  else
4085     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
4086}
4087
4088void
4089SiS_EnableCRT2(SiS_Private *SiS_Pr)
4090{
4091  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4092}
4093
4094/* Checked against all BIOSes */
4095void
4096SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
4097{
4098  USHORT tempah,pushax,temp=0;
4099  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
4100
4101  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
4102
4103      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
4104
4105        if(HwDeviceExtension->jChipType < SIS_315H) {
4106
4107	   /* 300 series */
4108
4109	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
4110	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
4111	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4112	   }
4113	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
4114	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4115	      SiS_ShortDelay(SiS_Pr,1);
4116	   }
4117	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4118	   SiS_DisplayOff(SiS_Pr);
4119	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4120	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4121	   SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
4122	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4123	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4124	   if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) ||
4125	              (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
4126	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4127              SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
4128	   }
4129
4130        } else {
4131
4132	   /* 310 series */
4133
4134#ifdef SIS650301NEW      /* From 650/301LVx 1.10.6s */
4135	   if(!(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4136	       tempah = 0xef;
4137	       if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4138	           tempah = 0xf7;
4139               }
4140	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4141	   }
4142
4143	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
4144
4145	   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4146	     	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
4147	   } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4148		   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
4149           }
4150
4151	   SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
4152
4153           pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
4154
4155	   SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4156
4157           if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4158
4159	       SiS_DisplayOff(SiS_Pr);
4160	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4161	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4162	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4163
4164	   } else {
4165
4166              SiS_DisplayOff(SiS_Pr);
4167	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4168	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4169	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4170	      temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
4171              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4172	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4173	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
4174
4175	   }
4176
4177	   tempah = 0x3f;
4178	   if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4179	      tempah = 0x7f;
4180	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4181		  tempah = 0xbf;
4182              }
4183	   }
4184	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4185
4186	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4187
4188	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4189	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4190	   }
4191
4192	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4193	      if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) {
4194	         if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4195		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4196                 }
4197              }
4198	   }
4199
4200	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
4201
4202#else	    /* TW: From 650/301LV BIOS */
4203
4204	   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4205	     	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
4206		   SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4207	   } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4208		   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
4209		   SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4210           }
4211
4212           /* TW: 301B dependent code starts here in 650/301LV BIOS */
4213	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
4214	     tempah = 0x3f;
4215             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4216           }
4217
4218           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4219	   SiS_DisplayOff(SiS_Pr);
4220
4221
4222           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4223
4224           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4225
4226	   temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
4227           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4228	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4229	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
4230
4231	   /* TW: Inserted from 650/301LV BIOS */
4232	   if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4233	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4234	           if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4235		          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4236			  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4237			  SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 4);
4238                   } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4239                          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4240			  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4241			  SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 4);
4242		   }
4243	       }
4244	    } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4245	       if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) {
4246	            SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
4247		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4248		    SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
4249               } else if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4250	           if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4251		          SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
4252			  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4253			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
4254                   } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4255                          SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
4256			  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4257			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
4258		   }
4259	       }
4260	   } /* TW: 650/301LV end */
4261#endif
4262
4263	}
4264
4265      } else {     /* ============ TW: For 301 ================ */
4266
4267        if(HwDeviceExtension->jChipType < SIS_315H) {
4268            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4269                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
4270	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
4271	    }
4272	}
4273
4274        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4275        SiS_DisplayOff(SiS_Pr);
4276
4277        if(HwDeviceExtension->jChipType >= SIS_315H) {
4278            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4279	}
4280
4281        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4282
4283	if(HwDeviceExtension->jChipType >= SIS_315H) {
4284            temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
4285            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4286	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4287	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
4288	} else {
4289            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4290	}
4291
4292      }
4293
4294  } else {     /* ============ TW: For LVDS =============*/
4295
4296    if(HwDeviceExtension->jChipType < SIS_315H) {
4297
4298	/* 300 series */
4299
4300	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4301#if 0	/* TW: Implemented this for power saving, but it's not worth
4302         *     the problems
4303	 */
4304	    if(SiS_Pr->SiS_Backup70xx == 0xff) {
4305		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr,0x0e);
4306	    }
4307#endif
4308	    SiS_SetCH700x(SiS_Pr,0x090E);
4309	}
4310
4311	if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4312
4313	    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4314
4315	        if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
4316
4317                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4318
4319		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4320		         SiS_DisplayOff(SiS_Pr);
4321	             }
4322
4323	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
4324	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4325                }
4326            }
4327	}
4328
4329	SiS_DisplayOff(SiS_Pr);
4330
4331	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4332
4333	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4334	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
4335	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4336	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4337
4338	if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) ||
4339	              (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
4340		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4341		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
4342	}
4343
4344    } else {
4345
4346	/* 310 series */
4347
4348	if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4349		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4350			SiS_Chrontel701xBLOff(SiS_Pr);
4351			SiS_Chrontel701xOff(SiS_Pr);
4352		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4353			SiS_Chrontel701xBLOff(SiS_Pr);
4354			SiS_Chrontel701xOff(SiS_Pr);
4355		}
4356
4357		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4358			SiS_SetCH701x(SiS_Pr,0x0149);
4359		} else if(SiS_IsTVOrYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr))  {
4360			SiS_SetCH701x(SiS_Pr,0x0149);
4361		}
4362	}
4363
4364	if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4365		SiS_DisplayOff(SiS_Pr);
4366	} else if(!(SiS_IsTVOrYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4367		SiS_DisplayOff(SiS_Pr);
4368	}
4369
4370	if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4371		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4372	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4373		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4374	}
4375
4376	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4377
4378	if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4379		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4380	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4381		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4382	}
4383
4384	if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4385		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4386	}
4387
4388	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4389		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
4390	} else {
4391		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4392	}
4393
4394	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
4395
4396	if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4397		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4398	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4399		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4400	}
4401
4402
4403    }  /* 310 series */
4404
4405  }  /* LVDS */
4406
4407}
4408
4409/* TW: Checked against all BIOSes */
4410void
4411SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
4412{
4413  USHORT temp=0,tempah,pushax,temp1;
4414  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
4415
4416  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
4417
4418    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
4419
4420      if(HwDeviceExtension->jChipType < SIS_315H) {
4421
4422         /* 300 series */
4423
4424	 if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4425	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
4426	    if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
4427	       SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
4428	    }
4429	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
4430/*	    DoSomeThingPCI_On(SiS_Pr) */
4431            SiS_DisplayOn(SiS_Pr);
4432	    SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
4433	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4434	    if(SiS_BridgeInSlave(SiS_Pr)) {
4435      		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4436      	    } else {
4437      		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4438            }
4439	    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4440	        if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4441		    if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
4442		        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
4443                    }
4444		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4445                    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
4446                }
4447	    }
4448         } else {
4449	   temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4450           if(SiS_BridgeInSlave(SiS_Pr)) {
4451              tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
4452              if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4453           }
4454           SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
4455	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4456	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4457	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
4458              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4459	      SiS_DisplayOn(SiS_Pr);
4460	   } else {
4461	      SiS_VBLongWait(SiS_Pr);
4462	      SiS_DisplayOn(SiS_Pr);
4463	      SiS_VBLongWait(SiS_Pr);
4464	   }
4465	 }
4466
4467      } else {
4468
4469         /* 310 series */
4470
4471#ifdef SIS650301NEW       /* TW: From 650/301LVx 1.10.6s */
4472
4473         if(!(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4474	       tempah = 0x10;
4475	       if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4476	           tempah = 0x08;
4477               }
4478	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4479	 }
4480
4481	 SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
4482
4483	 SiS_DisplayOff(SiS_Pr);
4484
4485	 pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
4486
4487	 if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
4488	     (SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) ) {
4489             if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4490	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4491		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4492		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4493	     }
4494	 }
4495
4496	 if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4497             temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4498	     if(SiS_BridgeInSlave(SiS_Pr)) {
4499                tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
4500                if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4501             }
4502             SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
4503
4504	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4505	     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
4506	 }
4507
4508	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4509	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4510	 }
4511
4512	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4513
4514	 tempah = 0xc0;
4515	 if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4516	     tempah = 0x80;
4517	     if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4518	        tempah = 0x40;
4519             }
4520	 }
4521         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4522
4523	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4524
4525	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4526	    if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
4527	        ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) ) {
4528		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4529		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4530		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4531		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4532		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4533		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4534		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4535		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4536		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4537		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
4538                SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4539		SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
4540	    }
4541	 }
4542
4543	 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
4544	 SiS_DisplayOn(SiS_Pr);
4545	 SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
4546
4547	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4548	     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4549	 }
4550
4551         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
4552	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4553	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4554	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
4555	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
4556	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);
4557	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
4558	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4559
4560#else	 /* TW: From 650/301LV BIOS (different PanelDelay!) */
4561
4562	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4563	     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfd,0x02);
4564	     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
4565	 } else if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4566	     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfd,0x02);
4567	     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
4568	 }
4569	 /* TW: --- end --- */
4570
4571         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4572            temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4573	    if(SiS_BridgeInSlave(SiS_Pr)) {
4574               tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
4575               if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4576            }
4577            SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
4578
4579	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4580
4581/*          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0x7F);   */ 	/* TW: Not done in 650/301LV BIOS */
4582            temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
4583            if (!(temp & 0x80))
4584                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4585          }
4586
4587          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4588
4589          if(SiS_Is301B(SiS_Pr,BaseAddr)) {
4590
4591             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xc0);
4592
4593             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)))   /* TW: "if" new from 650/301LV BIOS */
4594	        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
4595
4596          } else {
4597
4598             SiS_VBLongWait(SiS_Pr);
4599             SiS_DisplayOn(SiS_Pr);
4600	     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)))  {  /* TW: "if" new from 650/301LV BIOS */
4601	        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
4602                SiS_VBLongWait(SiS_Pr);
4603	     }
4604
4605          }
4606
4607	  /* TW: Entire section from 650/301LV BIOS */
4608	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4609	     if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4610/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
4611		   SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
4612		   SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4613		   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x01);
4614/*              }   */
4615             } else if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4616/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
4617		   SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
4618		   SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4619		   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x01);
4620/*              }   */
4621	     }
4622	  }
4623
4624#endif
4625
4626      }
4627
4628    } else {	/* ============  TW: For 301 ================ */
4629
4630       if(HwDeviceExtension->jChipType < SIS_315H) {
4631            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4632                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
4633	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
4634	    }
4635       }
4636
4637       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4638       if(SiS_BridgeInSlave(SiS_Pr)) {
4639         tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
4640         if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
4641       }
4642       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
4643
4644       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4645
4646       if(HwDeviceExtension->jChipType >= SIS_315H) {
4647         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
4648         if(!(temp & 0x80))
4649           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4650       }
4651
4652       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4653
4654       SiS_VBLongWait(SiS_Pr);
4655       SiS_DisplayOn(SiS_Pr);
4656       if(HwDeviceExtension->jChipType >= SIS_315H) {
4657           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4658       }
4659       SiS_VBLongWait(SiS_Pr);
4660
4661       if(HwDeviceExtension->jChipType < SIS_315H) {
4662            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4663	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
4664                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
4665	    }
4666       }
4667
4668    }
4669
4670  } else {   /* =================== TW: For LVDS ================== */
4671
4672    if(HwDeviceExtension->jChipType < SIS_315H) {
4673
4674      /* 300 series */
4675
4676      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4677         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
4678	 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
4679	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
4680	 }
4681      }
4682
4683      SiS_EnableCRT2(SiS_Pr);
4684      SiS_DisplayOn(SiS_Pr);
4685      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
4686      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4687      if(SiS_BridgeInSlave(SiS_Pr)) {
4688      	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4689      } else {
4690      	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4691      }
4692
4693      if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4694        if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) {
4695#if 0	/* TW: Implemented this for power saving, but it's not worth
4696         *     the problems
4697	 */
4698           if(SiS_Pr->SiS_Backup70xx != 0xff) {
4699		SiS_SetCH700x(SiS_Pr,((SiS_Pr->SiS_Backup70xx<<8)|0x0E));
4700		SiS_Pr->SiS_Backup70xx = 0xff;
4701	   } else
4702#endif
4703	        SiS_SetCH700x(SiS_Pr,0x0B0E);
4704        }
4705      }
4706
4707      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) {
4708          if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4709              if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4710	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
4711			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
4712        		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
4713		  }
4714		  SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4715                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
4716              }
4717	  }
4718      }
4719
4720    } else {
4721
4722       /* 310 series */
4723
4724
4725       SiS_EnableCRT2(SiS_Pr);
4726       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
4727
4728       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4729
4730       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4731          temp = SiS_GetCH701x(SiS_Pr,0x66);
4732	  temp &= 0x20;
4733	  SiS_Chrontel701xBLOff(SiS_Pr);
4734       }
4735
4736       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4737
4738       temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
4739       if (!(temp1 & 0x80))
4740           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4741
4742       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4743           if(temp) {
4744	       SiS_Chrontel701xBLOn(SiS_Pr);
4745	   }
4746       }
4747
4748       if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4749           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4750       }
4751
4752       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4753           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4754       }
4755
4756       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4757
4758       		if(SiS_IsTVOrYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4759           		SiS_Chrontel701xOn(SiS_Pr,HwDeviceExtension, BaseAddr);
4760         	}
4761
4762         	if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4763           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
4764         	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4765           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
4766        	}
4767
4768       }
4769
4770       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4771       	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4772 	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
4773	            		SiS_Chrontel701xBLOn(SiS_Pr);
4774	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
4775           		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
4776/*	      			if(!SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {  */ /* TW: makes no sense */
4777            				SiS_Chrontel701xBLOn(SiS_Pr);
4778            				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
4779/*            			}   */
4780	   		}
4781       		}
4782       }
4783
4784    } /* 310 series */
4785
4786  }  /* LVDS */
4787
4788}
4789
4790void
4791SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4792{
4793  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
4794
4795  /* TW: Switch on LCD backlight on SiS30x */
4796  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
4797      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr)) ) {
4798    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4799	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4800	SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
4801    }
4802    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
4803        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4804    }
4805  }
4806}
4807
4808void
4809SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4810{
4811  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
4812
4813  /* TW: Switch off LCD backlight on SiS30x */
4814  if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
4815      (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
4816	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
4817  }
4818
4819  if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4820      if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr))) {
4821          if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
4822  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
4823          }
4824      }
4825  }
4826}
4827
4828BOOLEAN
4829SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4830{
4831  USHORT temp,temp1;
4832  UCHAR *ROMAddr;
4833
4834  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
4835     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
4836     temp >>= 4;
4837     temp = 1 << temp;
4838     temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
4839     if(temp1 & temp) return(1);
4840     else return(0);
4841  } else {
4842     return(0);
4843  }
4844}
4845
4846BOOLEAN
4847SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4848{
4849  USHORT temp,temp1;
4850  UCHAR *ROMAddr;
4851
4852  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
4853     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
4854     temp >>= 4;
4855     temp = 1 << temp;
4856     temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
4857     if(temp1 & temp) return(1);
4858     else return(0);
4859  } else {
4860     return(0);
4861  }
4862}
4863
4864void
4865SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
4866                  USHORT DelayTime)
4867{
4868  USHORT PanelID, DelayIndex, Delay, temp;
4869
4870  if(HwDeviceExtension->jChipType < SIS_315H) {
4871
4872      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 300 series, LVDS */
4873
4874	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
4875
4876	  DelayIndex = PanelID >> 4;
4877
4878	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
4879              Delay = 3;
4880          } else {
4881              if(DelayTime >= 2) DelayTime -= 2;
4882
4883              if(!(DelayTime & 0x01)) {
4884       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
4885              } else {
4886       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
4887              }
4888	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
4889                  if(ROMAddr[0x220] & 0x40) {
4890                      if(!(DelayTime & 0x01)) {
4891	    	          Delay = (USHORT)ROMAddr[0x225];
4892                      } else {
4893	    	          Delay = (USHORT)ROMAddr[0x226];
4894                      }
4895                  }
4896              }
4897          }
4898	  SiS_ShortDelay(SiS_Pr,Delay);
4899
4900      } else {							/* 300 series, 301(B) */
4901
4902	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
4903	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
4904          if(!(temp & 0x10))  PanelID = 0x12;
4905
4906          DelayIndex = PanelID >> 4;
4907
4908	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
4909              Delay = 3;
4910          } else {
4911              if(DelayTime >= 2) DelayTime -= 2;
4912
4913              if(!(DelayTime & 0x01)) {
4914       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
4915              } else {
4916       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
4917              }
4918	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
4919                  if(ROMAddr[0x220] & 0x40) {
4920                      if(!(DelayTime & 0x01)) {
4921	    	          Delay = (USHORT)ROMAddr[0x225];
4922                      } else {
4923	    	          Delay = (USHORT)ROMAddr[0x226];
4924                      }
4925                  }
4926              }
4927          }
4928	  SiS_ShortDelay(SiS_Pr,Delay);
4929
4930      }
4931
4932   } else {
4933
4934      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
4935
4936          /* TW: Not currently used */
4937
4938      } else {							/* 310/325 series, 301(B) */
4939
4940          PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
4941	  DelayIndex = PanelID >> 4;
4942          if(!(DelayTime & 0x01)) {
4943       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
4944          } else {
4945       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
4946          }
4947	  SiS_DDC2Delay(SiS_Pr, Delay * 4);
4948
4949      }
4950
4951   }
4952
4953}
4954
4955void
4956SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
4957{
4958  while(delay--) {
4959    SiS_GenericDelay(SiS_Pr,0x19df);
4960  }
4961}
4962
4963void
4964SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
4965{
4966  while(delay--) {
4967      SiS_GenericDelay(SiS_Pr,0x42);
4968  }
4969}
4970
4971void
4972SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
4973{
4974  USHORT temp,flag;
4975
4976  flag = SiS_GetReg3(0x61) & 0x10;
4977
4978  while(delay) {
4979      temp = SiS_GetReg3(0x61) & 0x10;
4980      if(temp == flag) continue;
4981      flag = temp;
4982      delay--;
4983  }
4984}
4985
4986BOOLEAN
4987SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr)
4988{
4989  USHORT flag;
4990
4991  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
4992  if(flag >= 0x0B0) return(1);
4993  else return(0);
4994}
4995
4996BOOLEAN
4997SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr)
4998{
4999  USHORT flag;
5000
5001  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5002  if(flag & 0x20) return(1);
5003  else return(0);
5004}
5005
5006BOOLEAN
5007SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5008{
5009#ifdef SIS315H
5010  USHORT flag;
5011
5012  if(HwDeviceExtension->jChipType >= SIS_315H) {
5013     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5014     if(flag & EnableDualEdge)  return(1);
5015     else  return(0);
5016  } else
5017#endif
5018     return(0);
5019}
5020
5021BOOLEAN
5022SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5023{
5024#ifdef SIS315H
5025  USHORT flag;
5026
5027  if(HwDeviceExtension->jChipType >= SIS_315H) {
5028     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5029     if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
5030     else
5031       return(0);
5032  } else
5033#endif
5034     return(0);
5035 }
5036
5037BOOLEAN
5038SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5039{
5040#ifdef SIS315H
5041  USHORT flag;
5042
5043  if(HwDeviceExtension->jChipType >= SIS_315H) {
5044     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
5045     if(flag & 0x10)  return(1);
5046     else             return(0);
5047  } else
5048#endif
5049     return(0);
5050 }
5051
5052
5053BOOLEAN
5054SiS_IsM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5055{
5056#ifdef SIS315H
5057  USHORT flag;
5058
5059  if(HwDeviceExtension->jChipType >= SIS_315H) {
5060     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
5061     flag &= 0xF0;
5062     if((flag == 0xb0) || (flag == 0x90)) return 0;
5063     else return 1;
5064  } else
5065#endif
5066    return 1;
5067}
5068
5069BOOLEAN
5070SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5071{
5072#ifdef SIS315H
5073  USHORT flag;
5074
5075  if(HwDeviceExtension->jChipType >= SIS_315H) {
5076     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5077     if(flag & 0x08)  return(1);
5078     else      	      return(0);
5079  } else
5080#endif
5081     return(0);
5082}
5083
5084BOOLEAN
5085SiS_IsTVOrYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5086{
5087  USHORT flag;
5088
5089#ifdef SIS315H
5090  if(HwDeviceExtension->jChipType >= SIS_315H) {
5091     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5092     if(flag & SetCRT2ToTV) return(1);
5093     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5094     if(flag & 0x08)        return(1);
5095     else                   return(0);
5096  } else
5097#endif
5098  {
5099     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5100     if(flag & SetCRT2ToTV) return(1);
5101  }
5102  return(0);
5103}
5104
5105BOOLEAN
5106SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
5107{
5108  USHORT flag;
5109
5110#ifdef SIS315H
5111  if(HwDeviceExtension->jChipType >= SIS_315H) {
5112     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5113     if(flag & SetCRT2ToLCD) return(1);
5114     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5115     if(flag & SetToLCDA)    return(1);
5116     else                    return(0);
5117  } else
5118#endif
5119  {
5120   flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5121   if(flag & SetCRT2ToLCD)   return(1);
5122  }
5123  return(0);
5124
5125}
5126
5127BOOLEAN
5128SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr)
5129{
5130  USHORT flag;
5131
5132  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
5133  if(flag & 0x20) return(0);
5134  else            return(1);
5135}
5136
5137BOOLEAN
5138SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
5139{
5140  USHORT flag;
5141
5142  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
5143     return(0);   					/* TW: Changed from 1 to 0! */
5144  } else {
5145        flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
5146        if((flag == 1) || (flag == 2)) return(0);       /* TW: Changed from 1 to 0! */
5147        else return(1);                                 /* TW: Changed from 0 to 1! */
5148  }
5149}
5150
5151BOOLEAN
5152SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
5153{
5154  USHORT flag;
5155
5156  if(!(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension))) {
5157    flag = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
5158    if(HwDeviceExtension->jChipType < SIS_315H) {
5159      /* 300 series (630/301B 2.04.5a) */
5160      flag &= 0xa0;
5161      if((flag == 0x80) || (flag == 0x20)) return 0;
5162      else	                           return 1;
5163    } else {
5164      /* 310/325 series (650/301LVx 1.10.6s) */
5165      flag &= 0x50;
5166      if((flag == 0x40) || (flag == 0x10)) return 0;
5167      else                                 return 1;
5168    }
5169  }
5170  return 1;
5171}
5172
5173BOOLEAN
5174SiS_BridgeInSlave(SiS_Private *SiS_Pr)
5175{
5176  USHORT flag1;
5177
5178  flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
5179  if(flag1 & (SetInSlaveMode >> 8)) return 1;
5180  else return 0;
5181}
5182
5183/* TW: New from 650/301LV(x) 1.10.6s BIOS */
5184void
5185SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
5186{
5187  USHORT temp;
5188
5189  SiS_Pr->SiS_HiVision = 0;
5190  if(HwDeviceExtension->jChipType >= SIS_315H) {
5191     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
5192        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
5193	if(temp & 0x40) {
5194	    temp &= 0x30;
5195	    switch(temp) {
5196	      case 0x00: SiS_Pr->SiS_HiVision = 4; break;
5197	      case 0x10: SiS_Pr->SiS_HiVision = 1; break;
5198	      case 0x20: SiS_Pr->SiS_HiVision = 2; break;
5199	      default:   SiS_Pr->SiS_HiVision = 3; break;
5200	    }
5201	}
5202     }
5203  }
5204}
5205
5206/* TW: Checked against 630/LVDS 2.08, 650/LVDS and 650/301LV BIOS */
5207BOOLEAN
5208SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
5209                  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
5210{
5211  USHORT temp,modeflag,resinfo=0;
5212  const unsigned char SiS300SeriesLCDRes[] =
5213         { 0, 1, 2, 3, 7, 4, 5, 8,
5214	   0, 0, 0, 0, 0, 0, 0, 0 };
5215
5216  SiS_Pr->SiS_LCDResInfo = 0;
5217  SiS_Pr->SiS_LCDTypeInfo = 0;
5218  SiS_Pr->SiS_LCDInfo = 0;
5219
5220  if (ModeNo<=0x13) {
5221    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5222  } else {
5223    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5224    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5225  }
5226
5227  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
5228
5229  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
5230
5231  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
5232
5233  /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
5234  if(SiS_Pr->SiS_IF_DEF_FSTN){
5235   	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
5236   	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
5237  }
5238
5239  SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
5240  temp &= 0x0f;
5241  if(HwDeviceExtension->jChipType < SIS_315H) {
5242      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
5243      temp = SiS300SeriesLCDRes[temp];
5244  }
5245  SiS_Pr->SiS_LCDResInfo = temp;
5246
5247  if(SiS_Pr->SiS_IF_DEF_FSTN){
5248       	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
5249  }
5250
5251  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
5252    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
5253		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
5254  } else {
5255    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
5256		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
5257  }
5258
5259  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
5260  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
5261
5262  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
5263  if(SiS_Pr->SiS_IF_DEF_FSTN){
5264        /* TW: Fake LVDS bridge for FSTN */
5265      	temp = 0x04;
5266      	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
5267  }
5268  SiS_Pr->SiS_LCDInfo = temp;
5269
5270  /* TW: Inserted entire 315-block from 650/LVDS/301+LVx BIOSes */
5271  if(HwDeviceExtension->jChipType >= SIS_315H) {
5272     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
5273         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5274	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
5275		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
5276		     SiS_Pr->SiS_LCDInfo |= LCDNonExpanding;
5277		 }
5278	     }
5279	 }
5280     }
5281     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
5282         SiS_Pr->SiS_LCDInfo &= 0xFFEF;
5283	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
5284     }
5285  } else {
5286     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
5287        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
5288           if(!(ROMAddr[0x235] & 0x02)) {
5289	      SiS_Pr->SiS_LCDInfo &= 0xEF;
5290	   }
5291        }
5292     } else {
5293        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
5294	   if((SiS_Pr->SiS_SetFlag & CRT2IsVGA) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
5295               SiS_Pr->SiS_LCDInfo &= 0xEF;
5296	   }
5297	}
5298     }
5299  }
5300
5301#ifdef LINUX_KERNEL
5302  printk(KERN_INFO "sisfb: (LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
5303                   SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
5304#endif
5305#ifdef LINUX_XF86
5306  xf86DrvMsg(0, X_PROBED, "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
5307			SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
5308#endif
5309
5310  /* TW: With Trumpion, always Expanding */
5311  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
5312       SiS_Pr->SiS_LCDInfo &= (~LCDNonExpanding);
5313  }
5314
5315  if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & CRT2IsVGA))) {
5316
5317     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
5318        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
5319	   if(ModeNo > 0x13) {
5320	      if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
5321                 if((resinfo == 7) || (resinfo == 3)) {
5322                    SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
5323		 }
5324              }
5325           }
5326        }
5327	if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5328	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
5329	}
5330     }
5331
5332     if(modeflag & HalfDCLK) {
5333        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
5334           if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
5335	      if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwDeviceExtension->jChipType < SIS_315H)) &&
5336	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
5337                 if(ModeNo > 0x13) {
5338                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
5339                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
5340                    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
5341                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
5342                    }
5343                 }
5344	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
5345           } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
5346        } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
5347     }
5348
5349  }
5350
5351  /* TW: wdr: if (VBInfo & LCD) && (VBInfo & (SetSimuScanMode | SwitchToCRT2)) { */
5352  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
5353    	if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
5354      		SiS_Pr->SiS_SetFlag |= LCDVESATiming;
5355    	}
5356  } else {
5357    	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
5358  }
5359
5360  /* TW: Inserted from 650/301LVx BIOS 1.10.6s */
5361  if(SiS_Pr->SiS_VBType & VB_SIS30xNEW) {
5362      temp = 0x00;
5363      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
5364      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
5365      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
5366      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
5367  } else if((HwDeviceExtension->jChipType > SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
5368      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
5369  }
5370
5371  return 1;
5372}
5373
5374void
5375SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
5376{
5377  return;
5378  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
5379  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
5380  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
5381  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
5382  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
5383  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
5384  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
5385}
5386
5387void
5388SiS_LongWait(SiS_Private *SiS_Pr)
5389{
5390  USHORT i;
5391
5392  i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);
5393
5394  if(!(i & 0xC0)) {
5395    for(i=0; i<0xFFFF; i++) {
5396       if(!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
5397         break;
5398    }
5399    for(i=0; i<0xFFFF; i++) {
5400       if((SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
5401         break;
5402    }
5403  }
5404}
5405
5406void
5407SiS_VBLongWait(SiS_Private *SiS_Pr)
5408{
5409  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5410    SiS_VBWait(SiS_Pr);
5411  } else {
5412    SiS_LongWait(SiS_Pr);
5413  }
5414  return;
5415}
5416
5417void
5418SiS_VBWait(SiS_Private *SiS_Pr)
5419{
5420  USHORT tempal,temp,i,j;
5421
5422  temp = 0;
5423  for(i=0; i<3; i++) {
5424    for(j=0; j<100; j++) {
5425       tempal = SiS_GetReg2(SiS_Pr->SiS_P3da);
5426       if(temp & 0x01) {
5427          if((tempal & 0x08))  continue;
5428          if(!(tempal & 0x08)) break;
5429       } else {
5430          if(!(tempal & 0x08)) continue;
5431          if((tempal & 0x08))  break;
5432       }
5433    }
5434    temp ^= 0x01;
5435  }
5436}
5437
5438void
5439SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
5440{
5441  if(HwDeviceExtension->jChipType < SIS_315H) {
5442     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
5443        if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
5444     }
5445     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
5446        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
5447     } else {
5448        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
5449     }
5450  } else {
5451     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
5452        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
5453     } else {
5454        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
5455     }
5456  }
5457}
5458
5459void
5460SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
5461{
5462  USHORT i,watchdog;
5463
5464  if(HwDeviceExtension->jChipType >= SIS_315H) {
5465     if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
5466     watchdog = 65535;
5467     while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
5468     watchdog = 65535;
5469     while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
5470  } else {
5471     for(i=0; i<10; i++) {
5472        watchdog = 65535;
5473        while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
5474	if(watchdog) break;
5475     }
5476     for(i=0; i<10; i++) {
5477        watchdog = 65535;
5478        while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
5479	if(watchdog) break;
5480     }
5481  }
5482}
5483
5484void
5485SiS_WaitRetraceDDC(SiS_Private *SiS_Pr)
5486{
5487  USHORT watchdog;
5488
5489  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
5490  watchdog = 65535;
5491  while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
5492  watchdog = 65535;
5493  while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
5494}
5495
5496void
5497SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
5498{
5499  USHORT i,watchdog,temp;
5500
5501  if(HwDeviceExtension->jChipType >= SIS_315H) {
5502     watchdog = 65535;
5503     while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02) && --watchdog);
5504     watchdog = 65535;
5505     while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02)) && --watchdog);
5506  } else {
5507     for(i=0; i<10; i++) {
5508        watchdog = 65535;
5509	while( (temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02) && --watchdog);
5510	if(watchdog) break;
5511     }
5512     for(i=0; i<10; i++) {
5513        watchdog = 65535;
5514	while( (!(temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02)) && --watchdog);
5515	if(watchdog) break;
5516     }
5517  }
5518}
5519
5520/* =========== Set and Get register routines ========== */
5521
5522void
5523SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR)
5524{
5525  USHORT temp;
5526
5527  temp = SiS_GetReg1(Port,Index);     /* SiS_Pr->SiS_Part1Port index 02 */
5528  temp = (temp & (DataAND)) | DataOR;
5529  SiS_SetReg1(Port,Index,temp);
5530}
5531
5532void
5533SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND)
5534{
5535  USHORT temp;
5536
5537  temp = SiS_GetReg1(Port,Index);     /* SiS_Pr->SiS_Part1Port index 02 */
5538  temp &= DataAND;
5539  SiS_SetReg1(Port,Index,temp);
5540}
5541
5542void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR)
5543{
5544  USHORT temp;
5545
5546  temp = SiS_GetReg1(Port,Index);     /* SiS_Pr->SiS_Part1Port index 02 */
5547  temp |= DataOR;
5548  SiS_SetReg1(Port,Index,temp);
5549}
5550
5551/* ========================================================= */
5552
5553/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
5554/* TW: Checked against 650/301LV, 650/301LVx and 630/301B (I+II) */
5555void
5556SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
5557              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
5558	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
5559{
5560  USHORT      i, j, tempax, tempbx, tempcx, temp, temp1;
5561  USHORT      push1, push2;
5562  const       UCHAR *PhasePoint;
5563  const       UCHAR *TimingPoint;
5564  const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
5565  USHORT      modeflag, resinfo, crt2crtc, resindex, CRT2Index;
5566  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
5567  const UCHAR atable[] = {
5568                 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
5569	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
5570  };
5571
5572  /* TW: Inserted from 650/301LV BIOS */
5573  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5574     /* TW: Inserted from 650/301LVx 1.10.6s: (Is at end of SetGroup2!) */
5575     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5576        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
5577	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
5578	   temp = 1;
5579	   if(ModeNo<=0x13) temp = 3;
5580	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
5581	}
5582     }
5583     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
5584       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5585         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
5586           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
5587               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
5588	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
5589	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
5590	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
5591	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
5592	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
5593	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
5594	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
5595	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
5596	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
5597	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
5598	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
5599	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
5600	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
5601	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
5602	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
5603	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
5604	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
5605	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
5606	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
5607	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
5608	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
5609           }
5610         }
5611       }
5612     }
5613     return;
5614  }
5615
5616  if(ModeNo<=0x13) {
5617    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
5618    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5619    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5620  } else {
5621    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
5622    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5623    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5624  }
5625
5626  tempcx = SiS_Pr->SiS_VBInfo;
5627  tempax = (tempcx & 0x00FF) << 8;
5628  tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
5629  tempbx &= 0x0410;
5630  temp = (tempax & 0x0800) >> 8;
5631  temp >>= 1;
5632  temp |= (((tempbx & 0xFF00) >> 8) << 1);
5633  temp |= ((tempbx & 0x00FF) >> 3);
5634  temp ^= 0x0C;
5635
5636  PhasePoint  = SiS_Pr->SiS_PALPhase;
5637  TimingPoint = SiS_Pr->SiS_PALTiming;
5638#ifdef oldHV
5639  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          /* PALPhase */
5640    temp ^= 0x01;
5641    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
5642      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
5643      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
5644        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
5645        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
5646      }
5647    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
5648  } else {
5649#endif
5650    if(SiS_Pr->SiS_VBInfo & SetPALTV){
5651
5652      TimingPoint = SiS_Pr->SiS_PALTiming;
5653      PhasePoint  = SiS_Pr->SiS_PALPhase;
5654
5655      if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
5656          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
5657	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
5658         PhasePoint = SiS_Pr->SiS_PALPhase2;
5659      }
5660
5661    } else {
5662
5663        temp |= 0x10;
5664	TimingPoint = SiS_Pr->SiS_NTSCTiming;
5665	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
5666
5667        if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
5668	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
5669	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
5670        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
5671        }
5672
5673    }
5674#ifdef oldHV
5675  }
5676#endif
5677  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
5678
5679  temp = 0;
5680  if((HwDeviceExtension->jChipType == SIS_630)||
5681     (HwDeviceExtension->jChipType == SIS_730)) {
5682     temp = 0x35;
5683  }
5684  if(HwDeviceExtension->jChipType >= SIS_315H) {
5685     temp = 0x38;
5686  }
5687  if(temp) {
5688    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5689      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
5690          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
5691          if(temp1 & 0x40) {
5692              	PhasePoint = SiS_Pr->SiS_PALMPhase;
5693		if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
5694		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
5695		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
5696	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
5697		}
5698	  }
5699          if(temp1 & 0x80) {
5700               	PhasePoint = SiS_Pr->SiS_PALNPhase;
5701		if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
5702		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
5703		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
5704	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
5705		}
5706	  }
5707      }
5708    }
5709  }
5710
5711#ifdef SIS315H
5712  /* TW: Inserted from 650/301LV BIOS */
5713  if(HwDeviceExtension->jChipType >= SIS_315H) {
5714     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  /* 650/301LV : 301LV | 302LV */
5715        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5716           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
5717              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
5718	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
5719	      }
5720           }
5721        }
5722     }
5723  }
5724#endif
5725
5726  for(i=0x31, j=0; i<=0x34; i++, j++){
5727     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
5728  }
5729
5730  for(i=0x01, j=0; i<=0x2D; i++, j++){
5731     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
5732  }
5733  for(i=0x39; i<=0x45; i++, j++){
5734     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
5735  }
5736
5737  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5738    if(HwDeviceExtension->jChipType >= SIS_315H) {
5739      if(!(SiS_Pr->SiS_ModeType & 0x07))
5740        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
5741    } else {
5742      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
5743    }
5744  }
5745
5746  SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
5747
5748  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
5749  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
5750  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
5751  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
5752
5753#ifdef oldHV
5754  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) tempax = 950;
5755  else {
5756#endif
5757    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
5758    else tempax = 440;
5759#ifdef oldHV
5760  }
5761#endif
5762
5763  if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
5764      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_HiVision != 3) &&
5765        ( (SiS_Pr->SiS_VGAHDE == 1024) || ((SiS_Pr->SiS_VGAHDE != 1024) && (SiS_Pr->SiS_VDE <= tempax)) ) ) ) {
5766
5767     tempax -= SiS_Pr->SiS_VDE;
5768     tempax >>= 2;
5769     tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
5770
5771     temp = (tempax & 0xFF00) >> 8;
5772     temp += (USHORT)TimingPoint[0];
5773     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
5774
5775     temp = (tempax & 0xFF00) >> 8;
5776     temp += (USHORT)TimingPoint[1];
5777     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
5778
5779     if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
5780        (SiS_Pr->SiS_HiVision != 3) &&
5781        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
5782        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
5783           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
5784           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
5785        } else {
5786           if(HwDeviceExtension->jChipType >= SIS_315H) {
5787             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
5788             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
5789	   } else {
5790             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
5791             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
5792	   }
5793        }
5794     }
5795
5796  }
5797
5798  tempcx = SiS_Pr->SiS_HT;
5799
5800  /* TW: Inserted from 650/301LVx 1.10.6s */
5801  if(HwDeviceExtension->jChipType >= SIS_315H) {
5802      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
5803      	   tempcx >>= 1;
5804      }
5805  }
5806
5807  tempcx--;
5808  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
5809        tempcx--;
5810  }
5811  temp = tempcx & 0x00FF;
5812  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1B,temp);
5813  temp = (tempcx & 0xFF00) >> 8;
5814  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
5815
5816  tempcx++;
5817  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
5818        tempcx++;
5819  }
5820  tempcx >>= 1;
5821
5822  push1 = tempcx;
5823
5824  tempcx += 7;
5825#ifdef oldHV
5826  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4;
5827#endif
5828  temp = (tempcx & 0x00FF) << 4;
5829  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
5830
5831  tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
5832  tempbx += tempcx;
5833
5834  push2 = tempbx;
5835
5836  temp = tempbx & 0x00FF;
5837  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,temp);
5838  temp = ((tempbx & 0xFF00) >> 8) << 4;
5839  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
5840
5841  tempbx = push2;
5842
5843  tempbx += 8;
5844#ifdef oldHV
5845  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
5846    tempbx -= 4;
5847    tempcx = tempbx;
5848  }
5849#endif
5850  temp = (tempbx & 0x00FF) << 4;
5851  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
5852
5853  j += 2;
5854  tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
5855  temp = tempcx & 0x00FF;
5856  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,temp);
5857  temp = ((tempcx & 0xFF00) >> 8) << 4;
5858  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
5859
5860  tempcx += 8;
5861#ifdef oldHV
5862  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4;
5863#endif
5864  temp = (tempcx & 0xFF) << 4;
5865  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
5866
5867  tempcx = push1;
5868
5869  j += 2;
5870  tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
5871  temp = (tempcx & 0x00FF) << 4;
5872  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
5873
5874  tempcx -= 11;
5875  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5876    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
5877    tempcx = tempax;
5878  }
5879  temp = tempcx & 0x00FF;
5880  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
5881
5882  tempbx = SiS_Pr->SiS_VDE;
5883  if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
5884  if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
5885  if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
5886  if(HwDeviceExtension->jChipType < SIS_315H) {
5887  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
5888  } else {
5889	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
5890	   tempbx >>= 1;
5891	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
5892	      if(ModeNo <= 0x13) {
5893	         if(crt2crtc == 1) {
5894	            tempbx++;
5895                 }
5896	      }
5897	   } else {
5898              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
5899	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
5900                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
5901	      }
5902	   }
5903        }
5904  }
5905  tempbx -= 2;
5906  temp = tempbx & 0x00FF;
5907#ifdef oldHV
5908  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
5909    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
5910      if(ModeNo == 0x2f) temp++;
5911    }
5912  }
5913#endif
5914  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2F,temp);
5915
5916  tempax = (tempcx & 0xFF00) | (tempax & 0x00FF);
5917  tempbx = ((tempbx & 0xFF00) << 6) | (tempbx & 0x00FF);
5918  tempax |= (tempbx & 0xFF00);
5919#ifdef oldHV
5920  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
5921#endif
5922    if(HwDeviceExtension->jChipType < SIS_315H) {
5923      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
5924         tempax |= 0x1000;
5925         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
5926      }
5927    } else {
5928      tempax |= 0x1000;
5929      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
5930    }
5931#ifdef oldHV
5932  }
5933#endif
5934  temp = (tempax & 0xFF00) >> 8;
5935  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
5936
5937  /* TW: Inserted from 650/301LVx 1.10.6s */
5938  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5939     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
5940         (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
5941         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
5942     }
5943  }
5944
5945  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {      /* tv gatingno */
5946    tempbx = SiS_Pr->SiS_VDE;
5947    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
5948         tempbx >>= 1;
5949    }
5950    tempbx -= 3;
5951    tempbx &= 0x03ff;
5952    temp = ((tempbx & 0xFF00) >> 8) << 5;
5953    temp |= 0x18;
5954    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
5955    temp = tempbx & 0x00FF;
5956    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);
5957    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: Inserted from 650/301LVx 1.10.6s */
5958       tempax = 0;
5959       if(SiS_Pr->SiS_HiVision & 0x07) {
5960          if(SiS_Pr->SiS_HiVision & 0x04) tempax = 0x1000;
5961          else if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x3000;
5962	  else tempax = 0x5000;
5963       }
5964       temp = (tempax & 0xFF00) >> 8;
5965       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
5966    }
5967  }
5968
5969  tempbx &= 0x00FF;
5970  if(!(modeflag & HalfDCLK)) {
5971    tempcx = SiS_Pr->SiS_VGAHDE;
5972    if(tempcx >= SiS_Pr->SiS_HDE){
5973      tempbx |= 0x2000;
5974      tempax &= 0x00FF;
5975    }
5976  }
5977
5978  tempcx = 0x0101;
5979  if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {   /*301b- TW: BIOS BUG? */
5980    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
5981      if(SiS_Pr->SiS_VGAHDE >= 1024) {
5982        if(!(modeflag & HalfDCLK)) {   /* TW: This check not in 630/301B */
5983          tempcx = 0x1920;
5984          if(SiS_Pr->SiS_VGAHDE >= 1280) {
5985            tempcx = 0x1420;
5986            tempbx &= 0xDFFF;
5987          }
5988        }
5989      }
5990    }
5991  }
5992
5993  if(!(tempbx & 0x2000)){
5994
5995    if(modeflag & HalfDCLK) {
5996         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
5997    }
5998    push1 = tempbx;
5999    tempeax = SiS_Pr->SiS_VGAHDE;
6000    tempebx = (tempcx & 0xFF00) >> 8;
6001    longtemp = tempeax * tempebx;
6002    tempecx = tempcx & 0x00FF;
6003    longtemp /= tempecx;
6004    longtemp <<= 0x0d;
6005    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6006     	longtemp <<= 3;
6007    }
6008    tempecx = SiS_Pr->SiS_HDE;
6009    temp2 = longtemp % tempecx;
6010    tempeax = longtemp / tempecx;
6011    if(temp2 != 0) tempeax++;
6012    tempax = (USHORT)tempeax;
6013    tempbx = push1;
6014    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
6015    tempbx |= (tempax & 0x1F00);
6016    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
6017  }
6018
6019  temp = (tempax & 0xFF00) >> 8;
6020  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp);
6021  temp = (tempbx & 0xFF00) >> 8;
6022  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
6023
6024  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6025       temp = tempcx & 0x00FF;
6026       if(tempbx & 0x2000) temp = 0;
6027       temp |= 0x18;
6028       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
6029       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
6030             tempbx = 0x0382;    /* TW: BIOS; Was 0x0364; */
6031             tempcx = 0x007e;    /* TW: BIOS; Was 0x009c; */
6032       } else {
6033             tempbx = 0x0369;    /* TW: BIOS; Was 0x0346; */
6034             tempcx = 0x0061;    /* TW: BIOS; Was 0x0078; */
6035       }
6036       temp = (tempbx & 0x00FF) ;
6037       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
6038       temp = (tempcx & 0x00FF) ;
6039       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
6040       tempbx &= 0x0300;
6041       temp = (tempcx & 0xFF00) >> 8;
6042       temp = (temp & 0x0003) << 2;
6043       temp |= (tempbx >> 8);
6044       if(HwDeviceExtension->jChipType < SIS_315H) {
6045          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
6046       } else {
6047          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
6048       }
6049
6050       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
6051       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
6052  }
6053
6054  temp = 0;
6055  if((HwDeviceExtension->jChipType == SIS_630)||
6056     (HwDeviceExtension->jChipType == SIS_730)) {
6057     temp = 0x35;
6058  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
6059     temp = 0x38;
6060  }
6061  if(temp) {
6062      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6063          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
6064               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & 0x40) {
6065                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6066                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
6067                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
6068               }
6069          }
6070      }
6071  }
6072
6073
6074#ifdef oldHV
6075  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
6076    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6077      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6078    }
6079  }
6080#endif
6081
6082  if(HwDeviceExtension->jChipType < SIS_315H) {
6083     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  return;
6084  } else {
6085     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
6086     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6087       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
6088         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6089           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
6090             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
6091               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
6092	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
6093	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
6094	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
6095	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
6096	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
6097	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
6098	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
6099	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
6100	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
6101	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
6102	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
6103	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
6104	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
6105	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
6106	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
6107	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
6108	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
6109	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
6110	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
6111	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
6112	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
6113	     }
6114           }
6115         }
6116       }
6117       return;
6118     }
6119  }
6120
6121  /* TW: From here: Part2 LCD setup */
6122
6123  tempbx = SiS_Pr->SiS_HDE;
6124  /* TW: Inserted from 650/301LVx 1.10.6s */
6125  if(HwDeviceExtension->jChipType >= SIS_315H) {
6126      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
6127  }
6128  tempbx--;			         /* RHACTE=HDE-1 */
6129  temp = tempbx & 0x00FF;
6130  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
6131  temp = (tempbx & 0xFF00) >> 8;
6132  temp <<= 4;
6133  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
6134
6135  temp = 0x01;
6136  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
6137    if(SiS_Pr->SiS_ModeType == ModeEGA) {
6138      if(SiS_Pr->SiS_VGAHDE >= 1024) {
6139        temp = 0x02;
6140	if(HwDeviceExtension->jChipType >= SIS_315H) {
6141           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6142             temp = 0x01;
6143	   }
6144	}
6145      }
6146    }
6147  }
6148  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
6149
6150  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
6151  push1 = tempbx;
6152
6153  tempbx--;
6154  temp = tempbx & 0x00FF;
6155  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
6156  temp = ((tempbx & 0xFF00) >> 8) & 0x07;
6157  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
6158
6159  tempcx = SiS_Pr->SiS_VT;
6160  push2 = tempcx;
6161
6162  tempcx--;
6163  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
6164  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
6165
6166  temp = (tempcx & 0xFF00) >> 8;
6167  temp <<= 5;
6168  if(HwDeviceExtension->jChipType < SIS_315H) {
6169    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
6170    else {
6171      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
6172         temp |= 0x10;
6173    }
6174  } else {
6175      /* TW: Inserted from 630/301LVx 1.10.6s */
6176      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6177         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6178      	    temp |= 0x10;
6179	 }
6180      }
6181  }
6182
6183  /* 630/301 does not do all this */
6184  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6185      if(HwDeviceExtension->jChipType >= SIS_315H) {
6186        /* TW: Inserted from 650/301LVx 1.10.6s */
6187        temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
6188      } else {
6189        tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
6190        if(tempbx & LCDSync) {
6191          tempbx &= (0xFF00 | LCDSyncBit);
6192          tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> LCDSyncShift);
6193          temp |= (tempbx & 0x00FF);
6194        }
6195      }
6196  }
6197  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
6198
6199  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6200  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6201
6202  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6203  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6204
6205  if(HwDeviceExtension->jChipType >= SIS_315H) {   /* ------------- 310 series ------------ */
6206
6207      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
6208
6209      SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
6210                         &CRT2Index,&resindex);
6211
6212      switch(CRT2Index) {
6213        case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
6214        case Panel_1280x1024     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
6215	case Panel_1400x1050     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
6216	case Panel_1600x1200     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
6217        case Panel_1024x768 + 16 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
6218        case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
6219	case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
6220	case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
6221        case Panel_1024x768 + 32 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
6222        case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
6223	case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
6224	case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
6225	default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
6226      }
6227
6228      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6229      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6230      for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6231        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6232      }
6233      for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6234        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6235      }
6236      for(j = 0x1f; j <= 0x21; i++, j++ ) {
6237        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6238      }
6239      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6240      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6241
6242      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6243        if(SiS_Pr->SiS_VGAVDE == 0x20d) {
6244	  temp = 0xc3;
6245	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6246	     temp++;
6247	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6248	  }
6249	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
6250	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6251	}
6252	if(SiS_Pr->SiS_VGAVDE == 0x1a4) {
6253	  temp = 0x4d;
6254	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6255	     temp++;
6256	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6257	  }
6258	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
6259	}
6260     }
6261
6262     /* TW: Inserted from 650/301LVx 1.10.6s: */
6263     /* !!! This is a duplicate, done for LCDA as well - see above */
6264     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6265        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
6266	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
6267	   temp = 1;
6268	   if(ModeNo<=0x13) temp = 3;
6269	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
6270	}
6271     }
6272
6273  } else {   /* ------------- 300 series ----------- */
6274
6275    tempcx++;
6276    tempbx = 768;
6277    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
6278      tempbx = 1024;
6279      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
6280         tempbx = 1200;
6281         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
6282            if(tempbx != SiS_Pr->SiS_VDE) {
6283               tempbx = 960;
6284            }
6285         }
6286      }
6287    }
6288    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
6289      tempbx = SiS_Pr->SiS_VDE - 1;
6290      tempcx--;
6291    }
6292    tempax = 1;
6293    if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
6294      if(tempbx != SiS_Pr->SiS_VDE){
6295        tempax = tempbx;
6296        if(tempax < SiS_Pr->SiS_VDE) {
6297          tempax = 0;
6298          tempcx = 0;
6299        } else {
6300          tempax -= SiS_Pr->SiS_VDE;
6301        }
6302        tempax >>= 1;
6303      }
6304      tempcx -= tempax; /* lcdvdes */
6305      tempbx -= tempax; /* lcdvdee */
6306    } else {
6307      tempax >>= 1;
6308      tempcx -= tempax; /* lcdvdes */
6309      tempbx -= tempax; /* lcdvdee */
6310    }
6311
6312    temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
6313    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
6314    temp = tempbx & 0x00FF;   				/* RVEQ2EQ=lcdvdee */
6315    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp);
6316
6317    temp = ((tempbx & 0xFF00) >> 8 ) << 3;
6318    temp |= ((tempcx & 0xFF00) >> 8);
6319    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
6320
6321    tempbx = push2;
6322    tempax = push1;
6323    tempcx = tempbx;
6324    tempcx -= tempax;
6325    tempcx >>= 4;
6326    tempbx += tempax;
6327    tempbx >>= 1;
6328    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx -= 10;
6329
6330    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
6331    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
6332
6333    temp = ((tempbx & 0xFF00) >> 8) << 4;
6334    tempbx += (tempcx + 1);
6335    temp |= (tempbx & 0x000F);
6336    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
6337
6338    /* TW: Code from 630/301B (I+II) BIOS */
6339
6340    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
6341            (HwDeviceExtension->jChipType == SIS_730) ) &&
6342          (HwDeviceExtension->jChipRevision > 2) )  &&
6343        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
6344        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6345        (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
6346            if(ModeNo == 0x13) {
6347              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6348              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6349              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6350            } else {
6351              if((crt2crtc & 0x3F) == 4) {
6352                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6353                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
6354                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6355                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
6356                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6357              }
6358            }
6359    }
6360
6361    /* TW: Inserted missing code from 630/301B BIOS: (II: 3258) */
6362
6363    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6364         crt2crtc &= 0x1f;
6365         tempcx = 0;
6366         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6367           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6368              tempcx += 7;
6369           }
6370         }
6371         tempcx += crt2crtc;
6372         if (crt2crtc >= 4) {
6373           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
6374         }
6375
6376         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6377           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6378             if(crt2crtc == 4) {
6379                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
6380             }
6381           }
6382         }
6383         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
6384         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6385    }
6386
6387    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
6388    tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
6389    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6390         tempbx += 2;
6391    }
6392    push1 = tempbx;
6393    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
6394    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
6395    temp = (tempbx & 0xFF00) >> 8;
6396    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
6397
6398    temp = 7;
6399    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6400         temp += 2;
6401    }
6402    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes */
6403
6404    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);
6405
6406    tempbx += tempcx;
6407    push2 = tempbx;
6408    temp = tempbx & 0xFF;            		          /* RHBURSTS=lcdhrs */
6409    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
6410      if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
6411        if(SiS_Pr->SiS_HDE == 1280)  temp = 0x47;
6412      }
6413    }
6414    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
6415    temp = ((tempbx & 0xFF00) >> 8) << 4;
6416    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
6417
6418    tempbx = push2;
6419    tempcx <<= 1;
6420    tempbx += tempcx;
6421    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
6422    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
6423
6424    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6425      if(SiS_Pr->SiS_VGAVDE == 525) {
6426        if(SiS_Pr->SiS_ModeType <= ModeVGA)
6427    	   temp=0xC6;
6428        else
6429       	   temp=0xC3;
6430        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
6431        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
6432      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6433        if(SiS_Pr->SiS_ModeType <= ModeVGA)
6434	   temp=0x4F;
6435        else
6436       	   temp=0x4D;   /* 650: 4e */
6437        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
6438      }
6439    }
6440
6441  } /* HwDeviceExtension */
6442}
6443
6444USHORT
6445SiS_GetVGAHT2(SiS_Private *SiS_Pr)
6446{
6447  ULONG tempax,tempbx;
6448
6449  tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
6450  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
6451  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
6452  return((USHORT) tempax);
6453}
6454
6455/* TW: Set 301 Macrovision(tm) registers */
6456/* TW: Double-Checked against 650/301LV, 650/301LVx and 630/301B BIOS */
6457void
6458SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
6459              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
6460{
6461  USHORT temp;
6462#ifdef oldHV
6463  USHORT i;
6464  const UCHAR  *tempdi;
6465#endif
6466  USHORT modeflag;
6467
6468  /* TW: Inserted from 650/301LVx 1.10.6s */
6469  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6470
6471  if(ModeNo<=0x13)
6472    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6473  else
6474    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6475
6476  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
6477
6478  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
6479    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
6480    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
6481  } else {
6482    if(HwDeviceExtension->jChipType >= SIS_315H) {
6483      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
6484      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
6485    } else {
6486      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
6487      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
6488    }
6489  }
6490
6491  temp = 0;
6492  if((HwDeviceExtension->jChipType == SIS_630)||
6493     (HwDeviceExtension->jChipType == SIS_730)) {
6494     temp = 0x35;
6495  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
6496     temp = 0x38;
6497  }
6498  if(temp) {
6499      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6500          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
6501              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & 0x40){
6502                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
6503                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
6504                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
6505              }
6506          }
6507      }
6508  }
6509
6510#ifdef oldHV
6511  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
6512    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
6513    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
6514      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
6515      if(!(modeflag & Charx8Dot)) {
6516        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
6517      }
6518    }
6519    for(i=0; i<=0x3E; i++){
6520       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
6521    }
6522  }
6523#endif
6524
6525  return;
6526}
6527
6528/* TW: Set 301 VGA2 registers */
6529/* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
6530void
6531SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
6532              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6533	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
6534{
6535  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2;
6536  ULONG tempebx,tempeax,templong;
6537
6538  if(ModeNo<=0x13)
6539    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6540  else
6541    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6542
6543  /* TW: From 650/301LVx 1.10.6s BIOS */
6544  if(SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) {
6545      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6546          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
6547      }
6548  }
6549
6550  if(SiS_Pr->SiS_VBType & VB_SIS30xNEW) {
6551      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6552          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
6553      }
6554  }
6555
6556  /* TW: From 650/301LV BIOS */
6557  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6558  	/* TW: This is a duplicate; done at the end, too */
6559	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
6560		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
6561	}
6562	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
6563	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
6564	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
6565   	return;
6566  }
6567
6568  temp = SiS_Pr->SiS_RVBHCFACT;
6569  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp);
6570
6571  tempbx = SiS_Pr->SiS_RVBHCMAX;
6572  temp = tempbx & 0x00FF;
6573  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp);
6574
6575  temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
6576
6577  tempcx = SiS_Pr->SiS_VGAHT - 1;
6578  temp = tempcx & 0x00FF;
6579  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp);
6580
6581  temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
6582  temp2 |= temp;
6583
6584  tempcx = SiS_Pr->SiS_VGAVT - 1;
6585  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
6586
6587  temp = tempcx & 0x00FF;
6588  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp);
6589
6590  temp = temp2 | ((tempcx & 0xFF00) >> 8);
6591  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp);
6592
6593  tempcx = SiS_Pr->SiS_VBInfo;
6594  tempbx = SiS_Pr->SiS_VGAHDE;
6595  if(modeflag & HalfDCLK)  tempbx >>= 1;
6596
6597  /* TW: New for 650/301LV and 630/301B */
6598  temp = 0xA0;
6599#ifdef oldHV
6600  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
6601       temp = 0;
6602       if(tempbx > 800) {
6603          temp = 0xA0;
6604          if(tempbx != 1024) {
6605             temp = 0xC0;
6606             if(tempbx != 1280) temp = 0;
6607	  }
6608       }
6609  } else
6610#endif
6611    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6612      if(tempbx <= 800) {
6613         temp = 0x80;
6614	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
6615            temp = 0;
6616            if(tempbx > 800) temp = 0x60;
6617         }
6618      }
6619  } else {
6620      temp = 0x80;
6621      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
6622            temp = 0;
6623            if(tempbx > 800) temp = 0x60;
6624      }
6625  }
6626  if(SiS_Pr->SiS_HiVision & 0x03) {
6627        temp = 0;
6628	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
6629  }
6630  if(HwDeviceExtension->jChipType >= SIS_315H) {
6631  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
6632  }
6633
6634  if(SiS_Pr->SiS_VBType & VB_SIS301) {
6635     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
6636        temp |= 0x0A;
6637  }
6638
6639  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
6640
6641  tempebx = SiS_Pr->SiS_VDE;
6642
6643#ifdef oldHV
6644  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
6645     if(!(temp & 0xE0)) tempebx >>=1;
6646  }
6647#endif
6648
6649  tempcx = SiS_Pr->SiS_RVBHRS;
6650  temp = tempcx & 0x00FF;
6651  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
6652
6653  tempeax = SiS_Pr->SiS_VGAVDE;
6654  tempcx |= 0x4000;
6655  if(tempeax <= tempebx){
6656    tempcx ^= 0x4000;
6657  } else {
6658    tempeax -= tempebx;
6659  }
6660
6661  templong = (tempeax * 256 * 1024) % tempebx;
6662  tempeax = (tempeax * 256 * 1024) / tempebx;
6663  tempebx = tempeax;
6664  if(templong != 0) tempebx++;
6665
6666  temp = (USHORT)(tempebx & 0x000000FF);
6667  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
6668  temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6669  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp);
6670
6671  tempbx = (USHORT)(tempebx >> 16);
6672  temp = tempbx & 0x00FF;
6673  temp <<= 4;
6674  temp |= ((tempcx & 0xFF00) >> 8);
6675  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp);
6676
6677  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6678
6679         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28);
6680	 tempbx = 0;
6681         tempax = SiS_Pr->SiS_VGAHDE;
6682         if(modeflag & HalfDCLK) tempax >>= 1;
6683         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
6684	     if(HwDeviceExtension->jChipType >= SIS_315H) {
6685	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
6686		 else if(tempax > 800) tempax -= 800;
6687	     } else {
6688                 if(tempax > 800) tempax -= 800;
6689             }
6690         }
6691
6692         if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
6693           if(tempax > 800) {
6694	      tempbx = 8;
6695              if(tempax == 1024)
6696	        tempax *= 25;
6697              else
6698	        tempax *= 20;
6699
6700	      temp = tempax % 32;
6701	      tempax /= 32;
6702	      tempax--;
6703	      if (temp!=0) tempax++;
6704           }
6705         }
6706	 tempax--;
6707         temp = (tempax & 0xFF00) >> 8;
6708         temp &= 0x03;
6709	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
6710	 temp <<= 4;
6711	 temp |= tempbx;
6712	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
6713
6714         temp = 0x0036;
6715         if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
6716	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
6717		temp |= 0x01;
6718	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6719	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
6720  	                  temp &= 0xFE;
6721		}
6722         }
6723         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
6724
6725	 tempbx = SiS_Pr->SiS_HT;
6726	 if(HwDeviceExtension->jChipType >= SIS_315H) {
6727	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
6728	 }
6729         tempbx >>= 1;
6730	 tempbx -= 2;
6731         temp = ((tempbx & 0x0700) >> 8) << 3;
6732         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
6733         temp = tempbx & 0x00FF;
6734         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
6735         if( (SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) &&
6736	                        (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
6737             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
6738	 }
6739
6740         /* TW: 650 BIOS does this for all bridge types - assumingly wrong */
6741	 if(HwDeviceExtension->jChipType >= SIS_315H) {
6742             /* TW: This is a duplicate; done for LCDA as well (see above) */
6743	     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
6744		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
6745	     }
6746	     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
6747	     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
6748	     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
6749         }
6750
6751  }  /* 301B */
6752
6753  SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
6754                  RefreshRateTableIndex,HwDeviceExtension);
6755}
6756
6757/* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
6758void
6759SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
6760                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
6761{
6762  USHORT vclkindex;
6763  USHORT tempah;
6764
6765  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
6766                              HwDeviceExtension);
6767
6768  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6769   	tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
6770   	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
6771   	tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
6772   	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
6773	/* TW: New from 650/301LV, LVx BIOS */
6774	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
6775           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6776	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
6777                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
6778		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
6779		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
6780		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
6781                 }
6782              }
6783           }
6784	}
6785  } else {	/* 650/301LVx does not do this anymore, jumps to SetRegs above - BUG? */
6786   	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
6787   	tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
6788   	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
6789   	tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
6790   	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
6791  }
6792  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
6793  tempah = 0x08;
6794  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6795    	tempah |= 0x20;
6796  }
6797  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
6798}
6799
6800/* TW: Double-checked against 650/LVDS (1.10.07), 630/301B/LVDS/LVDS+CH, 650/301LVx (1.10.6s) BIOS */
6801USHORT
6802SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
6803                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
6804{
6805  USHORT tempbx;
6806#ifdef SIS300
6807  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
6808  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
6809  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
6810  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
6811#endif
6812#ifdef SIS315H
6813  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
6814  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
6815  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
6816  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
6817  			   /* {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2}; -  650/LVDS 1.10.07 */
6818#endif
6819  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
6820  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
6821  USHORT CRT2Index,VCLKIndex=0;
6822  USHORT modeflag,resinfo;
6823  const UCHAR *CHTVVCLKPtr=NULL;
6824  const USHORT *LCDXlatVCLK1 = NULL;
6825  const USHORT *LCDXlatVCLK2 = NULL;
6826  const USHORT *LVDSXlatVCLK2 = NULL;
6827  const USHORT *LVDSXlatVCLK3 = NULL;
6828
6829#ifdef SIS315H
6830  if(HwDeviceExtension->jChipType >= SIS_315H) {
6831		LCDXlatVCLK1 = LCDXlat1VCLK310;
6832		LCDXlatVCLK2 = LCDXlat2VCLK310;
6833		LVDSXlatVCLK2 = LVDSXlat2VCLK310;
6834		LVDSXlatVCLK3 = LVDSXlat3VCLK310;
6835  } else {
6836#endif
6837#ifdef SIS300
6838		LCDXlatVCLK1 = LCDXlat1VCLK300;
6839		LCDXlatVCLK2 = LCDXlat2VCLK300;
6840		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
6841		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
6842#endif
6843#ifdef SIS315H
6844  }
6845#endif
6846
6847  if(ModeNo<=0x13) {
6848    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6849    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
6850    	CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6851  } else {
6852    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6853    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6854    	CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6855  }
6856
6857  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 301 */
6858
6859     if (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
6860
6861        CRT2Index >>= 6;
6862        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
6863            if(HwDeviceExtension->jChipType < SIS_315H) {
6864	       /* TW: Inserted from 630/301B BIOS */
6865	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
6866	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
6867	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
6868	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
6869	       else
6870	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
6871	    } else {
6872               /* TW: 650/301LV BIOS does not check expanding, 315 does  */
6873	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
6874	           (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
6875      	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
6876		     VCLKIndex = 0x19;
6877		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
6878		     VCLKIndex = 0x19;
6879		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
6880		     VCLKIndex = 0x21;
6881		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
6882		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
6883                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
6884		     VCLKIndex = 0x45;
6885		     if(resinfo == 0x09) VCLKIndex++;
6886	          } else {
6887		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
6888      	          }
6889	       } else {
6890                   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
6891         	   VCLKIndex = ((VCLKIndex >> 2) & 0x03);
6892        	   if(ModeNo > 0x13) {
6893          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
6894        	   }
6895		   if(ModeNo <= 0x13) {  /* TW: Inserted from 315 BIOS */
6896		      if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
6897		   }
6898		   if(VCLKIndex == 0) VCLKIndex = 0x41;
6899		   if(VCLKIndex == 1) VCLKIndex = 0x43;
6900		   if(VCLKIndex == 4) VCLKIndex = 0x44;
6901	       }
6902	    }
6903        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
6904        	if((SiS_Pr->SiS_IF_DEF_HiVision == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
6905          		if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = HiTVVCLKDIV2;
6906     			else                                  VCLKIndex = HiTVVCLK;
6907          		if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
6908            			if(modeflag & Charx8Dot)      VCLKIndex = HiTVSimuVCLK;
6909            			else 			      VCLKIndex = HiTVTextVCLK;
6910          		}
6911        	} else {
6912       			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
6913            		else         		              VCLKIndex = TVVCLK;
6914          	}
6915		if(HwDeviceExtension->jChipType >= SIS_315H) {
6916              		VCLKIndex += 25;
6917  		}
6918        } else {         					/* RAMDAC2 */
6919        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
6920        	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
6921        	if(ModeNo > 0x13) {
6922          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
6923			if(HwDeviceExtension->jChipType < SIS_315H) {
6924          			VCLKIndex &= 0x3f;
6925				if( (HwDeviceExtension->jChipType == SIS_630) &&
6926				    (HwDeviceExtension->jChipRevision >= 0x30)) {
6927				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
6928				}
6929			}
6930        	}
6931        }
6932
6933    } else {   /* If not programming CRT2 */
6934
6935        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
6936        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
6937        if(ModeNo > 0x13) {
6938             VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
6939	     if(HwDeviceExtension->jChipType < SIS_315H) {
6940                VCLKIndex &= 0x3f;
6941		if( (HwDeviceExtension->jChipType != SIS_630) &&
6942		    (HwDeviceExtension->jChipType != SIS_300) ) {
6943		   if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
6944		}
6945	     }
6946        }
6947    }
6948
6949  } else {       /*   LVDS  */
6950
6951    	VCLKIndex = CRT2Index;
6952
6953	if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
6954
6955	   if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
6956
6957		VCLKIndex &= 0x1f;
6958        	tempbx = 0;
6959        	if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx += 2;
6960        	if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
6961       		switch(tempbx) {
6962          	   case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
6963         	   case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
6964                   case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
6965                   case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
6966        	}
6967        	VCLKIndex = CHTVVCLKPtr[VCLKIndex];
6968
6969	   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6970
6971	        VCLKIndex >>= 6;
6972     		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
6973		                   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
6974     			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
6975     		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
6976     			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
6977		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
6978                        VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
6979     		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
6980
6981	   } else {
6982
6983	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
6984                VCLKIndex = ((VCLKIndex >> 2) & 0x03);
6985                if(ModeNo > 0x13) {
6986                     VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
6987		     if( (HwDeviceExtension->jChipType == SIS_630) &&
6988                         (HwDeviceExtension->jChipRevision >= 0x30) ) {
6989		         	if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
6990		     }
6991	        }
6992
6993	   }
6994
6995	} else {  /* if not programming CRT2 */
6996
6997	   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
6998           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
6999           if(ModeNo > 0x13) {
7000              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
7001              if(HwDeviceExtension->jChipType < SIS_315H) {
7002	         if( (HwDeviceExtension->jChipType != SIS_630) &&
7003		     (HwDeviceExtension->jChipType != SIS_300) ) {
7004		        if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
7005	         }
7006	      }
7007	   }
7008
7009	}
7010
7011  }
7012
7013  if(HwDeviceExtension->jChipType < SIS_315H) {
7014    	VCLKIndex &= 0x3F;
7015  }
7016  return (VCLKIndex);
7017}
7018
7019/* TW: Set 301 Palette address port registers */
7020/* TW: Checked against 650/301LV BIOS */
7021void
7022SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
7023              UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
7024{
7025
7026  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7027
7028  if(SiS_Pr->SiS_ModeType == ModeVGA){
7029    if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
7030      SiS_EnableCRT2(SiS_Pr);
7031      SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
7032    }
7033  }
7034  return;
7035}
7036
7037/* TW: Checked against 650/LVDS and 630/301B BIOS */
7038void
7039SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
7040                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
7041{
7042  USHORT temp,tempah,i,modeflag,j;
7043  USHORT ResInfo,DisplayType;
7044  const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7045
7046  if(ModeNo <= 0x13) {
7047    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7048  } else {
7049    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7050  }
7051
7052  temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
7053                            &ResInfo,&DisplayType);
7054
7055  if(temp == 0) return;
7056
7057  /* TW: Inserted from 630/LVDS BIOS */
7058  if(HwDeviceExtension->jChipType < SIS_315H) {
7059     if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) return;
7060  }
7061
7062  switch(DisplayType) {
7063    case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
7064    case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
7065    case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
7066    case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
7067    case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
7068    case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
7069    case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
7070    case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
7071    case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
7072    case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
7073    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
7074    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
7075    case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
7076    case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
7077    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
7078    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
7079    case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
7080    case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
7081    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7082    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7083    case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7084    case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7085    case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
7086    case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7087    case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7088    case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7089    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7090    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
7091    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
7092    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
7093    case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
7094    case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
7095    case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
7096    case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
7097    case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
7098  }
7099
7100  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
7101
7102  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
7103  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
7104
7105  for(i=0x02,j=1;i<=0x05;i++,j++){
7106    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
7107    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
7108  }
7109  for(i=0x06,j=5;i<=0x07;i++,j++){
7110    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
7111    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
7112  }
7113  for(i=0x10,j=7;i<=0x11;i++,j++){
7114    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
7115    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
7116  }
7117  for(i=0x15,j=9;i<=0x16;i++,j++){
7118    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
7119    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
7120  }
7121  for(i=0x0A,j=11;i<=0x0C;i++,j++){
7122    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
7123    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
7124  }
7125
7126  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
7127  tempah &= 0xE0;
7128  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     	/* TW: Modfied (650/LVDS); Was SetReg(tempah) */
7129
7130  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
7131  tempah &= 0x01;
7132  tempah <<= 5;
7133  if(modeflag & DoubleScanMode){
7134    	tempah |= 0x080;
7135  }
7136  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7137
7138  /* TW: Inserted from 650/LVDS BIOS */
7139  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7140     if(modeflag & HalfDCLK)
7141        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7142  }
7143
7144  return;
7145}
7146
7147
7148/* TW: Checked against 650/LVDS BIOS: modified for new panel resolutions */
7149BOOLEAN
7150SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
7151		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
7152		   USHORT *DisplayType)
7153 {
7154  USHORT tempbx,modeflag=0;
7155  USHORT Flag,CRT2CRTC;
7156
7157  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
7158      /* TW: Inserted from 650/LVDS BIOS */
7159      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7160          if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
7161      }
7162  }
7163
7164  if(ModeNo <= 0x13) {
7165    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7166    	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7167  } else {
7168    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7169    	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7170  }
7171
7172  Flag = 1;
7173  tempbx = 0;
7174  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
7175    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
7176      Flag = 0;
7177      tempbx = 18;
7178      if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx += 2;
7179      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
7180    }
7181  }
7182  if(Flag) {
7183    tempbx = SiS_Pr->SiS_LCDResInfo;
7184    tempbx -= SiS_Pr->SiS_PanelMinLVDS;
7185    if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
7186       if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
7187       if(modeflag & HalfDCLK) tempbx += 3;
7188    } else {
7189       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
7190           tempbx = 14;
7191	   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
7192	   if(modeflag & HalfDCLK) tempbx++;
7193       } else if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7194           tempbx = 12;
7195	   if(modeflag & HalfDCLK) tempbx++;
7196       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
7197           tempbx = 23;
7198	   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
7199	   if(modeflag & HalfDCLK) tempbx++;
7200       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
7201           tempbx = 27;
7202	   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
7203	   if(modeflag & HalfDCLK) tempbx++;
7204       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
7205           tempbx = 36;
7206	   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
7207	   if(modeflag & HalfDCLK) tempbx++;
7208       }
7209    }
7210  }
7211  if(SiS_Pr->SiS_IF_DEF_FSTN){
7212     if(SiS_Pr->SiS_LCDResInfo==SiS_Pr->SiS_Panel320x480){
7213       tempbx=22;
7214     }
7215  }
7216  *ResInfo = CRT2CRTC & 0x3F;
7217  *DisplayType = tempbx;
7218  return 1;
7219}
7220
7221/* TW: Checked against 650/LVDS (1.10a, 1.10.07), 630/301B (I/II) and 630/LVDS BIOS */
7222void
7223SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
7224           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
7225{
7226  USHORT tempah,tempal,pushax;
7227  USHORT vclkindex=0;
7228
7229  if(HwDeviceExtension->jChipType < SIS_315H) {
7230     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7231        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) return;
7232     }
7233  }
7234
7235  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
7236	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7237        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
7238    	tempal &= 0x3F;
7239	if(tempal == 2) RefreshRateTableIndex--;
7240	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
7241                               RefreshRateTableIndex,HwDeviceExtension);
7242	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7243  } else {
7244        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
7245                               RefreshRateTableIndex,HwDeviceExtension);
7246  }
7247
7248  tempal = 0x02B;
7249  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7250     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7251    	tempal += 3;
7252     }
7253  }
7254  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
7255  pushax = tempal;
7256  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
7257  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7258  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7259  tempal++;
7260  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7261  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7262  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
7263  tempal = pushax;
7264  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7265  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7266  tempal++;
7267  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7268  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7269  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
7270  tempal = pushax;
7271  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7272  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7273  tempal++;
7274  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7275  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
7276  return;
7277}
7278
7279
7280/* TW: Start of Chrontel 70xx functions ---------------------- */
7281
7282/* Set-up the Chrontel Registers */
7283void
7284SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
7285               USHORT RefreshRateTableIndex)
7286{
7287  USHORT temp, tempbx, tempcl;
7288  USHORT TVType, resindex;
7289  const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
7290
7291  if(ModeNo <= 0x13)
7292    	tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7293  else
7294    	tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7295
7296  TVType = 0;
7297  if(SiS_Pr->SiS_VBInfo & SetPALTV) TVType += 2;
7298  if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
7299  switch(TVType) {
7300    	case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7301    	case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7302    	case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
7303    	case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7304  }
7305  resindex = tempcl & 0x3F;
7306
7307  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7308
7309     /* Chrontel 7005 */
7310
7311     /* TW: We don't support modes >800x600 */
7312     if (resindex > 5) return;
7313
7314     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
7315    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7316    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
7317     } else {
7318    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7319    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
7320     }
7321
7322     temp = CHTVRegData[resindex].Reg[0];
7323     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
7324     SiS_SetCH700x(SiS_Pr,tempbx);
7325     temp = CHTVRegData[resindex].Reg[1];
7326     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
7327     SiS_SetCH700x(SiS_Pr,tempbx);
7328     temp = CHTVRegData[resindex].Reg[2];
7329     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
7330     SiS_SetCH700x(SiS_Pr,tempbx);
7331     temp = CHTVRegData[resindex].Reg[3];
7332     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
7333     SiS_SetCH700x(SiS_Pr,tempbx);
7334     temp = CHTVRegData[resindex].Reg[4];
7335     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
7336     SiS_SetCH700x(SiS_Pr,tempbx);
7337
7338     /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
7339                minimum text enhancement (S3-2=10),
7340   	        maximum flicker filter for Chroma channel (S5-4=10)
7341	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7342      */
7343     SiS_SetCH700x(SiS_Pr,0x2801);
7344
7345     /* TW: Set video bandwidth
7346            High bandwith Luma composite video filter(S0=1)
7347            low bandwith Luma S-video filter (S2-1=00)
7348	    disable peak filter in S-video channel (S3=0)
7349	    high bandwidth Chroma Filter (S5-4=11)
7350	    =00110001=0x31
7351     */
7352     SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
7353
7354     /* TW: Register 0x3D does not exist in non-macrovision register map
7355            (Maybe this is a macrovision register?)
7356      */
7357     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
7358
7359     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
7360            all other bits a read-only. Macrovision?
7361      */
7362     SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
7363
7364     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
7365            contrast enhancement (set to 010 -> gain 2 Yout = 9/8*(Yin-57) )
7366      */
7367     SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
7368
7369     /* TW: Clear DSEN
7370      */
7371     SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
7372
7373     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {		/* ---- NTSC ---- */
7374       if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) {
7375         if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
7376      	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);   	/* loop filter off */
7377           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
7378         } else {
7379           if(resindex == 0x05) {    			/* 800x600 overscan: Mode 23 */
7380             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
7381             SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
7382             SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
7383             SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
7384             SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
7385             SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
7386             SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
7387             SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
7388             SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);     /* Loop filter on for mode 23 */
7389             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);     /* ACIV off, need to set FSCI */
7390           }
7391         }
7392       } else {
7393         if(resindex == 0x04) {     			 /* ----- 640x480 underscan; Mode 17 */
7394           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
7395           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
7396         } else {
7397           if(resindex == 0x05) {   			 /* ----- 800x600 underscan: Mode 24 */
7398             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);     /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7399             SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);	 /* FSCI for mode 24 is 428,554,851 */
7400             SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);
7401             SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
7402             SiS_SetCH70xxANDOR(SiS_Pr,0x031C,0xF0);
7403             SiS_SetCH70xxANDOR(SiS_Pr,0x0a1D,0xF0);
7404             SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
7405             SiS_SetCH70xxANDOR(SiS_Pr,0x031F,0xF0);
7406             SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off for mode 24 */
7407             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);	 /* ACIV off, need to set FSCI */
7408           }
7409         }
7410       }
7411     } else {				/* ---- PAL ---- */
7412           /* TW: We don't play around with FSCI in PAL mode */
7413         if (resindex == 0x04) {
7414           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
7415           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
7416         } else {
7417           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
7418           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
7419         }
7420     }
7421
7422  } else {
7423
7424     /* Chrontel 7019 */
7425
7426     /* TW: We don't support modes >1024x768 */
7427     if (resindex > 6) return;
7428
7429     temp = CHTVRegData[resindex].Reg[0];
7430     tempbx=((temp & 0x00FF) <<8 ) | 0x00;
7431     SiS_SetCH701x(SiS_Pr,tempbx);
7432
7433     temp = CHTVRegData[resindex].Reg[1];
7434     tempbx=((temp & 0x00FF) <<8 ) | 0x01;
7435     SiS_SetCH701x(SiS_Pr,tempbx);
7436
7437     temp = CHTVRegData[resindex].Reg[2];
7438     tempbx=((temp & 0x00FF) <<8 ) | 0x02;
7439     SiS_SetCH701x(SiS_Pr,tempbx);
7440
7441     temp = CHTVRegData[resindex].Reg[3];
7442     tempbx=((temp & 0x00FF) <<8 ) | 0x04;
7443     SiS_SetCH701x(SiS_Pr,tempbx);
7444
7445     temp = CHTVRegData[resindex].Reg[4];
7446     tempbx=((temp & 0x00FF) <<8 ) | 0x03;
7447     SiS_SetCH701x(SiS_Pr,tempbx);
7448
7449     temp = CHTVRegData[resindex].Reg[5];
7450     tempbx=((temp & 0x00FF) <<8 ) | 0x05;
7451     SiS_SetCH701x(SiS_Pr,tempbx);
7452
7453     temp = CHTVRegData[resindex].Reg[6];
7454     tempbx=((temp & 0x00FF) <<8 ) | 0x06;
7455     SiS_SetCH701x(SiS_Pr,tempbx);
7456
7457     temp = CHTVRegData[resindex].Reg[7];
7458     tempbx=((temp & 0x00FF) <<8 ) | 0x07;
7459     SiS_SetCH701x(SiS_Pr,tempbx);
7460
7461     temp = CHTVRegData[resindex].Reg[8];
7462     tempbx=((temp & 0x00FF) <<8 ) | 0x08;
7463     SiS_SetCH701x(SiS_Pr,tempbx);
7464
7465     temp = CHTVRegData[resindex].Reg[9];
7466     tempbx=((temp & 0x00FF) <<8 ) | 0x15;
7467     SiS_SetCH701x(SiS_Pr,tempbx);
7468
7469     temp = CHTVRegData[resindex].Reg[10];
7470     tempbx=((temp & 0x00FF) <<8 ) | 0x1f;
7471     SiS_SetCH701x(SiS_Pr,tempbx);
7472
7473     temp = CHTVRegData[resindex].Reg[11];
7474     tempbx=((temp & 0x00FF) <<8 ) | 0x0c;
7475     SiS_SetCH701x(SiS_Pr,tempbx);
7476
7477     temp = CHTVRegData[resindex].Reg[12];
7478     tempbx=((temp & 0x00FF) <<8 ) | 0x0d;
7479     SiS_SetCH701x(SiS_Pr,tempbx);
7480
7481     temp = CHTVRegData[resindex].Reg[13];
7482     tempbx=((temp & 0x00FF) <<8 ) | 0x0e;
7483     SiS_SetCH701x(SiS_Pr,tempbx);
7484
7485     temp = CHTVRegData[resindex].Reg[14];
7486     tempbx=((temp & 0x00FF) <<8 ) | 0x0f;
7487     SiS_SetCH701x(SiS_Pr,tempbx);
7488
7489     temp = CHTVRegData[resindex].Reg[15];
7490     tempbx=((temp & 0x00FF) <<8 ) | 0x10;
7491     SiS_SetCH701x(SiS_Pr,tempbx);
7492
7493  }
7494}
7495
7496void
7497SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
7498{
7499  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
7500                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
7501  UCHAR table28b4[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
7502                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
7503  UCHAR table28c0[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
7504                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
7505  UCHAR *tableptr = NULL;
7506  USHORT tempbh;
7507  int i;
7508
7509  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
7510      tableptr = table28c0;
7511  } else {
7512      tableptr = table28b4;
7513  }
7514  tempbh = SiS_GetCH701x(SiS_Pr,0x74);
7515  if((tempbh == 0xf6) || (tempbh == 0xc7)) {
7516     tempbh = SiS_GetCH701x(SiS_Pr,0x73);
7517     if(tempbh == 0xc8) {
7518        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) return;
7519     } else if(tempbh == 0xdb) {
7520        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
7521     }
7522  }
7523  for(i=0; i<0x0c; i++) {
7524     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
7525  }
7526  SiS_Chrontel19f2(SiS_Pr);
7527  tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
7528  tempbh |= 0xc0;
7529  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
7530}
7531
7532/* TW: Chrontel 701x functions ================================= */
7533
7534void
7535SiS_Chrontel19f2(SiS_Private *SiS_Pr)
7536{
7537  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
7538  UCHAR table19e8[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
7539  UCHAR table19ed[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
7540  UCHAR *tableptr = NULL;
7541  int i;
7542
7543  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
7544      tableptr = table19ed;
7545  } else {
7546      tableptr = table19e8;
7547  }
7548
7549  for(i=0; i<5; i++) {
7550     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
7551  }
7552}
7553
7554void
7555SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
7556{
7557  USHORT temp;
7558
7559  /* TW: Enable Chrontel 7019 LCD panel backlight */
7560  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
7561        temp = SiS_GetCH701x(SiS_Pr,0x66);
7562        temp |= 0x20;
7563	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
7564  }
7565}
7566
7567void
7568SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
7569{
7570  USHORT temp;
7571
7572  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
7573     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
7574        temp = SiS_GetCH701x(SiS_Pr,0x01);
7575	temp &= 0x3f;
7576	temp |= 0x80;
7577	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
7578     }
7579     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
7580     temp = SiS_GetCH701x(SiS_Pr,0x49);
7581     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
7582        temp = SiS_GetCH701x(SiS_Pr,0x73);
7583	temp |= 0x60;
7584	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
7585     }
7586     temp = SiS_GetCH701x(SiS_Pr,0x47);
7587     temp &= 0x7f;
7588     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
7589     SiS_LongDelay(SiS_Pr,2);
7590     temp = SiS_GetCH701x(SiS_Pr,0x47);
7591     temp |= 0x80;
7592     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
7593  }
7594}
7595
7596void
7597SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
7598{
7599  USHORT temp;
7600
7601  /* TW: Disable Chrontel 7019 LCD panel backlight */
7602  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
7603        temp = SiS_GetCH701x(SiS_Pr,0x66);
7604        temp &= 0xDF;
7605	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
7606  }
7607}
7608
7609void
7610SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
7611{
7612  USHORT temp;
7613
7614  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
7615        SiS_LongDelay(SiS_Pr,2);
7616	/* TW: Complete power down of LVDS */
7617	temp = SiS_GetCH701x(SiS_Pr,0x76);
7618	temp &= 0xfc;
7619	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
7620	SiS_SetCH701x(SiS_Pr,0x0066);
7621  }
7622}
7623
7624void
7625SiS_ChrontelResetDB(SiS_Private *SiS_Pr)
7626{
7627     /* TW: Reset Chrontel 7019 datapath */
7628     SiS_SetCH701x(SiS_Pr,0x1048);
7629     SiS_LongDelay(SiS_Pr,1);
7630     SiS_SetCH701x(SiS_Pr,0x1848);
7631}
7632
7633void
7634SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
7635{
7636     USHORT temp;
7637
7638     SiS_SetCH701x(SiS_Pr,0xaf76);
7639     temp = SiS_GetCH701x(SiS_Pr,0x49);
7640     temp &= 1;
7641     if(temp != 1) {
7642	temp = SiS_GetCH701x(SiS_Pr,0x47);
7643	temp &= 0x70;
7644	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
7645	SiS_LongDelay(SiS_Pr,3);
7646	temp = SiS_GetCH701x(SiS_Pr,0x47);
7647	temp |= 0x80;
7648	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
7649     }
7650}
7651
7652void
7653SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
7654                         USHORT BaseAddr)
7655{
7656     USHORT temp,temp1;
7657
7658     temp1 = 0;
7659     temp = SiS_GetCH701x(SiS_Pr,0x61);
7660     if(temp < 2) {
7661          temp++;
7662	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
7663	  temp1 = 1;
7664     }
7665     SiS_SetCH701x(SiS_Pr,0xac76);
7666     temp = SiS_GetCH701x(SiS_Pr,0x66);
7667     temp |= 0x5f;
7668     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
7669     if(ModeNo > 0x13) {
7670         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
7671	    SiS_GenericDelay(SiS_Pr,0x3ff);
7672	 } else {
7673	    SiS_GenericDelay(SiS_Pr,0x2ff);
7674	 }
7675     } else {
7676         if(!temp1)
7677	    SiS_GenericDelay(SiS_Pr,0x2ff);
7678     }
7679     temp = SiS_GetCH701x(SiS_Pr,0x76);
7680     temp |= 0x03;
7681     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
7682     temp = SiS_GetCH701x(SiS_Pr,0x66);
7683     temp &= 0x7f;
7684     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
7685     SiS_LongDelay(SiS_Pr,1);
7686}
7687
7688void
7689SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
7690{
7691     USHORT temp,tempcl,tempch;
7692
7693     SiS_LongDelay(SiS_Pr, 1);
7694     tempcl = 3;
7695     tempch = 0;
7696
7697     do {
7698       temp = SiS_GetCH701x(SiS_Pr,0x66);
7699       temp &= 0x04;
7700       if(temp == 0x04) break;
7701
7702       SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension, BaseAddr);
7703
7704       if(tempcl == 0) {
7705           if(tempch == 3) break;
7706	   SiS_ChrontelResetDB(SiS_Pr);
7707	   tempcl = 3;
7708	   tempch++;
7709       }
7710       tempcl--;
7711       temp = SiS_GetCH701x(SiS_Pr,0x76);
7712       temp &= 0xfb;
7713       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
7714       SiS_LongDelay(SiS_Pr,2);
7715       temp = SiS_GetCH701x(SiS_Pr,0x76);
7716       temp |= 0x04;
7717       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
7718       SiS_SetCH701x(SiS_Pr,0x6078);
7719       SiS_LongDelay(SiS_Pr,2);
7720    } while(0);
7721
7722    SiS_SetCH701x(SiS_Pr,0x0077);
7723}
7724
7725void
7726SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
7727                         USHORT BaseAddr)
7728{
7729     USHORT temp;
7730
7731     temp = SiS_GetCH701x(SiS_Pr,0x03);
7732     temp |= 0x80;
7733     temp &= 0xbf;
7734     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
7735
7736     SiS_ChrontelResetDB(SiS_Pr);
7737
7738     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension, BaseAddr);
7739
7740     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
7741     SiS_ChrontelDoSomething3(SiS_Pr,temp, HwDeviceExtension, BaseAddr);
7742
7743     SiS_SetCH701x(SiS_Pr,0xaf76);
7744}
7745
7746/* TW: End of Chrontel 701x functions ==================================== */
7747
7748/* TW: Generic Read/write routines for Chrontel ========================== */
7749
7750/* TW: The Chrontel is connected to the 630/730 via
7751 * the 630/730's DDC/I2C port.
7752 *
7753 * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
7754 * possibly for working around the DDC problems
7755 */
7756
7757void
7758SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
7759{
7760   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
7761      SiS_SetCH700x(SiS_Pr,tempbx);
7762   else
7763      SiS_SetCH701x(SiS_Pr,tempbx);
7764}
7765
7766/* TW: Write to Chrontel 700x */
7767/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
7768void
7769SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
7770{
7771  USHORT tempah,temp,i;
7772
7773  if(!(SiS_Pr->SiS_ChrontelInit)) {
7774     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
7775     SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
7776     SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
7777     SiS_Pr->SiS_DDC_DataShift = 0x00;
7778     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
7779  }
7780
7781  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
7782    /* SiS_SetSwitchDDC2(SiS_Pr); */
7783    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
7784    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7785    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
7786    if(temp) continue;				/* TW:    (ERROR: no ack) */
7787    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
7788    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
7789    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
7790    if(temp) continue;				/* TW:    (ERROR: no ack) */
7791    tempah = (tempbx & 0xFF00) >> 8;
7792    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
7793    if(temp) continue;				/* TW:    (ERROR: no ack) */
7794    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
7795    SiS_Pr->SiS_ChrontelInit = 1;
7796    return;
7797  }
7798
7799  /* TW: For 630ST */
7800  if(!(SiS_Pr->SiS_ChrontelInit)) {
7801     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
7802     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
7803     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
7804     SiS_Pr->SiS_DDC_DataShift = 0x00;
7805     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
7806
7807     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
7808       /* SiS_SetSwitchDDC2(SiS_Pr); */
7809       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
7810       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7811       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
7812       if(temp) continue;			/* TW:    (ERROR: no ack) */
7813       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
7814       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
7815       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
7816       if(temp) continue;			/* TW:    (ERROR: no ack) */
7817       tempah = (tempbx & 0xFF00) >> 8;
7818       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
7819       if(temp) continue;			/* TW:    (ERROR: no ack) */
7820       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
7821       SiS_Pr->SiS_ChrontelInit = 1;
7822       return;
7823    }
7824  }
7825}
7826
7827/* TW: Write to Chrontel 701x */
7828/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
7829void
7830SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
7831{
7832  USHORT tempah,temp,i;
7833
7834  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
7835  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
7836  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
7837  SiS_Pr->SiS_DDC_DataShift = 0x00;
7838  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
7839
7840  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
7841    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
7842    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7843    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
7844    if(temp) continue;				/* TW:    (ERROR: no ack) */
7845    tempah = tempbx & 0x00FF;
7846    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
7847    if(temp) continue;				/* TW:    (ERROR: no ack) */
7848    tempah = (tempbx & 0xFF00) >> 8;
7849    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
7850    if(temp) continue;				/* TW:    (ERROR: no ack) */
7851    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
7852    return;
7853  }
7854}
7855
7856/* TW: Read from Chrontel 70xx */
7857/* Parameter is [Register no (S7-S0)] */
7858USHORT
7859SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
7860{
7861   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
7862      return(SiS_GetCH700x(SiS_Pr,tempbx));
7863   else
7864      return(SiS_GetCH701x(SiS_Pr,tempbx));
7865}
7866
7867/* TW: Read from Chrontel 700x */
7868/* Parameter is [Register no (S7-S0)] */
7869USHORT
7870SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
7871{
7872  USHORT tempah,temp,i;
7873
7874  if(!(SiS_Pr->SiS_ChrontelInit)) {
7875     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
7876     SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
7877     SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
7878     SiS_Pr->SiS_DDC_DataShift = 0x00;
7879     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
7880  }
7881
7882  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
7883
7884  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
7885    /* SiS_SetSwitchDDC2(SiS_Pr); */
7886    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
7887    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7888    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
7889    if(temp) continue;				/* TW:        (ERROR: no ack) */
7890    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
7891    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
7892    if(temp) continue;				/* TW:        (ERROR: no ack) */
7893    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
7894    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
7895    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
7896    if(temp) continue;				/* TW:        (ERROR: no ack) */
7897    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
7898    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
7899    SiS_Pr->SiS_ChrontelInit = 1;
7900    return(tempah);
7901  }
7902
7903  /* TW: For 630ST */
7904  if(!SiS_Pr->SiS_ChrontelInit) {
7905     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
7906     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
7907     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
7908     SiS_Pr->SiS_DDC_DataShift = 0x00;
7909     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
7910
7911     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
7912       /* SiS_SetSwitchDDC2(SiS_Pr); */
7913       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
7914       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7915       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
7916       if(temp) continue;				/* TW:        (ERROR: no ack) */
7917       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
7918       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
7919       if(temp) continue;				/* TW:        (ERROR: no ack) */
7920       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
7921       tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
7922       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
7923       if(temp) continue;				/* TW:        (ERROR: no ack) */
7924       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
7925       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
7926       SiS_Pr->SiS_ChrontelInit = 1;
7927       return(tempah);
7928     }
7929  }
7930  return(0xFFFF);
7931}
7932
7933/* TW: Read from Chrontel 701x */
7934/* Parameter is [Register no (S7-S0)] */
7935USHORT
7936SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
7937{
7938  USHORT tempah,temp,i;
7939
7940  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
7941  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
7942  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
7943  SiS_Pr->SiS_DDC_DataShift = 0x00;
7944  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
7945  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
7946
7947   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
7948    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
7949    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
7950    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
7951    if(temp) continue;				/* TW:        (ERROR: no ack) */
7952    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
7953    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
7954    if(temp) continue;				/* TW:        (ERROR: no ack) */
7955    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
7956    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
7957    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
7958    if(temp) continue;				/* TW:        (ERROR: no ack) */
7959    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
7960    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
7961    return(tempah);
7962   }
7963  return 0xFFFF;
7964}
7965
7966#ifdef LINUX_XF86
7967/* TW: Our own DDC functions */
7968USHORT
7969SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype)
7970{
7971     unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6};
7972     unsigned char flag, cr32;
7973     USHORT        temp = 0, myadaptnum = adaptnum;
7974
7975     SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
7976
7977     SiS_Pr->SiS_DDC_SecAddr = 0;
7978     SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
7979     SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
7980     SiS_Pr->SiS_DDC_Index = 0x11;
7981     flag = 0xff;
7982
7983     cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
7984
7985     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
7986
7987        if(pSiS->VBFlags & VB_SISBRIDGE) {
7988	   if(myadaptnum == 0) {
7989	      if(!(cr32 & 0x20)) {
7990	         myadaptnum = 2;
7991		 if(!(cr32 & 0x10)) {
7992		    myadaptnum = 1;
7993		    if(!(cr32 & 0x08)) {
7994		       myadaptnum = 0;
7995		    }
7996		 }
7997              }
7998	   }
7999	}
8000
8001        if(myadaptnum != 0) {
8002	   flag = 0;
8003	   if(pSiS->VBFlags & VB_SISBRIDGE) {
8004	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
8005              SiS_Pr->SiS_DDC_Index = 0x0f;
8006	   }
8007        }
8008
8009	if(cr32 & 0x80) {
8010           if(myadaptnum >= 1) {
8011	      if(!(cr32 & 0x08)) {
8012	          myadaptnum = 1;
8013		  if(!(cr32 & 0x10)) return 0xFFFF;
8014              }
8015	   }
8016	}
8017
8018	temp = 4 - (myadaptnum * 2);
8019	if(flag) temp = 0;
8020
8021	SiS_Pr->SiS_DDC_Data = 0x02 << temp;
8022        SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
8023
8024     } else {						/* 310/325 series */
8025
8026        if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) myadaptnum = 0;
8027
8028	if(pSiS->VBFlags & VB_SISBRIDGE) {
8029	   if(myadaptnum == 0) {
8030	      if(!(cr32 & 0x20)) {
8031	         myadaptnum = 2;
8032		 if(!(cr32 & 0x10)) {
8033		    myadaptnum = 1;
8034		    if(!(cr32 & 0x08)) {
8035		       myadaptnum = 0;
8036		    }
8037		 }
8038              }
8039	   }
8040	   if(myadaptnum == 2) {
8041	      myadaptnum = 1;
8042           }
8043	}
8044
8045        if(myadaptnum == 1) {
8046     	   flag = 0;
8047	   if(pSiS->VBFlags & VB_SISBRIDGE) {
8048	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
8049              SiS_Pr->SiS_DDC_Index = 0x0f;
8050	   }
8051        }
8052
8053        if(cr32 & 0x80) {
8054           if(myadaptnum >= 1) {
8055	      if(!(cr32 & 0x08)) {
8056	         myadaptnum = 1;
8057		 if(!(cr32 & 0x10)) return 0xFFFF;
8058	      }
8059	   }
8060        }
8061
8062        temp = myadaptnum;
8063        if(myadaptnum == 1) {
8064           temp = 0;
8065	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
8066        }
8067
8068	if(flag) temp = 0;
8069
8070        SiS_Pr->SiS_DDC_Data = 0x02 << temp;
8071        SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
8072
8073    }
8074    return 0;
8075}
8076
8077USHORT
8078SiS_WriteDABDDC(SiS_Private *SiS_Pr)
8079{
8080   SiS_SetStart(SiS_Pr);
8081   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) return 0xFFFF;
8082   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) return 0xFFFF;
8083   return(0);
8084}
8085
8086USHORT
8087SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
8088{
8089   SiS_SetStart(SiS_Pr);
8090   if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) return 0xFFFF;
8091   return(0);
8092}
8093
8094USHORT
8095SiS_PrepareDDC(SiS_Private *SiS_Pr)
8096{
8097   if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
8098   if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
8099   return(0);
8100}
8101
8102void
8103SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
8104{
8105   SiS_SetSCLKLow(SiS_Pr);
8106   if(yesno) {
8107      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
8108                      ~SiS_Pr->SiS_DDC_Data, SiS_Pr->SiS_DDC_Data);
8109   } else {
8110      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
8111                      ~SiS_Pr->SiS_DDC_Data, 0);
8112   }
8113   SiS_SetSCLKHigh(SiS_Pr);
8114}
8115
8116USHORT
8117SiS_DoProbeDDC(SiS_Private *SiS_Pr)
8118{
8119    unsigned char mask, value;
8120    USHORT  temp, ret;
8121
8122    SiS_SetSwitchDDC2(SiS_Pr);
8123    if(SiS_PrepareDDC(SiS_Pr)) {
8124         SiS_SetStop(SiS_Pr);
8125         return(0xFFFF);
8126    }
8127    mask = 0xf0;
8128    value = 0x20;
8129    if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
8130       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
8131       SiS_SendACK(SiS_Pr, 0);
8132       if(temp == 0) {
8133           mask = 0xff;
8134	   value = 0xff;
8135       }
8136    }
8137    temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
8138    SiS_SendACK(SiS_Pr, 1);
8139    temp &= mask;
8140    if(temp == value) ret = 0;
8141    else {
8142       ret = 0xFFFF;
8143       if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
8144           if(value == 0x30) ret = 0;
8145       }
8146    }
8147    SiS_SetStop(SiS_Pr);
8148    return(ret);
8149}
8150
8151USHORT
8152SiS_ProbeDDC(SiS_Private *SiS_Pr)
8153{
8154   USHORT flag;
8155
8156   flag = 0x180;
8157   SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
8158   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
8159   SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
8160   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
8161   SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
8162   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
8163   if(!(flag & 0x1a)) flag = 0;
8164   return(flag);
8165}
8166
8167USHORT
8168SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
8169{
8170   USHORT flag, length, i;
8171   unsigned char chksum,gotcha;
8172
8173   if(DDCdatatype > 3) return 0xFFFF;  /* incomplete! */
8174
8175   flag = 0;
8176   SiS_SetSwitchDDC2(SiS_Pr);
8177   if(!(SiS_PrepareDDC(SiS_Pr))) {
8178      length = 127;
8179      if(DDCdatatype != 1) length = 255;
8180      chksum = 0;
8181      gotcha = 0;
8182      for(i=0; i<length; i++) {
8183         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
8184	 chksum += buffer[i];
8185	 gotcha |= buffer[i];
8186	 SiS_SendACK(SiS_Pr, 0);
8187      }
8188      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
8189      chksum += buffer[i];
8190      SiS_SendACK(SiS_Pr, 1);
8191      if(gotcha) flag = (USHORT)chksum;
8192      else flag = 0xFFFF;
8193   } else {
8194      flag = 0xFFFF;
8195   }
8196   SiS_SetStop(SiS_Pr);
8197   return(flag);
8198}
8199
8200/* TW: Our private DDC function
8201
8202   It complies somewhat with the corresponding VESA function
8203   in arguments and return values.
8204
8205   Since this is probably called before the mode is changed,
8206   we use our pre-detected pSiS-values instead of SiS_Pr as
8207   regards chipset and video bridge type.
8208
8209   Arguments:
8210       adaptnum: 0=CRT1, 1=CRT2
8211                 CRT2 DDC is not supported in some cases.
8212       DDCdatatype: 0=Probe, 1=EDID, 2=VDIF(not supported), 3=?, 4=?(not supported)
8213       buffer: ptr to 256 data bytes which will be filled with read data.
8214
8215   Returns 0xFFFF if error, otherwise
8216       if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
8217       if DDCdatatype = 0:  Returns supported DDC modes
8218
8219 */
8220USHORT
8221SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
8222              USHORT DDCdatatype, unsigned char *buffer)
8223{
8224   if(DDCdatatype == 2) return 0xFFFF;
8225   if(adaptnum > 2) return 0xFFFF;
8226   if(pSiS->VGAEngine == SIS_300_VGA) {
8227      if((adaptnum != 0) && (DDCdatatype != 0)) return 0xFFFF;
8228   }
8229   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
8230   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype) == 0xFFFF) return 0xFFFF;
8231   if(DDCdatatype == 0) {
8232       return(SiS_ProbeDDC(SiS_Pr));
8233   } else {
8234       if(DDCdatatype > 4) return 0xFFFF;
8235       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
8236   }
8237}
8238
8239/* TW: Generic I2C functions (compliant to i2c library) */
8240
8241
8242#endif
8243
8244void
8245SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
8246{
8247  USHORT tempal,tempah,tempbl;
8248
8249  tempal = tempax & 0x00FF;
8250  tempah =(tempax >> 8) & 0x00FF;
8251  tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
8252  tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
8253  SiS_SetCH70xx(SiS_Pr,tempbl);
8254}
8255
8256/* TW: Generic I2C functions for Chrontel --------- */
8257
8258void
8259SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
8260{
8261  SiS_SetSCLKHigh(SiS_Pr);
8262  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
8263  SiS_WaitRetraceDDC(SiS_Pr);
8264
8265  SiS_SetSCLKLow(SiS_Pr);
8266  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
8267  SiS_WaitRetraceDDC(SiS_Pr);
8268}
8269
8270/* TW: Set I2C start condition */
8271/* TW: This is done by a SD high-to-low transition while SC is high */
8272USHORT
8273SiS_SetStart(SiS_Private *SiS_Pr)
8274{
8275  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
8276  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8277                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
8278  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
8279  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8280                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
8281  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
8282  return 0;
8283}
8284
8285/* TW: Set I2C stop condition */
8286/* TW: This is done by a SD low-to-high transition while SC is high */
8287USHORT
8288SiS_SetStop(SiS_Private *SiS_Pr)
8289{
8290  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
8291  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8292                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
8293  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
8294  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8295                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
8296  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
8297  return 0;
8298}
8299
8300/* TW: Write 8 bits of data */
8301USHORT
8302SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
8303{
8304  USHORT i,flag,temp;
8305
8306  flag=0x80;
8307  for(i=0;i<8;i++) {
8308    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
8309    if(tempax & flag) {
8310      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8311                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
8312    } else {
8313      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8314                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
8315    }
8316    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
8317    flag >>= 1;
8318  }
8319  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
8320  return(temp);
8321}
8322
8323USHORT
8324SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
8325{
8326  USHORT i,temp,getdata;
8327
8328  getdata=0;
8329  for(i=0; i<8; i++) {
8330    getdata <<= 1;
8331    SiS_SetSCLKLow(SiS_Pr);
8332    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8333                    ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);
8334    SiS_SetSCLKHigh(SiS_Pr);
8335    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
8336    if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
8337  }
8338  return(getdata);
8339}
8340
8341USHORT
8342SiS_SetSCLKLow(SiS_Private *SiS_Pr)
8343{
8344  USHORT temp, watchdog=50000;
8345
8346  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8347                  ~SiS_Pr->SiS_DDC_Clk,0x00);      		/* SetSCLKLow()  */
8348  do {
8349    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
8350  } while((temp & SiS_Pr->SiS_DDC_Clk) && --watchdog);
8351  if (!watchdog) return 0xFFFF;
8352  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8353  return 0;
8354}
8355
8356USHORT
8357SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
8358{
8359  USHORT temp,watchdog=50000;
8360
8361  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8362                  ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk);  	/* SetSCLKHigh()  */
8363  do {
8364    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
8365  } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
8366  if (!watchdog) return 0xFFFF;
8367  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8368  return 0;
8369}
8370
8371void
8372SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
8373{
8374  USHORT i;
8375
8376  for(i=0; i<delaytime; i++) {
8377    SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
8378  }
8379}
8380
8381/* TW: Check I2C acknowledge */
8382/* Returns 0 if ack ok, non-0 if ack not ok */
8383USHORT
8384SiS_CheckACK(SiS_Private *SiS_Pr)
8385{
8386  USHORT tempah;
8387
8388  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
8389  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
8390                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
8391  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
8392  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
8393  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
8394  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
8395  else return(0);
8396}
8397
8398/* TW: End of I2C functions ----------------------- */
8399
8400
8401/* =============== SiS 310/325 O.E.M. ================= */
8402
8403#ifdef SIS315H
8404
8405USHORT
8406GetLCDPtrIndex(SiS_Private *SiS_Pr)
8407{
8408  USHORT index;
8409
8410  index = SiS_Pr->SiS_LCDResInfo & 0x0F;
8411  index--;
8412  index *= 3;
8413  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) index += 2;
8414  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
8415
8416  return index;
8417}
8418
8419/*
8420---------------------------------------------------------
8421       GetTVPtrIndex()
8422          return       0 : NTSC Enhanced/Standard
8423                       1 : NTSC Standard TVSimuMode
8424                       2 : PAL Enhanced/Standard
8425                       3 : PAL Standard TVSimuMode
8426                       4 : HiVision Enhanced/Standard
8427                       5 : HiVision Standard TVSimuMode
8428---------------------------------------------------------
8429*/
8430USHORT
8431GetTVPtrIndex(SiS_Private *SiS_Pr)
8432{
8433  USHORT index;
8434
8435  index = 0;
8436  if(SiS_Pr->SiS_VBInfo & SetPALTV) index++;
8437  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++;  /* Hivision TV use PAL */
8438
8439  index <<= 1;
8440
8441  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode))
8442    index++;
8443
8444  return index;
8445}
8446
8447/* TW: Checked against 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (including data) */
8448void
8449SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8450             UCHAR *ROMAddr,USHORT ModeNo)
8451{
8452  USHORT delay,index;
8453
8454  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
8455     delay = SiS310_CRT2DelayCompensation1;
8456     if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B))
8457       delay = SiS310_CRT2DelayCompensation2;
8458     if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
8459       delay = SiS310_CRT2DelayCompensation3;
8460  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8461     index = GetLCDPtrIndex(SiS_Pr);
8462     delay = SiS310_LCDDelayCompensation1[index];
8463     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
8464       delay = SiS310_LCDDelayCompensation2[index];
8465     if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
8466       delay = SiS310_LCDDelayCompensation3[index];
8467  } else {
8468     index = GetTVPtrIndex(SiS_Pr);
8469     delay = SiS310_TVDelayCompensation1[index];
8470     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
8471       delay = SiS310_TVDelayCompensation2[index];
8472     if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
8473       delay = SiS310_TVDelayCompensation3[index];
8474  }
8475
8476  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8477    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8478       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
8479    } else {
8480       delay <<= 4;
8481       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
8482    }
8483  } else {
8484     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
8485  }
8486}
8487
8488/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
8489void
8490SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8491               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8492{
8493  USHORT index,temp;
8494
8495  temp = GetTVPtrIndex(SiS_Pr);
8496  temp >>= 1;  	  /* 0: NTSC, 1: PAL, 2: HiTV */
8497
8498  if (ModeNo<=0x13)
8499    index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
8500  else
8501    index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
8502
8503  temp = SiS310_TVAntiFlick1[temp][index];
8504  temp <<= 4;
8505
8506  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
8507}
8508
8509/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
8510void
8511SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8512               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8513{
8514  USHORT index,temp;
8515
8516  temp = GetTVPtrIndex(SiS_Pr);
8517  temp >>= 1;              	/* 0: NTSC, 1: PAL, 2: HiTV */
8518
8519  if (ModeNo<=0x13)
8520    index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
8521  else
8522    index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
8523
8524  temp = SiS310_TVEdge1[temp][index];
8525  temp <<= 5;
8526  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
8527}
8528
8529/* TW: Checked against 650/301LVx 1.10.6s BIOS (incl data) */
8530void
8531SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8532           UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8533{
8534  USHORT index, temp, i, j;
8535  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
8536
8537  temp = GetTVPtrIndex(SiS_Pr);
8538  temp >>= 1;  			/* 0: NTSC, 1: PAL, 2: HiTV */
8539
8540  if (ModeNo<=0x13) {
8541    index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
8542  } else {
8543    index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
8544  }
8545
8546  if(SiS_Pr->SiS_VBInfo&SetCRT2ToHiVisionTV)  temp = 1;  /* Hivision TV uses PAL */
8547
8548  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8549    for(i=0x35, j=0; i<=0x38; i++, j++) {
8550       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
8551    }
8552    for(i=0x48; i<=0x4A; i++, j++) {
8553       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
8554    }
8555  } else {
8556    for(i=0x35, j=0; i<=0x38; i++, j++){
8557       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
8558    }
8559  }
8560
8561  if(ROMAddr && SiS_Pr->SiS_UseROM) {
8562  	OutputSelect = ROMAddr[0xf3];
8563  }
8564  if(OutputSelect & EnablePALMN) {
8565      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
8566         temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
8567         temp &= (EnablePALMN | EnablePALN);
8568         if(temp == EnablePALMN) {
8569              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8570                 for(i=0x35, j=0; i<=0x38; i++, j++){
8571                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
8572                 }
8573                 for(i=0x48; i<=0x4A; i++, j++) {
8574                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
8575                 }
8576              } else {
8577                 for(i=0x35, j=0; i<=0x38; i++, j++) {
8578                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
8579                 }
8580              }
8581         }
8582         if(temp == EnablePALN) {
8583              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8584                 for(i=0x35, j=0; i<=0x38; i++, j++) {
8585                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
8586                 }
8587                 for(i=0x48, j=0; i<=0x4A; i++, j++) {
8588                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
8589                 }
8590             } else {
8591                 for(i=0x35, j=0; i<=0x38; i++, j++)
8592                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
8593             }
8594         }
8595      }
8596  }
8597}
8598
8599/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
8600void
8601SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8602             UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8603{
8604  USHORT index,temp,temp1,i,j,resinfo;
8605
8606  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
8607
8608  temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
8609  temp1 &=  (EnablePALMN | EnablePALN);
8610  if(temp1) return;
8611
8612
8613  if (ModeNo<=0x13) {
8614    resinfo =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
8615  } else {
8616    resinfo =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
8617  }
8618
8619  temp = GetTVPtrIndex(SiS_Pr);
8620  /* 0: NTSC Graphics, 1: NTSC Text,    2:PAL Graphics,
8621   * 3: PAL Text,      4: HiTV Graphics 5:HiTV Text
8622   */
8623  index = temp % 2;
8624  temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
8625
8626  for(j=0, i=0x31; i<=0x34; i++, j++) {
8627     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
8628	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
8629     else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode))
8630          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
8631     else
8632          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
8633  }
8634  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
8635     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
8636        if(resinfo == 6) {
8637	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
8638	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
8639	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
8640	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
8641	} else if (resinfo == 7) {
8642	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
8643	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
8644	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
8645	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
8646	} else if (resinfo == 8) {
8647	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
8648	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
8649	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
8650	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b);
8651	}
8652     }
8653  }
8654}
8655
8656void
8657SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8658                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8659{
8660   SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
8661   /* TW: The TV funtions are not for LVDS */
8662   if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
8663       SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8664       SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8665       SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8666       if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
8667          SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8668       }
8669   }
8670}
8671
8672/* TW: New from 650/301LVx 1.10.6s - clashes with OEMLCD() */
8673void
8674SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
8675                USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
8676{
8677  USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
8678  USHORT resinfo;
8679
8680  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
8681
8682  if(ModeNo<=0x13) {
8683	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
8684  } else {
8685    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
8686  }
8687
8688  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8689     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
8690        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
8691	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
8692	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
8693     }
8694     tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
8695     tempch &= 0xf0;
8696     tempch >>= 4;
8697     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
8698	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
8699	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
8700	}
8701     } else {
8702        tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
8703	tempcl &= 0x0f;
8704	tempbh &= 0x70;
8705	tempbh >>= 4;
8706	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
8707	tempbx = (tempbh << 8) | tempbl;
8708	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
8709	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding))) {
8710	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
8711	      	tempbx = 770;
8712	      } else {
8713	        if(tempbx > 770) tempbx = 770;
8714		if(SiS_Pr->SiS_VGAVDE < 600) {                   /* Shouldn't that be <=? */
8715		   tempax = 768 - SiS_Pr->SiS_VGAVDE;
8716		   tempax >>= 3;
8717		   if(SiS_Pr->SiS_VGAVDE < 480)  tempax >>= 1;   /* Shouldn't that be <=? */
8718		   tempbx -= tempax;
8719		}
8720	      }
8721	   } else return;
8722	}
8723	temp = tempbx & 0xff;
8724	SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
8725	temp = (tempbx & 0xff00) >> 8;
8726	temp <<= 4;
8727	temp |= tempcl;
8728	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
8729     }
8730  }
8731}
8732
8733/* TW: New and checked from 650/301LV BIOS */
8734/* This might clash with newer "FinalizeLCD()" function */
8735void
8736SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8737                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8738{
8739   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
8740
8741   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
8742
8743   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
8744      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
8745      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
8746      tempbh &= 0x38;
8747      tempbh >>= 3;
8748      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
8749      tempbx = (tempbh << 8) | tempbl;
8750      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
8751      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
8752      tempah = (tempbx & 0xff00) >> 8;
8753      tempah &= 0x07;
8754      tempah <<= 3;
8755      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
8756      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
8757      tempah &= 0x0f;
8758      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
8759      tempah &= 0x0f;
8760      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
8761      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
8762      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
8763      tempah -= 8;
8764      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
8765   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8766      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
8767      tempbh &= 0x70;
8768      tempbh >>= 4;
8769      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
8770      tempbx = (tempbh << 8) | tempbl;
8771      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
8772           tempbx -= 0x1e;
8773	   tempcl &= 0x0f;
8774	   tempcl -= 4;
8775	   tempcl &= 0x0f;
8776      }
8777      tempbl = tempbx & 0x00ff;
8778      tempbh = (tempbx >> 8) & 0x00ff;
8779      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
8780      tempbh <<= 4;
8781      tempbh |= tempcl;
8782      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
8783   }
8784}
8785#endif
8786
8787
8788/*  =================  SiS 300 O.E.M. ================== */
8789
8790#ifdef SIS300
8791
8792
8793/* TW: Checked against 630/301B BIOS (incl data) */
8794USHORT
8795GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag)
8796{
8797  USHORT tempbx=0;
8798  UCHAR customtable[] = {
8799  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
8800	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
8801  };
8802
8803  if(Flag) {
8804      if(customtable[SiS_Pr->SiS_LCDTypeInfo] == 0xFF) return 0xFFFF;
8805  }
8806  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
8807        tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
8808	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
8809	if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
8810  } else {
8811  	tempbx = SiS_Pr->SiS_LCDTypeInfo;
8812	if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
8813  }
8814  return tempbx;
8815}
8816
8817/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
8818void
8819SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8820               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8821{
8822  USHORT index,temp;
8823
8824  /* TW: The Panel Compensation Delay should be set according to tables
8825   *     here. Unfortunately, the different BIOS versions don't case about
8826   *     a uniform way using eg. ROM byte 0x220, but use different
8827   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). So we can't
8828   *     rely on the other OEM bits in 0x237, 0x238 here either.
8829   *     ROMAddr > 0x233 is even used for code (!) in newer BIOSes!
8830   */
8831  /* TW: We just check if a non-standard delay has been set; if not,
8832   * we use our tables. Otherwise don't do anything here.
8833   */
8834  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
8835     if(ROMAddr[0x220] & 0x80) return;
8836  }
8837  /* TW: We don't need to set this if the user select a custom pdc */
8838  if(HwDeviceExtension->pdc) return;
8839
8840  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, 0);
8841
8842  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
8843
8844  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
8845    	temp = SiS300_OEMLCDDelay2[temp][index];
8846  } else {
8847        temp = SiS300_OEMLCDDelay3[temp][index];
8848  }
8849  temp &= 0x3c;
8850  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
8851}
8852
8853/* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS */
8854USHORT
8855GetOEMTVPtr(SiS_Private *SiS_Pr)
8856{
8857  USHORT index;
8858
8859  index = 0;
8860  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
8861  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
8862     if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
8863     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
8864     else if(SiS_Pr->SiS_VBInfo & SetPALTV)   index += 1;
8865  } else {
8866     if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2;
8867     if(SiS_Pr->SiS_VBInfo & SetPALTV)        index += 1;
8868  }
8869  return index;
8870}
8871
8872/* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS (incl data) */
8873void
8874SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8875              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8876{
8877  USHORT index,temp;
8878
8879  temp = GetOEMTVPtr(SiS_Pr);
8880
8881  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
8882
8883  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
8884     temp = SiS300_OEMTVDelay301[temp][index];
8885  } else {
8886     temp = SiS300_OEMTVDelayLVDS[temp][index];
8887  }
8888  temp &= 0x3c;
8889  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
8890}
8891
8892/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
8893void
8894SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
8895                  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
8896		  USHORT ModeIdIndex)
8897{
8898  USHORT index,temp;
8899
8900  temp = GetOEMTVPtr(SiS_Pr);
8901
8902  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
8903
8904  temp = SiS300_OEMTVFlicker[temp][index];
8905  temp &= 0x70;
8906  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
8907}
8908
8909/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
8910void
8911SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8912                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8913{
8914  USHORT index,i,j,temp;
8915
8916  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return;
8917
8918  temp = GetOEMTVPtr(SiS_Pr);
8919
8920  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
8921
8922  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8923       for(i=0x31, j=0; i<=0x34; i++, j++) {
8924          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
8925       }
8926  } else {
8927       for(i=0x31, j=0; i<=0x34; i++, j++) {
8928          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
8929       }
8930  }
8931}
8932
8933/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
8934void
8935SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
8936              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
8937{
8938  USHORT index,temp,temp1,i,j;
8939
8940  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
8941
8942  temp = GetOEMTVPtr(SiS_Pr);
8943
8944  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
8945
8946  if(HwDeviceExtension->jChipType > SIS_300) {
8947     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
8948       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
8949       if(temp1 & (EnablePALMN | EnablePALN)) {
8950          temp = 8;
8951	  if(temp1 & EnablePALN) temp = 9;
8952       }
8953     }
8954  }
8955  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
8956      for(i=0x35, j=0; i<=0x38; i++, j++) {
8957       	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
8958      }
8959      for(i=0x48; i<=0x4A; i++, j++) {
8960     	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
8961      }
8962  } else {
8963      for(i=0x35, j=0; i<=0x38; i++, j++) {
8964       	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
8965      }
8966  }
8967}
8968
8969void
8970SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
8971		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
8972{
8973  USHORT ModeIdIndex;
8974
8975  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
8976  if(!(ModeIdIndex)) return;
8977
8978  if (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
8979       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8980  }
8981  if (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8982       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8983       if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
8984       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8985    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8986       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
8987       }
8988  }
8989}
8990#endif
8991
8992
8993