1 /*
2  * Mode initializing code (CRT2 section)
3  * for SiS 300/305/540/630/730,
4  *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
5  *     XGI V3XT/V5/V8, Z7
6  * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
7  *
8  * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
9  *
10  * If distributed as part of the Linux kernel, the following license terms
11  * apply:
12  *
13  * * This program is free software; you can redistribute it and/or modify
14  * * it under the terms of the GNU General Public License as published by
15  * * the Free Software Foundation; either version 2 of the named License,
16  * * or any later version.
17  * *
18  * * This program is distributed in the hope that it will be useful,
19  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * * GNU General Public License for more details.
22  * *
23  * * You should have received a copy of the GNU General Public License
24  * * along with this program; if not, write to the Free Software
25  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
26  *
27  * Otherwise, the following license terms apply:
28  *
29  * * Redistribution and use in source and binary forms, with or without
30  * * modification, are permitted provided that the following conditions
31  * * are met:
32  * * 1) Redistributions of source code must retain the above copyright
33  * *    notice, this list of conditions and the following disclaimer.
34  * * 2) Redistributions in binary form must reproduce the above copyright
35  * *    notice, this list of conditions and the following disclaimer in the
36  * *    documentation and/or other materials provided with the distribution.
37  * * 3) The name of the author may not be used to endorse or promote products
38  * *    derived from this software without specific prior written permission.
39  * *
40  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
43  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
44  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
46  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
47  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
49  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50  *
51  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
52  *
53  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
54  * Used by permission.
55  *
56  */
57 
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61 
62 #if 1
63 #define SET_EMI		/* 302LV/ELV: Set EMI values */
64 #endif
65 
66 #if 1
67 #define SET_PWD		/* 301/302LV: Set PWD */
68 #endif
69 
70 #define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */
71 #define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */
72 #define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */
73 
74 #include "init301.h"
75 
76 #ifdef SIS300
77 #include "oem300.h"
78 #endif
79 
80 #ifdef SIS315H
81 #include "oem310.h"
82 #endif
83 
84 #define SiS_I2CDELAY      1000
85 #define SiS_I2CDELAYSHORT  150
86 
87 static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
88 #ifdef SIS_LINUX_KERNEL
89 static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
90 #endif
91 
92 /*********************************************/
93 /*         HELPER: Lock/Unlock CRT2          */
94 /*********************************************/
95 
96 void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)97 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
98 {
99    if(SiS_Pr->ChipType == XGI_20)
100       return;
101    else if(SiS_Pr->ChipType >= SIS_315H)
102       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
103    else
104       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
105 }
106 
107 #ifdef SIS_LINUX_KERNEL
108 static
109 #endif
110 void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)111 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
112 {
113    if(SiS_Pr->ChipType == XGI_20)
114       return;
115    else if(SiS_Pr->ChipType >= SIS_315H)
116       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
117    else
118       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
119 }
120 
121 /*********************************************/
122 /*            HELPER: Write SR11             */
123 /*********************************************/
124 
125 static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)126 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND,
127 							unsigned short DataOR)
128 {
129    if(SiS_Pr->ChipType >= SIS_661) {
130       DataAND &= 0x0f;
131       DataOR  &= 0x0f;
132    }
133    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
134 }
135 
136 /*********************************************/
137 /*    HELPER: Get Pointer to LCD structure   */
138 /*********************************************/
139 
140 #ifdef SIS315H
141 static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)142 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
143 {
144    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
145    unsigned char  *myptr = NULL;
146    unsigned short romindex = 0, reg = 0, idx = 0;
147 
148    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
149     * due to the variaty of panels the BIOS doesn't know about.
150     * Exception: If the BIOS has better knowledge (such as in case
151     * of machines with a 301C and a panel that does not support DDC)
152     * use the BIOS data as well.
153     */
154 
155    if((SiS_Pr->SiS_ROMNew) &&
156       ( (SiS_Pr->SiS_VBType & VB_SISLVDS) ||
157         (!SiS_Pr->PanelSelfDetected) )) {
158 
159       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
160       else                           reg = 0x7d;
161 
162       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
163 
164       if(idx < (8*26)) {
165          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
166       }
167       romindex = SISGETROMW(0x100);
168       if(romindex) {
169          romindex += idx;
170          myptr = &ROMAddr[romindex];
171       }
172    }
173    return myptr;
174 }
175 
176 static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
178 {
179    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
180    unsigned short romptr = 0;
181 
182    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183     * due to the variaty of panels the BIOS doesn't know about.
184     * Exception: If the BIOS has better knowledge (such as in case
185     * of machines with a 301C and a panel that does not support DDC)
186     * use the BIOS data as well.
187     */
188 
189    if((SiS_Pr->SiS_ROMNew) &&
190       ( (SiS_Pr->SiS_VBType & VB_SISLVDS) ||
191         (!SiS_Pr->PanelSelfDetected) )) {
192       romptr = SISGETROMW(0x102);
193       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
194    }
195 
196    return romptr;
197 }
198 #endif
199 
200 /*********************************************/
201 /*           Adjust Rate for CRT2            */
202 /*********************************************/
203 
204 static BOOLEAN
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)205 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
206 		unsigned short RRTI, unsigned short *i)
207 {
208    unsigned short checkmask=0, modeid, infoflag;
209 
210    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
211 
212    if(SiS_Pr->SiS_VBType & VB_SISVB) {
213 
214       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
215 
216 	 checkmask |= SupportRAMDAC2;
217 	 if(SiS_Pr->ChipType >= SIS_315H) {
218 	    checkmask |= SupportRAMDAC2_135;
219 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
220 	       checkmask |= SupportRAMDAC2_162;
221 	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
222 		  checkmask |= SupportRAMDAC2_202;
223 	       }
224 	    }
225 	 }
226 
227       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
228 
229 	 checkmask |= SupportLCD;
230 	 if(SiS_Pr->ChipType >= SIS_315H) {
231 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
232 	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
233 	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
234 	       }
235 	    }
236 	 }
237 
238       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
239 
240 	 checkmask |= SupportHiVision;
241 
242       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
243 
244 	 checkmask |= SupportTV;
245 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
246 	    checkmask |= SupportTV1024;
247 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
248 	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
249 	          checkmask |= SupportYPbPr750p;
250 	       }
251 	    }
252 	 }
253 
254       }
255 
256    } else {	/* LVDS */
257 
258       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
259 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
260 	    checkmask |= SupportCHTV;
261 	 }
262       }
263 
264       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
265 	 checkmask |= SupportLCD;
266       }
267 
268    }
269 
270    /* Look backwards in table for matching CRT2 mode */
271    for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
272       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
273       if(infoflag & checkmask) return TRUE;
274       if((*i) == 0) break;
275    }
276 
277    /* Look through the whole mode-section of the table from the beginning
278     * for a matching CRT2 mode if no mode was found yet.
279     */
280    for((*i) = 0; ; (*i)++) {
281       if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
282       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
283       if(infoflag & checkmask) return TRUE;
284    }
285    return FALSE;
286 }
287 
288 /*********************************************/
289 /*              Get rate index               */
290 /*********************************************/
291 
292 unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)293 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
294 {
295    unsigned short RRTI,i,backup_i;
296    unsigned short modeflag,index,temp,backupindex;
297    static const unsigned short LCDRefreshIndex[] = {
298 		0x00, 0x00, 0x01, 0x01,
299 		0x01, 0x01, 0x01, 0x01,
300 		0x01, 0x01, 0x01, 0x01,
301 		0x01, 0x01, 0x01, 0x01,
302 		0x00, 0x00, 0x00, 0x00
303    };
304 
305    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
306    if(ModeNo == 0xfe) return 0;
307 
308    if(ModeNo <= 0x13) {
309       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
310    } else {
311       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
312    }
313 
314    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
315       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
316 	 if(modeflag & HalfDCLK) return 0;
317       }
318    }
319 
320    if(ModeNo < 0x14) return 0xFFFF;
321 
322    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
323    backupindex = index;
324 
325    if(index > 0) index--;
326 
327    if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
328       if(SiS_Pr->SiS_VBType & VB_SISVB) {
329 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
330 	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
331 	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
332 	 }
333 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
334 	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
335 	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
336 	       if(index > temp) index = temp;
337 	    }
338 	 }
339       } else {
340 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
341 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
342 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
343 	 }
344       }
345    }
346 
347    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
348    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
349 
350    if(SiS_Pr->ChipType >= SIS_315H) {
351       if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
352 	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
353 	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
354 	    if(backupindex <= 1) RRTI++;
355 	 }
356       }
357    }
358 
359    i = 0;
360    do {
361       if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
362       temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
363       temp &= ModeTypeMask;
364       if(temp < SiS_Pr->SiS_ModeType) break;
365       i++;
366       index--;
367    } while(index != 0xFFFF);
368 
369    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
370       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
371 	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
372 	 if(temp & InterlaceMode) i++;
373       }
374    }
375 
376    i--;
377 
378    if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
379       backup_i = i;
380       if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
381 	 i = backup_i;
382       }
383    }
384 
385    return (RRTI + i);
386 }
387 
388 /*********************************************/
389 /*            STORE CRT2 INFO in CR34        */
390 /*********************************************/
391 
392 static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)393 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
394 {
395    unsigned short temp1, temp2;
396 
397    /* Store CRT1 ModeNo in CR34 */
398    SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
399    temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
400    temp2 = ~(SetInSlaveMode >> 8);
401    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
402 }
403 
404 /*********************************************/
405 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
406 /*********************************************/
407 
408 #ifdef SIS300
409 static BOOLEAN
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)410 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
411 {
412    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
413    unsigned short temp,temp1;
414 
415    if(SiS_Pr->SiS_UseROM) {
416       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
417 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
418 	 temp1 = SISGETROMW(0x23b);
419 	 if(temp1 & temp) return TRUE;
420       }
421    }
422    return FALSE;
423 }
424 
425 static BOOLEAN
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)426 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
427 {
428    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
429    unsigned short temp,temp1;
430 
431    if(SiS_Pr->SiS_UseROM) {
432       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
433 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
434 	 temp1 = SISGETROMW(0x23d);
435 	 if(temp1 & temp) return TRUE;
436       }
437    }
438    return FALSE;
439 }
440 #endif
441 
442 /*********************************************/
443 /*          HELPER: DELAY FUNCTIONS          */
444 /*********************************************/
445 
446 void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)447 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
448 {
449    unsigned int i, j = 0;
450 
451    for(i = 0; i < delaytime; i++) {
452       j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
453    }
454 }
455 
456 #if defined(SIS300) || defined(SIS315H)
457 static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)458 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
459 {
460    SiS_DDC2Delay(SiS_Pr, delay * 36);
461 }
462 #endif
463 
464 #ifdef SIS315H
465 static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)466 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
467 {
468    while(delay--) {
469       SiS_GenericDelay(SiS_Pr, 6623);
470    }
471 }
472 #endif
473 
474 #if defined(SIS300) || defined(SIS315H)
475 static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)476 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
477 {
478    while(delay--) {
479       SiS_GenericDelay(SiS_Pr, 66);
480    }
481 }
482 #endif
483 
484 static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)485 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
486 {
487 #if defined(SIS300) || defined(SIS315H)
488    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
489    unsigned short PanelID, DelayIndex, Delay=0;
490 #endif
491 
492    if(SiS_Pr->ChipType < SIS_315H) {
493 
494 #ifdef SIS300
495 
496       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
497       if(SiS_Pr->SiS_VBType & VB_SISVB) {
498 	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
499 	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
500       }
501       DelayIndex = PanelID >> 4;
502       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
503 	 Delay = 3;
504       } else {
505 	 if(DelayTime >= 2) DelayTime -= 2;
506 	 if(!(DelayTime & 0x01)) {
507 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
508 	 } else {
509 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
510 	 }
511 	 if(SiS_Pr->SiS_UseROM) {
512 	    if(ROMAddr[0x220] & 0x40) {
513 	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
514 	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
515 	    }
516 	 }
517       }
518       SiS_ShortDelay(SiS_Pr, Delay);
519 
520 #endif  /* SIS300 */
521 
522    } else {
523 
524 #ifdef SIS315H
525 
526       if((SiS_Pr->ChipType >= SIS_661)    ||
527 	 (SiS_Pr->ChipType <= SIS_315PRO) ||
528 	 (SiS_Pr->ChipType == SIS_330)    ||
529 	 (SiS_Pr->SiS_ROMNew)) {
530 
531 	 if(!(DelayTime & 0x01)) {
532 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
533 	 } else {
534 	    SiS_DDC2Delay(SiS_Pr, 0x4000);
535 	 }
536 
537       } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {				/* 315 series, LVDS; Special */
538 
539 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
540 	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
541 	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
542 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
543 	    }
544 	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
545 	       DelayIndex = PanelID & 0x0f;
546 	    } else {
547 	       DelayIndex = PanelID >> 4;
548 	    }
549 	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
550 	       Delay = 3;
551 	    } else {
552 	       if(DelayTime >= 2) DelayTime -= 2;
553 	       if(!(DelayTime & 0x01)) {
554 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
555 		} else {
556 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
557 	       }
558 	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
559 		  if(ROMAddr[0x13c] & 0x40) {
560 		     if(!(DelayTime & 0x01)) {
561 			Delay = (unsigned short)ROMAddr[0x17e];
562 		     } else {
563 			Delay = (unsigned short)ROMAddr[0x17f];
564 		     }
565 		  }
566 	       }
567 	    }
568 	    SiS_ShortDelay(SiS_Pr, Delay);
569 	 }
570 
571       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
572 
573 	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
574 	 if(!(DelayTime & 0x01)) {
575 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
576 	 } else {
577 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
578 	 }
579 	 Delay <<= 8;
580 	 SiS_DDC2Delay(SiS_Pr, Delay);
581 
582       }
583 
584 #endif /* SIS315H */
585 
586    }
587 }
588 
589 #ifdef SIS315H
590 static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)591 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
592 {
593    int i;
594    for(i = 0; i < DelayLoop; i++) {
595       SiS_PanelDelay(SiS_Pr, DelayTime);
596    }
597 }
598 #endif
599 
600 /*********************************************/
601 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
602 /*********************************************/
603 
604 void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)605 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
606 {
607    unsigned short watchdog;
608 
609    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
610    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
611 
612    watchdog = 65535;
613    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
614    watchdog = 65535;
615    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616 }
617 
618 #if defined(SIS300) || defined(SIS315H)
619 static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)620 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
621 {
622    unsigned short watchdog;
623 
624    watchdog = 65535;
625    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
626    watchdog = 65535;
627    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
628 }
629 #endif
630 
631 static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)632 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
633 {
634    if(SiS_Pr->ChipType < SIS_315H) {
635 #ifdef SIS300
636       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
637 	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
638       }
639       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
640 	 SiS_WaitRetrace1(SiS_Pr);
641       } else {
642 	 SiS_WaitRetrace2(SiS_Pr, 0x25);
643       }
644 #endif
645    } else {
646 #ifdef SIS315H
647       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
648 	 SiS_WaitRetrace1(SiS_Pr);
649       } else {
650 	 SiS_WaitRetrace2(SiS_Pr, 0x30);
651       }
652 #endif
653    }
654 }
655 
656 static void
SiS_VBWait(struct SiS_Private * SiS_Pr)657 SiS_VBWait(struct SiS_Private *SiS_Pr)
658 {
659    unsigned short tempal,temp,i,j;
660 
661    temp = 0;
662    for(i = 0; i < 3; i++) {
663      for(j = 0; j < 100; j++) {
664         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
665         if(temp & 0x01) {
666 	   if((tempal & 0x08))  continue;
667 	   else break;
668         } else {
669 	   if(!(tempal & 0x08)) continue;
670 	   else break;
671         }
672      }
673      temp ^= 0x01;
674    }
675 }
676 
677 static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)678 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
679 {
680    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681       SiS_VBWait(SiS_Pr);
682    } else {
683       SiS_WaitRetrace1(SiS_Pr);
684    }
685 }
686 
687 /*********************************************/
688 /*               HELPER: MISC                */
689 /*********************************************/
690 
691 #ifdef SIS300
692 static BOOLEAN
SiS_Is301B(struct SiS_Private * SiS_Pr)693 SiS_Is301B(struct SiS_Private *SiS_Pr)
694 {
695    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
696    return FALSE;
697 }
698 #endif
699 
700 static BOOLEAN
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)701 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
702 {
703    if(SiS_Pr->ChipType == SIS_730) {
704       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
705    }
706    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
707    return FALSE;
708 }
709 
710 BOOLEAN
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)711 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
712 {
713 #ifdef SIS315H
714    if(SiS_Pr->ChipType >= SIS_315H) {
715       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
716 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
717       }
718    }
719 #endif
720    return FALSE;
721 }
722 
723 BOOLEAN
SiS_IsVAMode(struct SiS_Private * SiS_Pr)724 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
725 {
726 #ifdef SIS315H
727    unsigned short flag;
728 
729    if(SiS_Pr->ChipType >= SIS_315H) {
730       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
731       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
732    }
733 #endif
734    return FALSE;
735 }
736 
737 #ifdef SIS315H
738 static BOOLEAN
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)739 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
740 {
741    if(SiS_IsVAMode(SiS_Pr))  return TRUE;
742    if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
743    return FALSE;
744 }
745 #endif
746 
747 static BOOLEAN
SiS_IsDualLink(struct SiS_Private * SiS_Pr)748 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
749 {
750 #ifdef SIS315H
751    if(SiS_Pr->ChipType >= SIS_315H) {
752       if((SiS_CRT2IsLCD(SiS_Pr)) ||
753          (SiS_IsVAMode(SiS_Pr))) {
754 	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
755       }
756    }
757 #endif
758    return FALSE;
759 }
760 
761 #ifdef SIS315H
762 static BOOLEAN
SiS_TVEnabled(struct SiS_Private * SiS_Pr)763 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
764 {
765    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
766    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
767       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
768    }
769    return FALSE;
770 }
771 #endif
772 
773 #ifdef SIS315H
774 static BOOLEAN
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)775 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
776 {
777    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
778    return FALSE;
779 }
780 #endif
781 
782 #ifdef SIS315H
783 static BOOLEAN
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)784 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
785 {
786    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
787       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
788    }
789    return FALSE;
790 }
791 #endif
792 
793 #ifdef SIS315H
794 static BOOLEAN
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)795 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
796 {
797    unsigned short flag;
798 
799    if(SiS_Pr->ChipType == SIS_650) {
800       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
801       /* Check for revision != A0 only */
802       if((flag == 0xe0) || (flag == 0xc0) ||
803          (flag == 0xb0) || (flag == 0x90)) return FALSE;
804    } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
805    return TRUE;
806 }
807 #endif
808 
809 #ifdef SIS315H
810 static BOOLEAN
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)811 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
812 {
813    if(SiS_Pr->ChipType >= SIS_315H) {
814       /* YPrPb = 0x08 */
815       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
816    }
817    return FALSE;
818 }
819 #endif
820 
821 #ifdef SIS315H
822 static BOOLEAN
SiS_IsChScart(struct SiS_Private * SiS_Pr)823 SiS_IsChScart(struct SiS_Private *SiS_Pr)
824 {
825    if(SiS_Pr->ChipType >= SIS_315H) {
826       /* Scart = 0x04 */
827       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
828    }
829    return FALSE;
830 }
831 #endif
832 
833 #ifdef SIS315H
834 static BOOLEAN
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)835 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
836 {
837    unsigned short flag;
838 
839    if(SiS_Pr->ChipType >= SIS_315H) {
840       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
841       if(flag & SetCRT2ToTV)        return TRUE;
842       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
843       if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
844       if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
845    } else {
846       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
847       if(flag & SetCRT2ToTV)        return TRUE;
848    }
849    return FALSE;
850 }
851 #endif
852 
853 #ifdef SIS315H
854 static BOOLEAN
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)855 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
856 {
857    unsigned short flag;
858 
859    if(SiS_Pr->ChipType >= SIS_315H) {
860       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
861       if(flag & SetCRT2ToLCD) return TRUE;
862       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
863       if(flag & SetToLCDA)    return TRUE;
864    } else {
865       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
866       if(flag & SetCRT2ToLCD) return TRUE;
867    }
868    return FALSE;
869 }
870 #endif
871 
872 static BOOLEAN
SiS_HaveBridge(struct SiS_Private * SiS_Pr)873 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
874 {
875    unsigned short flag;
876 
877    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
878       return TRUE;
879    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
880       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
881       if((flag == 1) || (flag == 2)) return TRUE;
882    }
883    return FALSE;
884 }
885 
886 static BOOLEAN
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)887 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
888 {
889    unsigned short flag;
890 
891    if(SiS_HaveBridge(SiS_Pr)) {
892       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
893       if(SiS_Pr->ChipType < SIS_315H) {
894 	flag &= 0xa0;
895 	if((flag == 0x80) || (flag == 0x20)) return TRUE;
896       } else {
897 	flag &= 0x50;
898 	if((flag == 0x40) || (flag == 0x10)) return TRUE;
899       }
900    }
901    return FALSE;
902 }
903 
904 static BOOLEAN
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)905 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
906 {
907    unsigned short flag1;
908 
909    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
910    if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
911    return FALSE;
912 }
913 
914 /*********************************************/
915 /*       GET VIDEO BRIDGE CONFIG INFO        */
916 /*********************************************/
917 
918 /* Setup general purpose IO for Chrontel communication */
919 #ifdef SIS300
920 void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)921 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
922 {
923    unsigned int   acpibase;
924    unsigned short temp;
925 
926    if(!(SiS_Pr->SiS_ChSW)) return;
927 
928 #ifdef SIS_LINUX_KERNEL
929    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
930 #else
931    acpibase = sis_pci_read_device_u32(1, 0x74);
932 #endif
933    acpibase &= 0xFFFF;
934    if(!acpibase) return;
935    temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
936    temp &= 0xFEFF;
937    SiS_SetRegShort((acpibase + 0x3c), temp);
938    temp = SiS_GetRegShort((acpibase + 0x3c));
939    temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
940    temp &= 0xFEFF;
941    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
942    SiS_SetRegShort((acpibase + 0x3a), temp);
943    temp = SiS_GetRegShort((acpibase + 0x3a));
944 }
945 #endif
946 
947 void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)948 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
949 		unsigned short ModeIdIndex, int checkcrt2mode)
950 {
951    unsigned short tempax, tempbx, temp;
952    unsigned short modeflag, resinfo = 0;
953 
954    SiS_Pr->SiS_SetFlag = 0;
955 
956    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
957 
958    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
959 
960    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
961       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
962    }
963 
964    tempbx = 0;
965 
966    if(SiS_HaveBridge(SiS_Pr)) {
967 
968 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
969 	tempbx |= temp;
970 	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
971 	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
972 	tempbx |= tempax;
973 
974 #ifdef SIS315H
975 	if(SiS_Pr->ChipType >= SIS_315H) {
976 	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
977 	      if(ModeNo == 0x03) {
978 		 /* Mode 0x03 is never in driver mode */
979 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
980 	      }
981 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
982 		 /* Reset LCDA setting if not driver mode */
983 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 	      }
985 	      if(IS_SIS650) {
986 		 if(SiS_Pr->SiS_UseLCDA) {
987 		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
988 		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
989 			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
990 		       }
991 		    }
992 		 }
993 	      }
994 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
995 	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
996 		 tempbx |= SetCRT2ToLCDA;
997 	      }
998 	   }
999 
1000 	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1001 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1002 	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1003 		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1004 		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1005 		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1006 		    tempbx |= SetCRT2ToYPbPr525750;
1007 		 }
1008 	      }
1009 	   }
1010 
1011 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1012 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1013 	      if(temp & SetToLCDA) {
1014 		 tempbx |= SetCRT2ToLCDA;
1015 	      }
1016 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1017 		 if(temp & EnableCHYPbPr) {
1018 		    tempbx |= SetCRT2ToCHYPbPr;
1019 		 }
1020 	      }
1021 	   }
1022 	}
1023 
1024 #endif  /* SIS315H */
1025 
1026         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1027 	   tempbx &= ~(SetCRT2ToRAMDAC);
1028 	}
1029 
1030 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1031 	   temp = SetCRT2ToSVIDEO   |
1032 		  SetCRT2ToAVIDEO   |
1033 		  SetCRT2ToSCART    |
1034 		  SetCRT2ToLCDA     |
1035 		  SetCRT2ToLCD      |
1036 		  SetCRT2ToRAMDAC   |
1037 		  SetCRT2ToHiVision |
1038 		  SetCRT2ToYPbPr525750;
1039 	} else {
1040 	   if(SiS_Pr->ChipType >= SIS_315H) {
1041 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1042 		 temp = SetCRT2ToAVIDEO |
1043 		        SetCRT2ToSVIDEO |
1044 		        SetCRT2ToSCART  |
1045 		        SetCRT2ToLCDA   |
1046 		        SetCRT2ToLCD    |
1047 		        SetCRT2ToCHYPbPr;
1048 	      } else {
1049 		 temp = SetCRT2ToLCDA   |
1050 		        SetCRT2ToLCD;
1051 	      }
1052 	   } else {
1053 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1054 		 temp = SetCRT2ToTV | SetCRT2ToLCD;
1055 	      } else {
1056 		 temp = SetCRT2ToLCD;
1057 	      }
1058 	   }
1059 	}
1060 
1061 	if(!(tempbx & temp)) {
1062 	   tempax = DisableCRT2Display;
1063 	   tempbx = 0;
1064 	}
1065 
1066 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1067 
1068 	   unsigned short clearmask = ( DriverMode |
1069 				DisableCRT2Display |
1070 				LoadDACFlag 	   |
1071 				SetNotSimuMode 	   |
1072 				SetInSlaveMode 	   |
1073 				SetPALTV 	   |
1074 				SwitchCRT2	   |
1075 				SetSimuScanMode );
1076 
1077 	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1078 	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1079 	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1080 	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1081 	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1082 	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1083 
1084 	} else {
1085 
1086 	   if(SiS_Pr->ChipType >= SIS_315H) {
1087 	      if(tempbx & SetCRT2ToLCDA) {
1088 		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1089 	      }
1090 	   }
1091 	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1092 	      if(tempbx & SetCRT2ToTV) {
1093 		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1094 	      }
1095 	   }
1096 	   if(tempbx & SetCRT2ToLCD) {
1097 	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1098 	   }
1099 	   if(SiS_Pr->ChipType >= SIS_315H) {
1100 	      if(tempbx & SetCRT2ToLCDA) {
1101 	         tempbx |= SetCRT2ToLCD;
1102 	      }
1103 	   }
1104 
1105 	}
1106 
1107 	if(tempax & DisableCRT2Display) {
1108 	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1109 	      tempbx = SetSimuScanMode | DisableCRT2Display;
1110 	   }
1111 	}
1112 
1113 	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1114 
1115 	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1116 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1117 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1118 	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1119 	      modeflag &= (~CRT2Mode);
1120 	   }
1121 	}
1122 
1123 	if(!(tempbx & SetSimuScanMode)) {
1124 	   if(tempbx & SwitchCRT2) {
1125 	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1126 		 if(resinfo != SIS_RI_1600x1200) {
1127 		    tempbx |= SetSimuScanMode;
1128 		 }
1129               }
1130 	   } else {
1131 	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
1132 		 if(!(tempbx & DriverMode)) {
1133 		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1134 		       tempbx |= SetSimuScanMode;
1135 		    }
1136 		 }
1137 	      }
1138 	   }
1139 	}
1140 
1141 	if(!(tempbx & DisableCRT2Display)) {
1142 	   if(tempbx & DriverMode) {
1143 	      if(tempbx & SetSimuScanMode) {
1144 		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1145 		    if(resinfo != SIS_RI_1600x1200) {
1146 		       tempbx |= SetInSlaveMode;
1147 		    }
1148 		 }
1149 	      }
1150 	   } else {
1151 	      tempbx |= SetInSlaveMode;
1152 	   }
1153 	}
1154 
1155    }
1156 
1157    SiS_Pr->SiS_VBInfo = tempbx;
1158 
1159 #ifdef SIS300
1160    if(SiS_Pr->ChipType == SIS_630) {
1161       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1162    }
1163 #endif
1164 
1165 #ifdef SIS_LINUX_KERNEL
1166 #if 0
1167    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1168       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1169 #endif
1170 #endif
1171 #ifdef SIS_XORG_XF86
1172 #ifdef TWDEBUG
1173    xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1174       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1175 #endif
1176 #endif
1177 }
1178 
1179 /*********************************************/
1180 /*           DETERMINE YPbPr MODE            */
1181 /*********************************************/
1182 
1183 void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1184 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1185 {
1186 
1187    unsigned char temp;
1188 
1189    /* Note: This variable is only used on 30xLV systems.
1190     * CR38 has a different meaning on LVDS/CH7019 systems.
1191     * On 661 and later, these bits moved to CR35.
1192     *
1193     * On 301, 301B, only HiVision 1080i is supported.
1194     * On 30xLV, 301C, only YPbPr 1080i is supported.
1195     */
1196 
1197    SiS_Pr->SiS_YPbPr = 0;
1198    if(SiS_Pr->ChipType >= SIS_661) return;
1199 
1200    if(SiS_Pr->SiS_VBType) {
1201       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1202 	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1203       }
1204    }
1205 
1206    if(SiS_Pr->ChipType >= SIS_315H) {
1207       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1208 	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1209 	 if(temp & 0x08) {
1210 	    switch((temp >> 4)) {
1211 	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1212 	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1213 	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1214 	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1215 	    }
1216 	 }
1217       }
1218    }
1219 
1220 }
1221 
1222 /*********************************************/
1223 /*           DETERMINE TVMode flag           */
1224 /*********************************************/
1225 
1226 void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1227 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1228 {
1229    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1230    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1231    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1232 
1233    SiS_Pr->SiS_TVMode = 0;
1234 
1235    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1236    if(SiS_Pr->UseCustomMode) return;
1237 
1238    if(ModeNo > 0x13) {
1239       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1240    }
1241 
1242    if(SiS_Pr->ChipType < SIS_661) {
1243 
1244       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1245 
1246       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1247 	 temp = 0;
1248 	 if((SiS_Pr->ChipType == SIS_630) ||
1249 	    (SiS_Pr->ChipType == SIS_730)) {
1250 	    temp = 0x35;
1251 	    romindex = 0xfe;
1252 	 } else if(SiS_Pr->ChipType >= SIS_315H) {
1253 	    temp = 0x38;
1254 	    if(SiS_Pr->ChipType < XGI_20) {
1255 	       romindex = 0xf3;
1256 	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1257 	    }
1258 	 }
1259 	 if(temp) {
1260 	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1261 	       OutputSelect = ROMAddr[romindex];
1262 	       if(!(OutputSelect & EnablePALMN)) {
1263 		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1264 	       }
1265 	    }
1266 	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1267 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1268 	       if(temp1 & EnablePALM) {		/* 0x40 */
1269 		  SiS_Pr->SiS_TVMode |= TVSetPALM;
1270 		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1271 	       } else if(temp1 & EnablePALN) {	/* 0x80 */
1272 		  SiS_Pr->SiS_TVMode |= TVSetPALN;
1273 	       }
1274 	    } else {
1275 	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
1276 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1277 	       }
1278 	    }
1279 	 }
1280 	 /* Translate HiVision/YPbPr to our new flags */
1281 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1282 	    if(SiS_Pr->SiS_YPbPr == YPbPr750p) {
1283 	       SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1284 	    } else if(SiS_Pr->SiS_YPbPr == YPbPr525p) {
1285 	       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1286 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr625p;
1287 	       } else {
1288 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1289 	       }
1290 	    } else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) {
1291 	       SiS_Pr->SiS_TVMode |= TVSetHiVision;
1292 	    } else {
1293 	       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1294 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr625i;
1295 	       } else {
1296 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1297 	       }
1298 	    }
1299 	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p |
1300 				     TVSetYPbPr525p |
1301 				     TVSetYPbPr625p |
1302 				     TVSetYPbPr525i |
1303 				     TVSetYPbPr625i)) {
1304 	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1305 	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1306 	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1307 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1308 	       SiS_Pr->SiS_TVMode |= TVSetPAL;
1309 	    }
1310 	 }
1311       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1312 	 if(SiS_Pr->SiS_CHOverScan) {
1313 	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1314 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1315 	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1316 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1317 	       }
1318 	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1319 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1320 	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1321 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1322 	       }
1323 	    }
1324 	    if(SiS_Pr->SiS_CHSOverScan) {
1325 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1326 	    }
1327 	 }
1328 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1329 	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1330 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1331 	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1332 	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1333 	    } else {
1334 	       if(temp & EnableNTSCJ) {
1335 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1336 	       }
1337 	    }
1338 	 }
1339       }
1340 
1341    } else {  /* 661 and later */
1342 
1343       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1344       if(temp1 & 0x01) {
1345 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1346 	 if(temp1 & 0x08) {
1347 	    SiS_Pr->SiS_TVMode |= TVSetPALN;
1348 	 } else if(temp1 & 0x04) {
1349 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1350 	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1351 	    }
1352 	    SiS_Pr->SiS_TVMode |= TVSetPALM;
1353 	 }
1354       } else {
1355 	 if(temp1 & 0x02) {
1356 	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1357 	 }
1358       }
1359       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1360 	 if(SiS_Pr->SiS_CHOverScan) {
1361 	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1362 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1363 	    }
1364 	 }
1365       }
1366       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1367 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1368 	    temp1 &= 0xe0;
1369 	    if(temp1 == 0x00) {
1370 	       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1371 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr625i;
1372 	       } else {
1373 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1374 	       }
1375 	    } else if(temp1 == 0x20) {
1376 	       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1377 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr625p;
1378 	       } else {
1379 	          SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1380 	       }
1381 	    } else if(temp1 == 0x40) {
1382 	       SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1383 	    }
1384 	    SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1385 	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1386 	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1387 	 }
1388 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1389 	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1390 	       SiS_Pr->SiS_TVMode |= TVAspect169;
1391 	    } else {
1392 	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1393 	       if(temp1 & 0x02) {
1394 		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1395 		     SiS_Pr->SiS_TVMode |= TVAspect169;
1396 		  } else {
1397 		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1398 		  }
1399 	       } else {
1400 		  SiS_Pr->SiS_TVMode |= TVAspect43;
1401 	       }
1402 	    }
1403 	 }
1404       }
1405    }
1406 
1407    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1408 
1409    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1410 
1411       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1412 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1413 	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1414       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1415 	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i |
1416 	 			  TVSetYPbPr625i |
1417 				  TVSetYPbPr525p |
1418 				  TVSetYPbPr625p |
1419 				  TVSetYPbPr750p)) {
1420 	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1421 	 }
1422       }
1423 
1424       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1425 	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1426 	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1427 	 }
1428       }
1429 
1430       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1431 	 if(resinfo == SIS_RI_1024x768) {
1432 	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1433 	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
1434 	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision  |
1435 	    				      TVSetYPbPr750p |
1436 					      TVSetYPbPr625p |
1437 					      TVSetYPbPr625i))) {
1438 	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1439 	    }
1440 	 }
1441       }
1442 
1443       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1444          if(resinfo == SIS_RI_960x540) {
1445 	    SiS_Pr->SiS_TVMode |= TVSetHiVi960540;
1446 	 }
1447       }
1448 
1449       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1450       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1451 	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1452 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1453       } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) {
1454 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1455       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1456 	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1457 	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1458 	 }
1459       }
1460 
1461    }
1462 
1463    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1464 
1465 #ifdef SIS_XORG_XF86
1466 #ifdef TWDEBUG
1467    xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1468 #endif
1469 #endif
1470 }
1471 
1472 /*********************************************/
1473 /*               GET LCD INFO                */
1474 /*********************************************/
1475 
1476 static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1477 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1478 {
1479    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1480    /* Translate my LCDResInfo to BIOS value */
1481    switch(temp) {
1482    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1483    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1484    case Panel_1280x854:   temp = Panel661_1280x854; break;
1485    }
1486    return temp;
1487 }
1488 
1489 static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1490 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1491 {
1492 #ifdef SIS315H
1493    unsigned char  *ROMAddr;
1494    unsigned short temp;
1495 
1496 #ifdef SIS_XORG_XF86
1497 #ifdef TWDEBUG
1498    xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1499 	SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1500 	SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1501 	SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1502 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1503 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1504 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1505 #endif
1506 #endif
1507 
1508    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1509       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1510 	 SiS_Pr->SiS_NeedRomModeData = TRUE;
1511 	 SiS_Pr->PanelHT  = temp;
1512       }
1513       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1514 	 SiS_Pr->SiS_NeedRomModeData = TRUE;
1515 	 SiS_Pr->PanelVT  = temp;
1516       }
1517       SiS_Pr->PanelHRS = SISGETROMW(10);
1518       SiS_Pr->PanelHRE = SISGETROMW(12);
1519       SiS_Pr->PanelVRS = SISGETROMW(14);
1520       SiS_Pr->PanelVRE = SISGETROMW(16);
1521       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1522       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1523 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1524       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1525 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1526       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1527 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1528 
1529 #ifdef SIS_XORG_XF86
1530 #ifdef TWDEBUG
1531       xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1532 	SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1533 	SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1534 	SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1535 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1536 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1537 	SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1538 #endif
1539 #endif
1540 
1541    }
1542 #endif
1543 }
1544 
1545 static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1546 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1547 			const unsigned char *nonscalingmodes)
1548 {
1549    int i = 0;
1550    while(nonscalingmodes[i] != 0xff) {
1551       if(nonscalingmodes[i++] == resinfo) {
1552 	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1553 	    (SiS_Pr->UsePanelScaler == -1)) {
1554 	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1555 	 }
1556 	 break;
1557       }
1558    }
1559 }
1560 
1561 void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1562 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1563 {
1564   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1565   BOOLEAN panelcanscale = FALSE;
1566 #ifdef SIS300
1567   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1568   static const unsigned char SiS300SeriesLCDRes[] =
1569           { 0,  1,  2,  3,  7,  4,  5,  8,
1570 	    0,  0, 10,  0,  0,  0,  0, 15 };
1571 #endif
1572 #ifdef SIS315H
1573   unsigned char   *myptr = NULL;
1574 #endif
1575 
1576   SiS_Pr->SiS_LCDResInfo  = 0;
1577   SiS_Pr->SiS_LCDTypeInfo = 0;
1578   SiS_Pr->SiS_LCDInfo     = 0;
1579   SiS_Pr->PanelHRS        = 999; /* HSync start */
1580   SiS_Pr->PanelHRE        = 999; /* HSync end */
1581   SiS_Pr->PanelVRS        = 999; /* VSync start */
1582   SiS_Pr->PanelVRE        = 999; /* VSync end */
1583   SiS_Pr->SiS_NeedRomModeData = FALSE;
1584 
1585   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1586   SiS_Pr->Alternate1600x1200 = FALSE;
1587 
1588   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1589 
1590   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1591 
1592   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1593      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1594      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1595      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1596   }
1597 
1598   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1599 
1600   /* For broken BIOSes: Assume 1024x768 */
1601   if(temp == 0) temp = 0x02;
1602 
1603   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1604      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1605   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1606      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1607   } else {
1608      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1609   }
1610   temp &= 0x0f;
1611 #ifdef SIS300
1612   if(SiS_Pr->ChipType < SIS_315H) {
1613      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1614      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1615         if(temp < 0x0f) temp &= 0x07;
1616      }
1617      /* Translate 300 series LCDRes to 315 series for unified usage */
1618      temp = SiS300SeriesLCDRes[temp];
1619   }
1620 #endif
1621 
1622   /* Translate to our internal types */
1623 #ifdef SIS315H
1624   if(SiS_Pr->ChipType == SIS_550) {
1625      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1626      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1627      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1628   } else if(SiS_Pr->ChipType >= SIS_661) {
1629      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1630   }
1631 #endif
1632 
1633   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
1634      if(temp == Panel310_1280x768) {
1635         temp = Panel_1280x768_2;
1636      }
1637      if(SiS_Pr->SiS_ROMNew) {
1638 	if(temp == Panel661_1280x800) {
1639 	   temp = Panel_1280x800_2;
1640 	}
1641      }
1642   }
1643 
1644   SiS_Pr->SiS_LCDResInfo = temp;
1645 
1646 #ifdef SIS300
1647   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1648      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1649 	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1650      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1651 	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1652      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1653 	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1654      }
1655   }
1656 #endif
1657 
1658   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1659      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1660 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1661   } else {
1662      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1663 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1664   }
1665 
1666   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1667   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1668   /* Need temp below! */
1669 
1670   /* These must/can't scale no matter what */
1671   switch(SiS_Pr->SiS_LCDResInfo) {
1672   case Panel_320x240_1:
1673   case Panel_320x240_2:
1674   case Panel_320x240_3:
1675   case Panel_1280x960:
1676       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1677       break;
1678   case Panel_640x480:
1679       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1680   }
1681 
1682   panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1683 
1684   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1685   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1686 
1687   /* Dual link, Pass 1:1 BIOS default, etc. */
1688 #ifdef SIS315H
1689   if(SiS_Pr->ChipType >= SIS_661) {
1690      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1691 	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1692      }
1693      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1694 	if(SiS_Pr->SiS_ROMNew) {
1695 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1696 	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1697 	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1698 	}
1699      }
1700   } else if(SiS_Pr->ChipType >= SIS_315H) {
1701      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1702 	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1703      }
1704      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1705 	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1706 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1707 	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1708 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1709 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1710 	}
1711      } else if(!(SiS_Pr->SiS_ROMNew)) {
1712 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1713 	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1714 	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1715 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1716 	   }
1717 	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1718 	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1719 	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1720 	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1721 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1722 	   }
1723 	}
1724      }
1725   }
1726 #endif
1727 
1728   /* Pass 1:1 */
1729   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1730      /* Always center screen on LVDS (if scaling is disabled) */
1731      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1732   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1733      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1734 	/* Always center screen on SiS LVDS (if scaling is disabled) */
1735 	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1736      } else {
1737 	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1738 	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1739 	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1740      }
1741   }
1742 
1743   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1744   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1745 
1746   switch(SiS_Pr->SiS_LCDResInfo) {
1747      case Panel_320x240_1:
1748      case Panel_320x240_2:
1749      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1750 			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1751 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1752 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1753 			    break;
1754      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1755 						      SiS_Pr->PanelVRE  =    3;
1756 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1757 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1758 			    break;
1759      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1760      			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1761 			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1762 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1763 			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1764 			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1765 			    break;
1766      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1767 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1768 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1769 			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1770 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1771 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1772 			    break;
1773      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1774 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1775 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1776 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1777 			    if(SiS_Pr->ChipType < SIS_315H) {
1778 			       SiS_Pr->PanelHRS = 23;
1779 						      SiS_Pr->PanelVRE  =    5;
1780 			    }
1781 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1782 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1783 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1784 			    break;
1785      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
1786 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1787 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1788 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1789 			    if(SiS_Pr->ChipType < SIS_315H) {
1790 			       SiS_Pr->PanelHRS = 23;
1791 						      SiS_Pr->PanelVRE  =    5;
1792 			    }
1793 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1794 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1795 			    break;
1796      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
1797 			    break;
1798      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
1799 			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
1800 			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
1801 			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
1802 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1803 			    /* Data above for TMDS (projector); get from BIOS for LVDS */
1804 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1805 			    break;
1806      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1807 			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1808 			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
1809 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1810 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1811 			    } else {
1812 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
1813 			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
1814 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1815 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1816 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1817 			    }
1818 			    break;
1819      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1820 			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
1821 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1822 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1823 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1824 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1825 			    break;
1826      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1827 			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
1828 			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
1829 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1830 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1831 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1832 			    break;
1833      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1834 			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
1835 			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
1836 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1837 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1838 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1839 			    break;
1840      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
1841 			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
1842 			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
1843 			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
1844 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1845 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1846 			    break;
1847      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
1848 			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
1849 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1850 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1851 			    if(resinfo == SIS_RI_1280x1024) {
1852 			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1853 			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1854 			    }
1855 			    break;
1856      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1857 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1858 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1859 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1860 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1861 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1862 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1863 			    break;
1864      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1865 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1866 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1867 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1868 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1869 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1870 			    break;
1871      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1872 			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
1873 			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
1874 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1875 			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1876 			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1877 			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1878 				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
1879 				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
1880 				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
1881 				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1882 				  SiS_Pr->Alternate1600x1200 = TRUE;
1883 			       }
1884 			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1885 			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
1886 			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1887 			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1888 			    }
1889 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1890 			    break;
1891      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1892 			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
1893 			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
1894 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1895 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1896 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1897 			    break;
1898      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1899 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1900 			    break;
1901      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
1902 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1903 			    break;
1904      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
1905 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1906 			    break;
1907      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1908 			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1909 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
1910 			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
1911 			    if(SiS_Pr->CP_PreferredIndex != -1) {
1912 			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1913 			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1914 			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1915 			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1916 			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1917 			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1918 			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1919 			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1920 			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1921 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1922 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1923 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1924 			       if(SiS_Pr->CP_PrefClock) {
1925 				  int idx;
1926 				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1927 				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1928 				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1929 				  else				   idx = VCLK_CUSTOM_315;
1930 				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
1931 				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1932 				  SiS_Pr->SiS_VCLKData[idx].SR2B =
1933 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1934 				  SiS_Pr->SiS_VCLKData[idx].SR2C =
1935 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1936 			       }
1937 			    }
1938 			    break;
1939      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1940 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1941 			    break;
1942   }
1943 
1944   /* Special cases */
1945   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
1946       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
1947       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1948       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1949       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1950       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1951      SiS_Pr->PanelHRS = 999;
1952      SiS_Pr->PanelHRE = 999;
1953   }
1954 
1955   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1956       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1957       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1958       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1959      SiS_Pr->PanelVRS = 999;
1960      SiS_Pr->PanelVRE = 999;
1961   }
1962 
1963   /* DontExpand overrule */
1964   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1965 
1966      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1967 	/* No scaling for this mode on any panel (LCD=CRT2)*/
1968 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1969      }
1970 
1971      switch(SiS_Pr->SiS_LCDResInfo) {
1972 
1973      case Panel_Custom:
1974      case Panel_1152x864:
1975      case Panel_1280x768:	/* TMDS only */
1976 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1977 	break;
1978 
1979      case Panel_800x600: {
1980 	static const unsigned char nonscalingmodes[] = {
1981 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1982 	};
1983 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1984 	break;
1985      }
1986      case Panel_1024x768: {
1987 	static const unsigned char nonscalingmodes[] = {
1988 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1989 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1990 	   0xff
1991 	};
1992 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1993 	break;
1994      }
1995      case Panel_1280x720: {
1996 	static const unsigned char nonscalingmodes[] = {
1997 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1998 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1999 	   0xff
2000 	};
2001 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2002 	if(SiS_Pr->PanelHT == 1650) {
2003 	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2004 	}
2005 	break;
2006      }
2007      case Panel_1280x768_2: {  /* LVDS only */
2008 	static const unsigned char nonscalingmodes[] = {
2009 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2010 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2011 	   SIS_RI_1152x768,0xff
2012 	};
2013 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 	switch(resinfo) {
2015 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2016 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2017 			       }
2018 			       break;
2019 	}
2020 	break;
2021      }
2022      case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
2023 	static const unsigned char nonscalingmodes[] = {
2024 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2025 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2026 	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2027 	};
2028 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2029 	break;
2030      }
2031      case Panel_1280x800_2:  { 	/* SiS LVDS */
2032 	static const unsigned char nonscalingmodes[] = {
2033 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2034 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2035 	   SIS_RI_1152x768,0xff
2036 	};
2037 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2038 	switch(resinfo) {
2039 	case SIS_RI_1280x720:
2040 	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
2041 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2042 			       }
2043 			       break;
2044 	}
2045 	break;
2046      }
2047      case Panel_1280x854: {  	/* SiS LVDS */
2048 	static const unsigned char nonscalingmodes[] = {
2049 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2050 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2051 	   SIS_RI_1152x768,0xff
2052 	};
2053 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2054 	switch(resinfo) {
2055 	case SIS_RI_1280x720:
2056 	case SIS_RI_1280x768:
2057 	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2058 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2059 			       }
2060 			       break;
2061 	}
2062 	break;
2063      }
2064      case Panel_1280x960: {
2065 	static const unsigned char nonscalingmodes[] = {
2066 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2067 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2068 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2069 	   SIS_RI_1280x854,0xff
2070 	};
2071 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2072 	break;
2073      }
2074      case Panel_1280x1024: {
2075 	static const unsigned char nonscalingmodes[] = {
2076 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2077 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2078 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2079 	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
2080 	};
2081 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2082 	break;
2083      }
2084      case Panel_1400x1050: {
2085 	static const unsigned char nonscalingmodes[] = {
2086 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2087 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2088 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2089 	     SIS_RI_1280x960,0xff
2090 	};
2091 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2092 	switch(resinfo) {
2093 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2094 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2095 			       }
2096 			       break;
2097 	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2098 			       break;
2099 	}
2100 	break;
2101      }
2102      case Panel_1600x1200: {
2103 	static const unsigned char nonscalingmodes[] = {
2104 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2105 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2106 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2107 	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2108 	};
2109 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2110 	break;
2111      }
2112      case Panel_1680x1050: {
2113 	static const unsigned char nonscalingmodes[] = {
2114 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2115 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2116 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2117 	     SIS_RI_1360x1024,0xff
2118 	};
2119 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2120 	break;
2121      }
2122      }
2123   }
2124 
2125 #ifdef SIS300
2126   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2127      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2128 	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2129      }
2130   }
2131 
2132   if(SiS_Pr->ChipType < SIS_315H) {
2133      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2134 	if(SiS_Pr->SiS_UseROM) {
2135 	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2136 	      if(!(ROMAddr[0x235] & 0x02)) {
2137 		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2138 	      }
2139 	   }
2140 	}
2141      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2142 	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2143 	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2144 	}
2145      }
2146   }
2147 #endif
2148 
2149   /* Special cases */
2150 
2151   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2152      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2153   }
2154 
2155   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2156      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2157   }
2158 
2159   switch(SiS_Pr->SiS_LCDResInfo) {
2160   case Panel_640x480:
2161      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2162      break;
2163   case Panel_1280x800:
2164      /* Don't pass 1:1 by default (TMDS special) */
2165      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2166      break;
2167   case Panel_1280x960:
2168      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2169      break;
2170   case Panel_Custom:
2171      if((!SiS_Pr->CP_PrefClock) ||
2172         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2173         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2174      }
2175      break;
2176   }
2177 
2178   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2179      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2180   }
2181 
2182   /* (In)validate LCDPass11 flag */
2183   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2184      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2185   }
2186 
2187   /* LVDS DDA */
2188   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2189 
2190      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2191 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2192 	   if(ModeNo == 0x12) {
2193 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2194 		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2195 	      }
2196 	   } else if(ModeNo > 0x13) {
2197 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2198 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2199 		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2200 		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2201 		    }
2202 		 }
2203 	      }
2204 	   }
2205 	}
2206      }
2207 
2208      if(modeflag & HalfDCLK) {
2209 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2210 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2211 	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2212 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2213 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2214 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2215 	} else if(ModeNo > 0x13) {
2216 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2217 	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2218 	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2219 	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2220 	   }
2221 	}
2222      }
2223 
2224   }
2225 
2226   /* VESA timing */
2227   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2228      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2229 	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2230      }
2231   } else {
2232      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2233   }
2234 
2235 #ifdef SIS_LINUX_KERNEL
2236 #if 0
2237   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2238 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2239 #endif
2240 #endif
2241 #ifdef SIS_XORG_XF86
2242   xf86DrvMsgVerb(0, X_PROBED, 4,
2243 	"(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2244 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2245 #endif
2246 }
2247 
2248 /*********************************************/
2249 /*                 GET VCLK                  */
2250 /*********************************************/
2251 
2252 unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2253 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2254 		unsigned short RefreshRateTableIndex)
2255 {
2256   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2257   unsigned short resinfo, tempbx;
2258   const unsigned char *CHTVVCLKPtr = NULL;
2259 
2260   if(ModeNo <= 0x13) {
2261      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2262      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2263      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2264      VCLKIndexGENCRT = VCLKIndexGEN;
2265   } else {
2266      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2267      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2268      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2269      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2270 		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2271   }
2272 
2273   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2274 
2275      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2276 
2277 	CRT2Index >>= 6;
2278 	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2279 
2280 	   if(SiS_Pr->ChipType < SIS_315H) {
2281 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2282 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2283 		 VCLKIndex = VCLKIndexGEN;
2284 	      }
2285 	   } else {
2286 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2287 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2288 		 switch(resinfo) {
2289 		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2290 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2291 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2292 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2293 		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2294 		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2295 		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2296 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2297 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2298 		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2299 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2300 		 default:              VCLKIndex = VCLKIndexGEN;
2301 		 }
2302 
2303 		 if(ModeNo <= 0x13) {
2304 		    if(SiS_Pr->ChipType <= SIS_315PRO) {
2305 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2306 		    } else {
2307 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2308 		    }
2309 		 }
2310 		 if(SiS_Pr->ChipType <= SIS_315PRO) {
2311 		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2312 		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2313 		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2314 		 }
2315 	      }
2316 	   }
2317 
2318 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2319 
2320 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2321 	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
2322 	      else                                  	   VCLKIndex = HiTVVCLK;
2323 	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2324 	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)
2325 	      VCLKIndex = YPbPr750pVCLK;
2326 	   else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p | TVRPLLDIV2XO))
2327 	      VCLKIndex = TVVCLKDIV2;
2328 	   else
2329 	      VCLKIndex = TVVCLK;
2330 
2331 	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2332 	   else				   VCLKIndex += TVCLKBASE_315;
2333 
2334 	} else {							/* VGA2 */
2335 
2336 	   VCLKIndex = VCLKIndexGENCRT;
2337 	   if(SiS_Pr->ChipType < SIS_315H) {
2338 	      if(ModeNo > 0x13) {
2339 		 if( (SiS_Pr->ChipType == SIS_630) &&
2340 		     (SiS_Pr->ChipRevision >= 0x30)) {
2341 		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2342 		 }
2343 		 /* Better VGA2 clock for 1280x1024@75 */
2344 		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2345 	      }
2346 	   }
2347 	}
2348 
2349      } else {   /* If not programming CRT2 */
2350 
2351 	VCLKIndex = VCLKIndexGENCRT;
2352 	if(SiS_Pr->ChipType < SIS_315H) {
2353 	   if(ModeNo > 0x13) {
2354 	      if( (SiS_Pr->ChipType != SIS_630) &&
2355 		  (SiS_Pr->ChipType != SIS_300) ) {
2356 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2357 	      }
2358 	   }
2359 	}
2360      }
2361 
2362   } else {       /*   LVDS  */
2363 
2364      VCLKIndex = CRT2Index;
2365 
2366      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2367 
2368 	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2369 
2370 	   VCLKIndex &= 0x1f;
2371 	   tempbx = 0;
2372 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2373 	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2374 	      tempbx += 2;
2375 	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2376 		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2377 	      }
2378 	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2379 		 tempbx = 4;
2380 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2381 	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2382 		 tempbx = 6;
2383 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2384 	      }
2385 	   }
2386 	   switch(tempbx) {
2387 	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2388 	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2389 	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2390 	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2391 	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2392 	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2393 	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2394 	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2395 	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2396 	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2397 	   }
2398 	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2399 
2400 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2401 
2402 	   if(SiS_Pr->ChipType < SIS_315H) {
2403 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2404 	   } else {
2405 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2406 	   }
2407 
2408 #ifdef SIS300
2409 	   /* Special Timing: Barco iQ Pro R series */
2410 	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2411 
2412 	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2413 	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2414 	      if(SiS_Pr->ChipType < SIS_315H) {
2415 		 VCLKIndex = VCLK34_300;
2416 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2417 	      } else {
2418 		 VCLKIndex = VCLK34_315;
2419 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2420 	      }
2421 	   }
2422 #endif
2423 
2424 	} else {
2425 
2426 	   VCLKIndex = VCLKIndexGENCRT;
2427 	   if(SiS_Pr->ChipType < SIS_315H) {
2428 	      if(ModeNo > 0x13) {
2429 		 if( (SiS_Pr->ChipType == SIS_630) &&
2430 		     (SiS_Pr->ChipRevision >= 0x30) ) {
2431 		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2432 		 }
2433 	      }
2434 	   }
2435 	}
2436 
2437      } else {  /* if not programming CRT2 */
2438 
2439 	VCLKIndex = VCLKIndexGENCRT;
2440 	if(SiS_Pr->ChipType < SIS_315H) {
2441 	   if(ModeNo > 0x13) {
2442 	      if( (SiS_Pr->ChipType != SIS_630) &&
2443 		  (SiS_Pr->ChipType != SIS_300) ) {
2444 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2445 	      }
2446 #if 0
2447 	      if(SiS_Pr->ChipType == SIS_730) {
2448 		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2449 		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2450 	      }
2451 #endif
2452 	   }
2453         }
2454 
2455      }
2456 
2457   }
2458 
2459 #ifdef SIS_XORG_XF86
2460 #ifdef TWDEBUG
2461   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2462 #endif
2463 #endif
2464 
2465   return VCLKIndex;
2466 }
2467 
2468 /*********************************************/
2469 /*        SET CRT2 MODE TYPE REGISTERS       */
2470 /*********************************************/
2471 
2472 static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2473 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2474 {
2475   unsigned short i, j, modeflag, tempah=0;
2476   short tempcl;
2477 #if defined(SIS300) || defined(SIS315H)
2478   unsigned short tempbl;
2479 #endif
2480 #ifdef SIS315H
2481   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2482   unsigned short tempah2, tempbl2;
2483 #endif
2484 
2485   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2486 
2487   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2488 
2489      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2490      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2491 
2492   } else {
2493 
2494      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2495      if(SiS_Pr->ChipType >= SIS_315H) {
2496         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2497      }
2498 
2499      tempcl = SiS_Pr->SiS_ModeType;
2500 
2501      if(SiS_Pr->ChipType < SIS_315H) {
2502 
2503 #ifdef SIS300    /* ---- 300 series ---- */
2504 
2505 	/* For 301BDH: (with LCD via LVDS) */
2506 	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2507 	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2508 	   tempbl &= 0xef;
2509 	   tempbl |= 0x02;
2510 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2511 	      tempbl |= 0x10;
2512 	      tempbl &= 0xfd;
2513 	   }
2514 	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2515 	}
2516 
2517 	if(ModeNo > 0x13) {
2518 	   tempcl -= ModeVGA;
2519 	   if(tempcl >= 0) {
2520 	      tempah = ((0x10 >> tempcl) | 0x80);
2521 	   }
2522 	} else tempah = 0x80;
2523 
2524 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2525 
2526 #endif  /* SIS300 */
2527 
2528      } else {
2529 
2530 #ifdef SIS315H    /* ------- 315/330 series ------ */
2531 
2532 	if(ModeNo > 0x13) {
2533 	   tempcl -= ModeVGA;
2534 	   if(tempcl >= 0) {
2535 	      tempah = (0x08 >> tempcl);
2536 	      if (tempah == 0) tempah = 1;
2537 	      tempah |= 0x40;
2538 	   }
2539 	} else tempah = 0x40;
2540 
2541 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2542 
2543 #endif  /* SIS315H */
2544 
2545      }
2546 
2547      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2548 
2549      if(SiS_Pr->ChipType < SIS_315H) {
2550 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2551      } else {
2552 #ifdef SIS315H
2553 	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2554 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2555 	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2556 	   if(IS_SIS740) {
2557 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2558 	   } else {
2559 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2560 	   }
2561 	}
2562 #endif
2563      }
2564 
2565      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2566 
2567 	tempah = 0x01;
2568 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2569 	   tempah |= 0x02;
2570 	}
2571 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2572 	   tempah ^= 0x05;
2573 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2574 	      tempah ^= 0x01;
2575 	   }
2576 	}
2577 
2578 	if(SiS_Pr->ChipType < SIS_315H) {
2579 
2580 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2581 
2582 	   tempah = (tempah << 5) & 0xFF;
2583 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2584 	   tempah = (tempah >> 5) & 0xFF;
2585 
2586 	} else {
2587 
2588 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2589 	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2590 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2591 	   tempah &= ~0x08;
2592 
2593 	}
2594 
2595 	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2596 	   tempah |= 0x10;
2597 	}
2598 
2599 	tempah |= 0x80;
2600 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2601 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2602 	}
2603 
2604 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2605 	   if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) {
2606 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2607 		 tempah |= 0x20;
2608 	      }
2609 	   }
2610 	}
2611 
2612 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2613 
2614 	tempah = 0x80;
2615 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2616 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2617 	}
2618 
2619 	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2620 
2621 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2622 	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2623 	      tempah |= 0x40;
2624 	   }
2625 	}
2626 
2627 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2628 
2629      } else {  /* LVDS */
2630 
2631 	if(SiS_Pr->ChipType >= SIS_315H) {
2632 
2633 #ifdef SIS315H
2634 	   /* LVDS can only be slave in 8bpp modes */
2635 	   tempah = 0x80;
2636 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2637 	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2638 	         tempah |= 0x02;
2639 	      }
2640 	   }
2641 
2642 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2643 
2644 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2645 
2646 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2647 
2648 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2649 #endif
2650 
2651 	} else {
2652 
2653 #ifdef SIS300
2654 	   tempah = 0;
2655 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2656 	      tempah |= 0x02;
2657 	   }
2658 	   tempah <<= 5;
2659 
2660 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2661 
2662 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2663 #endif
2664 
2665 	}
2666 
2667      }
2668 
2669   }  /* LCDA */
2670 
2671   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2672 
2673      if(SiS_Pr->ChipType >= SIS_315H) {
2674 
2675 #ifdef SIS315H
2676 	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2677 
2678 	/* The following is nearly unpreditable and varies from machine
2679 	 * to machine. Especially the 301DH seems to be a real trouble
2680 	 * maker. Some BIOSes simply set the registers (like in the
2681 	 * NoLCD-if-statements here), some set them according to the
2682 	 * LCDA stuff. It is very likely that some machines are not
2683 	 * treated correctly in the following, very case-orientated
2684 	 * code. What do I do then...?
2685 	 */
2686 
2687 	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2688 
2689 	if(!(IS_SIS740)) {
2690 	   tempah = 0x04;						   /* For all bridges */
2691 	   tempbl = 0xfb;
2692 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2693 	      tempah = 0x00;
2694 	      if(SiS_IsDualEdge(SiS_Pr)) {
2695 	         tempbl = 0xff;
2696 	      }
2697 	   }
2698 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2699 	}
2700 
2701 	/* The following two are responsible for eventually wrong colors
2702 	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2703 	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2704 	 * in a 650 box (Jake). What is the criteria?
2705 	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2706 	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2707 	 * chipset than the bridge revision.
2708 	 */
2709 
2710 	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2711 	   tempah = 0x30;
2712 	   tempbl = 0xc0;
2713 	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2714 	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2715 	      tempah = 0x00;
2716 	      tempbl = 0x00;
2717 	   }
2718 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2719 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2720 	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2721 	   /* Fixes "TV-blue-bug" on 315+301 */
2722 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
2723 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2724 	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2725 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
2726 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2727 	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
2728 	   tempah = 0x30; tempah2 = 0xc0;
2729 	   tempbl = 0xcf; tempbl2 = 0x3f;
2730 	   if(SiS_Pr->SiS_TVBlue == 0) {
2731 	         tempah = tempah2 = 0x00;
2732 	   } else if(SiS_Pr->SiS_TVBlue == -1) {
2733 	      /* Set on 651/M650, clear on 315/650 */
2734 	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2735 	         tempah = tempah2 = 0x00;
2736 	      }
2737 	   }
2738 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2739 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2740 	} else {
2741 	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
2742 	   tempbl = 0xcf; tempbl2 = 0x3f;
2743 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2744 	      tempah = tempah2 = 0x00;
2745 	      if(SiS_IsDualEdge(SiS_Pr)) {
2746 		 tempbl = tempbl2 = 0xff;
2747 	      }
2748 	   }
2749 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2750 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2751 	}
2752 
2753 	if(IS_SIS740) {
2754 	   tempah = 0x80;
2755 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2756 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2757 	} else {
2758 	   tempah = 0x00;
2759 	   tempbl = 0x7f;
2760 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2761 	      tempbl = 0xff;
2762 	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2763 	   }
2764 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2765 	}
2766 
2767 #endif /* SIS315H */
2768 
2769      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2770 
2771 #ifdef SIS300
2772 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2773 
2774 	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2775 	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2776 	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2777 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2778 	} else {
2779 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2780 	}
2781 #endif
2782 
2783      }
2784 
2785      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2786 	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2787 	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2788 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2789         }
2790      }
2791 
2792   } else {  /* LVDS */
2793 
2794 #ifdef SIS315H
2795      if(SiS_Pr->ChipType >= SIS_315H) {
2796 
2797 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2798 
2799 	   tempah = 0x04;
2800 	   tempbl = 0xfb;
2801 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2802 	      tempah = 0x00;
2803 	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2804 	   }
2805 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2806 
2807 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2808 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2809 	   }
2810 
2811 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2812 
2813 	} else if(SiS_Pr->ChipType == SIS_550) {
2814 
2815 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2816 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2817 
2818 	}
2819 
2820      }
2821 #endif
2822 
2823   }
2824 
2825 }
2826 
2827 /*********************************************/
2828 /*            GET RESOLUTION DATA            */
2829 /*********************************************/
2830 
2831 unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2832 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2833 {
2834    if(ModeNo <= 0x13)
2835       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2836    else
2837       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2838 }
2839 
2840 static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2841 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2842 {
2843    unsigned short xres, yres, modeflag=0, resindex;
2844 
2845    if(SiS_Pr->UseCustomMode) {
2846       xres = SiS_Pr->CHDisplay;
2847       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2848       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2849       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2850       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2851       return;
2852    }
2853 
2854    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2855 
2856    if(ModeNo <= 0x13) {
2857       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2858       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2859    } else {
2860       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2861       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2862       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2863    }
2864 
2865    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2866 
2867       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2868 	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2869 	    if(yres == 350) yres = 400;
2870 	 }
2871 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2872 	    if(ModeNo == 0x12) yres = 400;
2873 	 }
2874       }
2875 
2876       if(modeflag & HalfDCLK)       xres <<= 1;
2877       if(modeflag & DoubleScanMode) yres <<= 1;
2878 
2879    }
2880 
2881    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2882 
2883       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2884 	 switch(SiS_Pr->SiS_LCDResInfo) {
2885 	   case Panel_1024x768:
2886 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2887 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2888 		    if(yres == 350) yres = 357;
2889 		    if(yres == 400) yres = 420;
2890 		    if(yres == 480) yres = 525;
2891 		 }
2892 	      }
2893 	      break;
2894 	   case Panel_1280x1024:
2895 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2896 		 /* BIOS bug - does this regardless of scaling */
2897 		 if(yres == 400) yres = 405;
2898 	      }
2899 	      if(yres == 350) yres = 360;
2900 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2901 		 if(yres == 360) yres = 375;
2902 	      }
2903 	      break;
2904 	   case Panel_1600x1200:
2905 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2906 		 if(yres == 1024) yres = 1056;
2907 	      }
2908 	      break;
2909 	 }
2910       }
2911 
2912    } else {
2913 
2914       if(SiS_Pr->SiS_VBType & VB_SISVB) {
2915 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2916 	    if(xres == 720) xres = 640;
2917 	 }
2918       } else if(xres == 720) xres = 640;
2919 
2920       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2921 	 yres = 400;
2922 	 if(SiS_Pr->ChipType >= SIS_315H) {
2923 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2924 	 } else {
2925 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2926 	 }
2927 	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2928       }
2929 
2930    }
2931    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2932    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2933 }
2934 
2935 /*********************************************/
2936 /*           GET CRT2 TIMING DATA            */
2937 /*********************************************/
2938 
2939 static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)2940 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2941 	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2942 	       unsigned short *ResIndex)
2943 {
2944   unsigned short tempbx=0, tempal=0, resinfo=0;
2945 
2946   if(ModeNo <= 0x13) {
2947      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2948   } else {
2949      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2950      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2951   }
2952 
2953   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2954 
2955      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2956 
2957 	tempbx = SiS_Pr->SiS_LCDResInfo;
2958 	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2959 
2960 	/* patch index */
2961 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2962 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
2963 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2964 	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2965 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2966 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2967 	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
2968 	}
2969 
2970 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2971 	   /* Pass 1:1 only (center-screen handled outside) */
2972 	   /* This is never called for the panel's native resolution */
2973 	   /* since Pass1:1 will not be set in this case */
2974 	   tempbx = 100;
2975 	   if(ModeNo >= 0x13) {
2976 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2977 	   }
2978 	}
2979 
2980 #ifdef SIS315H
2981 	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2982 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2983 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2984 		 tempbx = 200;
2985 		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2986 	      }
2987 	   }
2988 	}
2989 #endif
2990 
2991      } else {						  	/* TV */
2992 
2993 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2994 	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2995 	   tempbx = 2;
2996 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2997 	      tempbx = 13;
2998 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2999 	   }
3000 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3001 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
3002 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
3003 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i)	tempbx = 15;
3004 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p)	tempbx = 16;
3005 	   else						tempbx = 5;
3006 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3007 	} else {
3008 	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
3009 	   else						tempbx = 4;
3010 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3011 	}
3012 
3013      }
3014 
3015      tempal &= 0x3F;
3016 
3017      if(ModeNo > 0x13) {
3018         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3019 	   switch(resinfo) {
3020 	   case SIS_RI_720x480:
3021 	      tempal = 9;
3022 	      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 6;
3023 	      break;
3024 	   case SIS_RI_720x576:
3025 	   case SIS_RI_768x576:
3026 	   case SIS_RI_1024x576:
3027 	      tempal = 6;
3028 	      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3029 		 tempal = 8;
3030 		 if(resinfo == SIS_RI_1024x576) tempal = 10;
3031 	      }
3032 	      break;
3033 	   case SIS_RI_800x480:
3034 	      tempal = 4;
3035 	      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3036 	      break;
3037 	   case SIS_RI_512x384:
3038 	   case SIS_RI_1024x768:
3039 	      tempal = 7;
3040 	      if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p)) {
3041 	         tempal = 8;
3042 	      }
3043 	      break;
3044 	   case SIS_RI_1280x720:
3045 	      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 11;
3046 	      break;
3047 	   }
3048 	}
3049      }
3050 
3051      *CRT2Index = tempbx;
3052      *ResIndex = tempal;
3053 
3054   } else {   /* LVDS, 301B-DH (if running on LCD) */
3055 
3056      tempbx = 0;
3057      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3058 
3059 	tempbx = 90;
3060 	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3061 	   tempbx = 92;
3062 	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
3063 	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3064 	   }
3065 	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3066 	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3067 	}
3068 	if(tempbx != 99) {
3069 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3070 	}
3071 
3072      } else {
3073 
3074 	switch(SiS_Pr->SiS_LCDResInfo) {
3075 	case Panel_640x480:   tempbx = 12; break;
3076 	case Panel_320x240_1: tempbx = 10; break;
3077 	case Panel_320x240_2:
3078 	case Panel_320x240_3: tempbx = 14; break;
3079 	case Panel_800x600:   tempbx = 16; break;
3080 	case Panel_1024x600:  tempbx = 18; break;
3081 	case Panel_1152x768:
3082 	case Panel_1024x768:  tempbx = 20; break;
3083 	case Panel_1280x768:  tempbx = 22; break;
3084 	case Panel_1280x1024: tempbx = 24; break;
3085 	case Panel_1400x1050: tempbx = 26; break;
3086 	case Panel_1600x1200: tempbx = 28; break;
3087 #ifdef SIS300
3088 	case Panel_Barco1366: tempbx = 80; break;
3089 #endif
3090 	}
3091 
3092 	switch(SiS_Pr->SiS_LCDResInfo) {
3093 	case Panel_320x240_1:
3094 	case Panel_320x240_2:
3095 	case Panel_320x240_3:
3096 	case Panel_640x480:
3097 	   break;
3098 	default:
3099 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3100 	}
3101 
3102 	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3103 
3104 #ifdef SIS300
3105 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3106 	   tempbx = 82;
3107 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3108 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3109 	   tempbx = 84;
3110 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3111 	}
3112 #endif
3113 
3114      }
3115 
3116      (*CRT2Index) = tempbx;
3117      (*ResIndex) = tempal & 0x1F;
3118   }
3119 }
3120 
3121 static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3122 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3123 		unsigned short RefreshRateTableIndex)
3124 {
3125   unsigned short tempax=0, tempbx=0, index, dotclock;
3126   unsigned short temp1=0, modeflag=0, tempcx=0;
3127 
3128   SiS_Pr->SiS_RVBHCMAX  = 1;
3129   SiS_Pr->SiS_RVBHCFACT = 1;
3130 
3131   if(ModeNo <= 0x13) {
3132 
3133      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3134      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3135 
3136      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3137      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3138      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3139 
3140      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3141 
3142   } else {
3143 
3144      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3145      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3146 
3147      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3148      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3149      tempax &= 0x03FF;
3150      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3151      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3152      tempcx &= 0x0100;
3153      tempcx <<= 2;
3154      tempbx |= tempcx;
3155      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3156 
3157      dotclock = 8;
3158 
3159   }
3160 
3161   if(temp1 & 0x01) tempbx |= 0x0100;
3162   if(temp1 & 0x20) tempbx |= 0x0200;
3163 
3164   tempax += 5;
3165   tempax *= dotclock;
3166   if(modeflag & HalfDCLK) tempax <<= 1;
3167 
3168   tempbx++;
3169 
3170   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3171   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3172 }
3173 
3174 static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3175 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3176 		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3177 {
3178    unsigned short ResIndex;
3179 
3180    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3181       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3182 	 if(SiS_Pr->UseCustomMode) {
3183 	    ResIndex = SiS_Pr->CHTotal;
3184 	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3185 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3186 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3187 	 } else {
3188 	    if(ModeNo < 0x13) {
3189 	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3190 	    } else {
3191 	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3192 	    }
3193 	    if(ResIndex == 0x09) {
3194 	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3195 	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3196 	    }
3197 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3198 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3199 	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3200 	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3201 	 }
3202       } else {
3203 	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3204 	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3205       }
3206    } else {
3207       /* This handles custom modes and custom panels */
3208       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3209       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3210       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3211       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3212       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3213       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3214    }
3215 }
3216 
3217 static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3218 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3219                     unsigned short RefreshRateTableIndex)
3220 {
3221    unsigned short CRT2Index, ResIndex, backup;
3222    const struct SiS_LVDSData *LVDSData = NULL;
3223 
3224    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3225 
3226    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3227       SiS_Pr->SiS_RVBHCMAX  = 1;
3228       SiS_Pr->SiS_RVBHCFACT = 1;
3229       SiS_Pr->SiS_NewFlickerMode = 0;
3230       SiS_Pr->SiS_RVBHRS = 50;
3231       SiS_Pr->SiS_RY1COE = 0;
3232       SiS_Pr->SiS_RY2COE = 0;
3233       SiS_Pr->SiS_RY3COE = 0;
3234       SiS_Pr->SiS_RY4COE = 0;
3235       SiS_Pr->SiS_RVBHRS2 = 0;
3236    }
3237 
3238    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3239 
3240 #ifdef SIS315H
3241       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3242       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3243 #endif
3244 
3245    } else {
3246 
3247       /* 301BDH needs LVDS Data */
3248       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3249       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3250 	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3251       }
3252 
3253       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3254                      		            &CRT2Index, &ResIndex);
3255 
3256       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3257 
3258       switch(CRT2Index) {
3259 	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3260 	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3261 	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3262 	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3263 	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3264 	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3265 #ifdef SIS300
3266 	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3267 	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3268 	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3269 	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3270 	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3271 #endif
3272 	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3273 	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3274 	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3275 	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3276 	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3277 	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3278 	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3279 	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3280 	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
3281       }
3282 
3283       if(LVDSData) {
3284 	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3285 	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3286 	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3287 	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3288       } else {
3289 	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3290       }
3291 
3292       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3293 	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3294 	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3295 	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3296 	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3297 	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3298             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3299 #ifdef SIS300
3300 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3301 	       if(ResIndex < 0x08) {
3302 		  SiS_Pr->SiS_HDE = 1280;
3303 		  SiS_Pr->SiS_VDE = 1024;
3304 	       }
3305 	    }
3306 #endif
3307          }
3308       }
3309    }
3310 }
3311 
3312 static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3313 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3314 		unsigned short RefreshRateTableIndex)
3315 {
3316   unsigned char  *ROMAddr = NULL;
3317   unsigned short tempax, tempbx, modeflag, romptr=0;
3318   unsigned short resinfo, CRT2Index, ResIndex;
3319   const struct SiS_LCDData *LCDPtr = NULL;
3320   const struct SiS_TVData  *TVPtr  = NULL;
3321 #ifdef SIS315H
3322   short resinfo661;
3323 #endif
3324 
3325   if(ModeNo <= 0x13) {
3326      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3327      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3328   } else if(SiS_Pr->UseCustomMode) {
3329      modeflag = SiS_Pr->CModeFlag;
3330      resinfo = 0;
3331   } else {
3332      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3333      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3334 #ifdef SIS315H
3335      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3336      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3337 	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3338 	 (resinfo661 >= 0)                     &&
3339 	 (SiS_Pr->SiS_NeedRomModeData) ) {
3340 	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3341 	   if((romptr = (SISGETROMW(21)))) {
3342 	      romptr += (resinfo661 * 10);
3343 	      ROMAddr = SiS_Pr->VirtualRomBase;
3344 	   }
3345 	}
3346      }
3347 #endif
3348   }
3349 
3350   SiS_Pr->SiS_NewFlickerMode = 0;
3351   SiS_Pr->SiS_RVBHRS = 50;
3352   SiS_Pr->SiS_RY1COE = 0;
3353   SiS_Pr->SiS_RY2COE = 0;
3354   SiS_Pr->SiS_RY3COE = 0;
3355   SiS_Pr->SiS_RY4COE = 0;
3356   SiS_Pr->SiS_RVBHRS2 = 0;
3357 
3358   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3359 
3360   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3361 
3362      if(SiS_Pr->UseCustomMode) {
3363 
3364 	SiS_Pr->SiS_RVBHCMAX  = 1;
3365 	SiS_Pr->SiS_RVBHCFACT = 1;
3366 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3367 	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3368 
3369 	tempax = SiS_Pr->CHTotal;
3370 	if(modeflag & HalfDCLK) tempax <<= 1;
3371 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3372 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3373 
3374      } else {
3375 
3376 	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3377 
3378      }
3379 
3380   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3381 
3382      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3383 		    &CRT2Index,&ResIndex);
3384 
3385      switch(CRT2Index) {
3386 	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3387 	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3388 	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3389 	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3390 	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3391 	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3392 	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3393 	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3394 	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3395 	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3396 	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3397 	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3398 	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3399 	case 15: TVPtr = SiS_Pr->SiS_Ext625iData;   break;
3400 	case 16: TVPtr = SiS_Pr->SiS_Ext625pData;   break;
3401 	case 20: TVPtr = SiS_Pr->SiS_St625iData;    break;
3402 	case 21: TVPtr = SiS_Pr->SiS_St625pData;    break;
3403 	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3404      }
3405 
3406      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3407      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3408      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3409      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3410      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3411      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3412      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3413      if(modeflag & HalfDCLK) {
3414 	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3415 	if(SiS_Pr->SiS_RVBHRS2) {
3416 	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3417 	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3418 	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3419 	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3420 	}
3421      } else {
3422 	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3423      }
3424      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3425 
3426      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3427 
3428 	if((resinfo == SIS_RI_960x540)   ||
3429 	   (resinfo == SIS_RI_960x600)   ||
3430 	   (resinfo == SIS_RI_1024x768)  ||
3431 	   (resinfo == SIS_RI_1280x1024) ||
3432 	   (resinfo == SIS_RI_1280x720)) {
3433 	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3434 	}
3435 
3436 	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3437 
3438 	SiS_Pr->SiS_HT = ExtHiTVHT;
3439 	SiS_Pr->SiS_VT = ExtHiTVVT;
3440 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3441 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3442 	      SiS_Pr->SiS_HT = StHiTVHT;
3443 	      SiS_Pr->SiS_VT = StHiTVVT;
3444 	   }
3445 	}
3446 
3447      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3448 
3449 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3450 	   SiS_Pr->SiS_HT = 1650;
3451 	   SiS_Pr->SiS_VT = 750;
3452 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3453 	   SiS_Pr->SiS_HT = NTSCHT;
3454 	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3455 	   SiS_Pr->SiS_VT = NTSCVT;
3456 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) {
3457 	   SiS_Pr->SiS_HT = NTSCHT;
3458 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3459 	   SiS_Pr->SiS_VT = NTSCVT;
3460 	} else {
3461 	   SiS_Pr->SiS_HT = PALHT;
3462 	   SiS_Pr->SiS_VT = PALVT;
3463 	}
3464 
3465      } else {
3466 
3467 	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3468 	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3469 	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3470 	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3471 
3472 	if(modeflag & HalfDCLK) {
3473 	   SiS_Pr->SiS_RY1COE = 0x00;
3474 	   SiS_Pr->SiS_RY2COE = 0xf4;
3475 	   SiS_Pr->SiS_RY3COE = 0x10;
3476 	   SiS_Pr->SiS_RY4COE = 0x38;
3477 	}
3478 
3479 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3480 	   SiS_Pr->SiS_HT = NTSCHT;
3481 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3482 	   SiS_Pr->SiS_VT = NTSCVT;
3483 	} else {
3484 	   SiS_Pr->SiS_HT = PALHT;
3485 	   SiS_Pr->SiS_VT = PALVT;
3486 	}
3487 
3488      }
3489 
3490   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3491 
3492      SiS_Pr->SiS_RVBHCMAX  = 1;
3493      SiS_Pr->SiS_RVBHCFACT = 1;
3494 
3495      if(SiS_Pr->UseCustomMode) {
3496 
3497 	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3498 	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3499 
3500 	tempax = SiS_Pr->CHTotal;
3501 	if(modeflag & HalfDCLK) tempax <<= 1;
3502 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3503 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3504 
3505      } else {
3506 
3507 	BOOLEAN gotit = FALSE;
3508 
3509 	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3510 
3511 	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3512 	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3513 	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3514 	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3515 	   gotit = TRUE;
3516 
3517 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3518 
3519 #ifdef SIS315H
3520 	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3521 	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3522 	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3523 	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3524 	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3525 	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3526 	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3527 	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3528 	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3529 	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3530 	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3531 	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3532 	   }
3533 	   if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3534 	   else {
3535 	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3536 	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3537 	      SiS_Pr->SiS_RVBHCMAX  = 1;
3538 	      SiS_Pr->SiS_RVBHCFACT = 1;
3539 	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3540 	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3541 	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3542 	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3543 	      SiS_Pr->SiS_RVBHRS2 = 0;
3544 	      gotit = TRUE;
3545 	   }
3546 #endif
3547 
3548 	}
3549 
3550 	if(!gotit) {
3551 
3552 	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3553 			  &CRT2Index,&ResIndex);
3554 
3555 	   switch(CRT2Index) {
3556 	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3557 	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3558 	      case Panel_1280x720      :
3559 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3560 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3561 	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3562 	      case Panel_1280x800      :
3563 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3564 	      case Panel_1280x800_2    :
3565 	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3566 	      case Panel_1280x854      :
3567 	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3568 	      case Panel_1280x960      :
3569 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3570 	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3571 	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3572 	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3573 	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3574 	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3575 	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3576 	      case Panel_1680x1050     :
3577 	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3578 	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3579 #ifdef SIS315H
3580 	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3581 	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3582 #endif
3583 	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3584 	   }
3585 
3586 #ifdef SIS_XORG_XF86
3587 #ifdef TWDEBUG
3588 	   xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3589 #endif
3590 #endif
3591 
3592 	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3593 	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3594 	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3595 	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3596 	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3597 	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3598 
3599         }
3600 
3601 	tempax = SiS_Pr->PanelXRes;
3602 	tempbx = SiS_Pr->PanelYRes;
3603 
3604 	switch(SiS_Pr->SiS_LCDResInfo) {
3605 	case Panel_1024x768:
3606 	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3607 	      if(SiS_Pr->ChipType < SIS_315H) {
3608 		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3609 		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3610 	      }
3611 	   } else {
3612 	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3613 	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3614 	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3615 	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3616 	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3617 	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3618 	   }
3619 	   break;
3620 	case Panel_1280x960:
3621 	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3622 	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3623 	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3624 	   break;
3625 	case Panel_1280x1024:
3626 	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3627 	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3628 	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3629 	   break;
3630 	case Panel_1600x1200:
3631 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3632 	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3633 	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3634 	   }
3635 	   break;
3636 	}
3637 
3638 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3639 	   tempax = SiS_Pr->SiS_VGAHDE;
3640 	   tempbx = SiS_Pr->SiS_VGAVDE;
3641 	}
3642 
3643 	SiS_Pr->SiS_HDE = tempax;
3644 	SiS_Pr->SiS_VDE = tempbx;
3645      }
3646   }
3647 }
3648 
3649 static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3650 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3651                 unsigned short RefreshRateTableIndex)
3652 {
3653 
3654    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3655 
3656       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3657          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3658       } else {
3659 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3660 	    /* Need LVDS Data for LCD on 301B-DH */
3661 	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3662 	 } else {
3663 	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3664 	 }
3665       }
3666 
3667    } else {
3668 
3669       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3670 
3671    }
3672 }
3673 
3674 /*********************************************/
3675 /*         GET LVDS DES (SKEW) DATA          */
3676 /*********************************************/
3677 
3678 static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3679 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3680 {
3681    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3682 
3683 #ifdef SIS300
3684    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3685 
3686       if(SiS_Pr->ChipType < SIS_315H) {
3687 	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3688 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3689 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3690 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3691 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3692 	       }
3693             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3694 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3695 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3696 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3697 	       }
3698 	    }
3699 	 }
3700       }
3701    }
3702 #endif
3703    return PanelDesPtr;
3704 }
3705 
3706 static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3707 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3708                    unsigned short RefreshRateTableIndex)
3709 {
3710   unsigned short modeflag, ResIndex;
3711   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3712 
3713   SiS_Pr->SiS_LCDHDES = 0;
3714   SiS_Pr->SiS_LCDVDES = 0;
3715 
3716   /* Some special cases */
3717   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3718 
3719      /* Trumpion */
3720      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3721 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3722 	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3723 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3724 	   }
3725 	}
3726 	return;
3727      }
3728 
3729      /* 640x480 on LVDS */
3730      if(SiS_Pr->ChipType < SIS_315H) {
3731 	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3732 	   SiS_Pr->SiS_LCDHDES = 8;
3733 	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3734 	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3735 	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3736 	   return;
3737 	}
3738      }
3739 
3740   } /* LCD */
3741 
3742   if( (SiS_Pr->UseCustomMode) 		         ||
3743       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3744       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3745       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3746       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3747      return;
3748   }
3749 
3750   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3751   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3752 
3753   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3754 
3755 #ifdef SIS315H
3756      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3757 	/* non-pass 1:1 only, see above */
3758 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3759 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3760 	}
3761 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3762 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3763 	}
3764      }
3765      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3766 	switch(SiS_Pr->SiS_CustomT) {
3767 	case CUT_UNIWILL1024:
3768 	case CUT_UNIWILL10242:
3769 	case CUT_CLEVO1400:
3770 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3771 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3772 	   }
3773 	   break;
3774 	}
3775 	switch(SiS_Pr->SiS_LCDResInfo) {
3776 	case Panel_1280x1024:
3777 	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3778 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3779 	   }
3780 	   break;
3781 	case Panel_1280x800:	/* Verified for Averatec 6240 */
3782 	case Panel_1280x800_2:	/* Verified for Asus A4L */
3783 	case Panel_1280x854:    /* Not verified yet FIXME */
3784 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3785 	   break;
3786 	}
3787      }
3788 #endif
3789 
3790   } else {
3791 
3792      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3793 
3794 	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3795 	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3796 	}
3797 
3798      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3799 
3800 	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3801 	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3802 
3803      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3804 
3805 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3806 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3807 	}
3808 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3809 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3810 	} else {
3811 	   if(SiS_Pr->ChipType < SIS_315H) {
3812 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3813 	   } else {
3814 	      switch(SiS_Pr->SiS_LCDResInfo) {
3815 	      case Panel_800x600:
3816 	      case Panel_1024x768:
3817 	      case Panel_1280x1024:
3818 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3819 		 break;
3820 	      case Panel_1400x1050:
3821 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3822 		 break;
3823 	      }
3824 	   }
3825 	}
3826 
3827      } else {
3828 
3829         if(SiS_Pr->ChipType < SIS_315H) {
3830 #ifdef SIS300
3831 	   switch(SiS_Pr->SiS_LCDResInfo) {
3832 	   case Panel_800x600:
3833 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3834 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3835 	      } else {
3836 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3837 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3838 		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3839 		 else                          SiS_Pr->SiS_LCDVDES -= 4;
3840 	      }
3841 	      break;
3842 	   case Panel_1024x768:
3843 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3844 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3845 	      } else {
3846 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3847 		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3848 		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3849 	      }
3850 	      break;
3851 	   case Panel_1024x600:
3852 	   default:
3853 	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3854 		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3855 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3856 	      } else {
3857 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3858 	      }
3859 	      break;
3860 	   }
3861 
3862 	   switch(SiS_Pr->SiS_LCDTypeInfo) {
3863 	   case 1:
3864 	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3865 	      break;
3866 	   case 3: /* 640x480 only? */
3867 	      SiS_Pr->SiS_LCDHDES = 8;
3868 	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3869 	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3870 	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3871 	      break;
3872 	   }
3873 #endif
3874         } else {
3875 #ifdef SIS315H
3876 	   switch(SiS_Pr->SiS_LCDResInfo) {
3877 	   case Panel_1024x768:
3878 	   case Panel_1280x1024:
3879 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3880 	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3881 	      }
3882 	      break;
3883 	   case Panel_320x240_1:
3884 	   case Panel_320x240_2:
3885 	   case Panel_320x240_3:
3886 	      SiS_Pr->SiS_LCDVDES = 524;
3887 	      break;
3888 	   }
3889 #endif
3890 	}
3891      }
3892 
3893      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3894 	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3895 	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3896 	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3897 	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3898 	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3899 	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3900 	         if(SiS_Pr->ChipType < SIS_315H) {
3901 	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3902 	         } else {
3903 #ifdef SIS315H
3904 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
3905 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3906 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3907 		    if(!(modeflag & HalfDCLK)) {
3908 		       SiS_Pr->SiS_LCDHDES = 320;
3909 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3910 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3911         	    }
3912 #endif
3913 		 }
3914 	      }
3915 	   }
3916 	}
3917      }
3918   }
3919 }
3920 
3921 /*********************************************/
3922 /*           DISABLE VIDEO BRIDGE            */
3923 /*********************************************/
3924 
3925 #ifdef SIS315H
3926 static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)3927 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3928 {
3929    int ret = 0;
3930 #ifdef SET_PWD
3931    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3932    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3933    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3934    unsigned short temp;
3935 
3936    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3937        (romptr)				&&
3938        (SiS_Pr->SiS_PWDOffset) ) {
3939       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3940       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3941       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3942       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3943       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3944       temp = 0x00;
3945       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3946          temp = 0x80;
3947 	 ret = 1;
3948       }
3949       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3950 #ifdef SIS_XORG_XF86
3951 #ifdef TWDEBUG
3952       xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3953 #endif
3954 #endif
3955    }
3956 #endif
3957    return ret;
3958 }
3959 #endif
3960 
3961 /* NEVER use any variables (VBInfo), this will be called
3962  * from outside the context of modeswitch!
3963  * MUST call getVBType before calling this
3964  */
3965 void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)3966 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3967 {
3968 #ifdef SIS315H
3969   unsigned short tempah, pushax=0, modenum;
3970 #endif
3971   unsigned short temp=0;
3972 
3973   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3974 
3975      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
3976 
3977 	if(SiS_Pr->ChipType < SIS_315H) {
3978 
3979 #ifdef SIS300	   /* 300 series */
3980 
3981 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3982 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3983 		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3984 	      } else {
3985 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3986 	      }
3987 	      SiS_PanelDelay(SiS_Pr, 3);
3988 	   }
3989 	   if(SiS_Is301B(SiS_Pr)) {
3990 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3991 	      SiS_ShortDelay(SiS_Pr,1);
3992 	   }
3993 	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3994 	   SiS_DisplayOff(SiS_Pr);
3995 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3996 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3997 	   SiS_UnLockCRT2(SiS_Pr);
3998 	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3999 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4000 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4001 	   }
4002 	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4003 	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4004 	      SiS_PanelDelay(SiS_Pr, 2);
4005 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4006 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4007 	      } else {
4008 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4009 	      }
4010 	   }
4011 
4012 #endif  /* SIS300 */
4013 
4014         } else {
4015 
4016 #ifdef SIS315H	   /* 315 series */
4017 
4018 	   int didpwd = 0;
4019 	   BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4020 	                      (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
4021 
4022 	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4023 
4024 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4025 
4026 #ifdef SET_EMI
4027 	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4028 		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4029 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4030 		 }
4031 	      }
4032 #endif
4033 
4034 	      didpwd = SiS_HandlePWD(SiS_Pr);
4035 
4036 	      if( (modenum <= 0x13)           ||
4037 		  (SiS_IsVAMode(SiS_Pr))      ||
4038 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4039 		 if(!didpwd) {
4040 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4041 		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4042 		 } else {
4043 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4044 		 }
4045 	      }
4046 
4047 	      if(!custom1) {
4048 		 SiS_DDC2Delay(SiS_Pr,0xff00);
4049 		 SiS_DDC2Delay(SiS_Pr,0xe000);
4050 		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4051 		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4052 		 if(IS_SIS740) {
4053 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4054 		 }
4055 	         SiS_PanelDelay(SiS_Pr, 3);
4056 	      }
4057 
4058 	   }
4059 
4060 	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4061 	      /* if(SiS_Pr->ChipType < SIS_340) {*/
4062 		 tempah = 0xef;
4063 		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4064 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4065 	      /*}*/
4066 	   }
4067 
4068 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4069 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4070 	   }
4071 
4072 	   tempah = 0x3f;
4073 	   if(SiS_IsDualEdge(SiS_Pr)) {
4074 	      tempah = 0x7f;
4075 	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4076 	   }
4077 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4078 
4079 	   if((SiS_IsVAMode(SiS_Pr)) ||
4080 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4081 
4082 	      SiS_DisplayOff(SiS_Pr);
4083 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4084 		 SiS_PanelDelay(SiS_Pr, 2);
4085 	      }
4086 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4087 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4088 
4089 	   }
4090 
4091 	   if((!(SiS_IsVAMode(SiS_Pr))) ||
4092 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4093 
4094 	      if(!(SiS_IsDualEdge(SiS_Pr))) {
4095 		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4096 		 SiS_DisplayOff(SiS_Pr);
4097 	      }
4098 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4099 
4100 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4101 		 SiS_PanelDelay(SiS_Pr, 2);
4102 	      }
4103 
4104 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4105 	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4106 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4107 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4108 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4109 
4110 	   }
4111 
4112 	   if(SiS_IsNotM650orLater(SiS_Pr)) {
4113 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4114 	   }
4115 
4116 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4117 
4118 	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4119 		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4120 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4121 
4122 		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4123 		 if(!didpwd) {
4124 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4125 		 }
4126 		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4127 	      }
4128 
4129 	      if(!custom1) {
4130 		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4131 		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4132 		    if(SiS_IsVAorLCD(SiS_Pr)) {
4133 		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4134 		    }
4135 		 }
4136 	      }
4137 
4138 	   }
4139 
4140 #endif /* SIS315H */
4141 
4142 	}
4143 
4144      } else {     /* ============ For 301 ================ */
4145 
4146         if(SiS_Pr->ChipType < SIS_315H) {
4147 #ifdef SIS300
4148 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4149 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4150 	      SiS_PanelDelay(SiS_Pr, 3);
4151 	   }
4152 #endif
4153 	}
4154 
4155 	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4156 	SiS_DisplayOff(SiS_Pr);
4157 
4158 	if(SiS_Pr->ChipType >= SIS_315H) {
4159 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4160 	}
4161 
4162 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4163 
4164 	if(SiS_Pr->ChipType >= SIS_315H) {
4165 	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4166 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4167 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4168 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4169 	} else {
4170 #ifdef SIS300
4171 	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4172 	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4173 		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4174 		SiS_PanelDelay(SiS_Pr, 2);
4175 		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4176 	    }
4177 #endif
4178 	}
4179 
4180       }
4181 
4182   } else {     /* ============ For LVDS =============*/
4183 
4184     if(SiS_Pr->ChipType < SIS_315H) {
4185 
4186 #ifdef SIS300	/* 300 series */
4187 
4188 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4189 	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4190 	}
4191 
4192 	if(SiS_Pr->ChipType == SIS_730) {
4193 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4194 	      SiS_WaitVBRetrace(SiS_Pr);
4195 	   }
4196 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4197 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4198 	      SiS_PanelDelay(SiS_Pr, 3);
4199 	   }
4200 	} else {
4201 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4202 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4203 		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4204 		    SiS_WaitVBRetrace(SiS_Pr);
4205 		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4206 		       SiS_DisplayOff(SiS_Pr);
4207 		    }
4208 		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4209 		    SiS_PanelDelay(SiS_Pr, 3);
4210 		 }
4211 	      }
4212 	   }
4213 	}
4214 
4215 	SiS_DisplayOff(SiS_Pr);
4216 
4217 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4218 
4219 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4220 	SiS_UnLockCRT2(SiS_Pr);
4221 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4222 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4223 
4224 	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4225 	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4226 	   SiS_PanelDelay(SiS_Pr, 2);
4227 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4228 	}
4229 
4230 #endif  /* SIS300 */
4231 
4232     } else {
4233 
4234 #ifdef SIS315H	/* 315 series */
4235 
4236 	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4237 	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4238 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4239 	   /* } */
4240 	}
4241 
4242 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4243 
4244 	   if(SiS_Pr->ChipType == SIS_740) {
4245 	      temp = SiS_GetCH701x(SiS_Pr,0x61);
4246 	      if(temp < 1) {
4247 		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4248 		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4249 	      }
4250 
4251 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4252 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4253 		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4254 	      }
4255 	   }
4256 
4257 	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4258 	       (SiS_IsVAMode(SiS_Pr)) ) {
4259 	      SiS_Chrontel701xBLOff(SiS_Pr);
4260 	      SiS_Chrontel701xOff(SiS_Pr);
4261 	   }
4262 
4263 	   if(SiS_Pr->ChipType != SIS_740) {
4264 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4265 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4266 		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4267 	      }
4268 	   }
4269 
4270 	}
4271 
4272 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4273 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4274 	   SiS_PanelDelay(SiS_Pr, 3);
4275 	}
4276 
4277 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4278 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4279 	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4280 	   SiS_DisplayOff(SiS_Pr);
4281 	}
4282 
4283 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4284 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4285 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4286 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4287 	}
4288 
4289 	if(SiS_Pr->ChipType == SIS_740) {
4290 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4291 	}
4292 
4293 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4294 
4295 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4296 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4297 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4298 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4299 	}
4300 
4301 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4302 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4303 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4304 	      if(SiS_Pr->ChipType == SIS_550) {
4305 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4306 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4307 	      }
4308 	   }
4309 	} else {
4310 	   if(SiS_Pr->ChipType == SIS_740) {
4311 	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4312 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4313 	      }
4314 	   } else if(SiS_IsVAMode(SiS_Pr)) {
4315 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4316 	   }
4317 	}
4318 
4319 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4320 	   if(SiS_IsDualEdge(SiS_Pr)) {
4321 	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4322 	   } else {
4323 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4324 	   }
4325 	}
4326 
4327 	SiS_UnLockCRT2(SiS_Pr);
4328 
4329 	if(SiS_Pr->ChipType == SIS_550) {
4330 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4331 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4332 	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4333 		   (!(SiS_IsDualEdge(SiS_Pr))) ||
4334 		   (!(SiS_IsVAMode(SiS_Pr))) ) {
4335 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4336 	}
4337 
4338         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4339 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4340 	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4341 		 SiS_PanelDelay(SiS_Pr, 2);
4342 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4343 	      }
4344 	   }
4345         }
4346 
4347 #endif  /* SIS315H */
4348 
4349     }  /* 315 series */
4350 
4351   }  /* LVDS */
4352 
4353 }
4354 
4355 /*********************************************/
4356 /*            ENABLE VIDEO BRIDGE            */
4357 /*********************************************/
4358 
4359 /* NEVER use any variables (VBInfo), this will be called
4360  * from outside the context of a mode switch!
4361  * MUST call getVBType before calling this
4362  */
4363 #ifdef SIS_LINUX_KERNEL
4364 static
4365 #endif
4366 void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4367 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4368 {
4369   unsigned short temp=0, tempah;
4370 #ifdef SIS315H
4371   unsigned short temp1, pushax=0;
4372   BOOLEAN delaylong = FALSE;
4373 #endif
4374 
4375   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4376 
4377     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
4378 
4379       if(SiS_Pr->ChipType < SIS_315H) {
4380 
4381 #ifdef SIS300     /* 300 series */
4382 
4383 	 if(SiS_CRT2IsLCD(SiS_Pr)) {
4384 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4385 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4386 	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4387 	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4388 	    }
4389 	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4390 	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4391 		  SiS_PanelDelay(SiS_Pr, 0);
4392 	       }
4393 	    }
4394 	 }
4395 
4396 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4397 	    (SiS_CRT2IsLCD(SiS_Pr))) {
4398 
4399 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4400 	    SiS_DisplayOn(SiS_Pr);
4401 	    SiS_UnLockCRT2(SiS_Pr);
4402 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4403 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4404 	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4405 	    } else {
4406 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4407 	    }
4408 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4409 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4410 		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4411 		     SiS_PanelDelay(SiS_Pr, 1);
4412 		  }
4413 		  SiS_WaitVBRetrace(SiS_Pr);
4414 		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4415 	       }
4416 	    }
4417 
4418 	 } else {
4419 
4420 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4421 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4422 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4423 	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4424 	    }
4425 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4426 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4427 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4428 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4429 	    SiS_DisplayOn(SiS_Pr);
4430 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4431 	       if(SiS_CRT2IsLCD(SiS_Pr)) {
4432 		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4433 		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4434 		        SiS_PanelDelay(SiS_Pr, 1);
4435 		     }
4436 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4437 		  }
4438 	       }
4439 	    }
4440 
4441 	 }
4442 
4443 
4444 #endif /* SIS300 */
4445 
4446       } else {
4447 
4448 #ifdef SIS315H    /* 315 series */
4449 
4450 #ifdef SET_EMI
4451 	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4452 	 int didpwd = 0;
4453 	 /* unsigned short  emidelay=0; */
4454 #endif
4455 
4456 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4457 	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4458 #ifdef SET_EMI
4459 	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4460 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4461 	    }
4462 #endif
4463 	 }
4464 
4465 	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4466 	    /*if(SiS_Pr->ChipType < SIS_340) { */
4467 	       tempah = 0x10;
4468 	       if(SiS_LCDAEnabled(SiS_Pr)) {
4469 		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4470 		  else			    tempah = 0x08;
4471 	       }
4472 	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4473 	    /*}*/
4474 	 }
4475 
4476 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4477 
4478 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4479 	    SiS_DisplayOff(SiS_Pr);
4480 	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4481 	    if(IS_SIS740) {
4482 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4483 	    }
4484 
4485 	    didpwd = SiS_HandlePWD(SiS_Pr);
4486 
4487 	    if(SiS_IsVAorLCD(SiS_Pr)) {
4488 	       if(!didpwd) {
4489 		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4490 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4491 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4492 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4493 		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4494 		        SiS_GenericDelay(SiS_Pr, 17664);
4495 		     }
4496 		  }
4497 	       } else {
4498 		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4499 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4500 		     SiS_GenericDelay(SiS_Pr, 17664);
4501 		  }
4502 	       }
4503 	    }
4504 
4505 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4506 	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4507 	       delaylong = TRUE;
4508 	    }
4509 
4510 	 }
4511 
4512 	 if(!(SiS_IsVAMode(SiS_Pr))) {
4513 
4514 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4515 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4516 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4517 	       if(!(tempah & SetCRT2ToRAMDAC)) {
4518 		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4519 	       }
4520 	    }
4521 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4522 
4523 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4524 
4525 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4526 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4527 
4528 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4529 	       SiS_PanelDelay(SiS_Pr, 2);
4530 	    }
4531 
4532 	 } else {
4533 
4534 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4535 
4536 	 }
4537 
4538 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4539 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4540 
4541 	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4542 	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
4543 	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
4544 	       /* Enable "LVDS PLL power on" (even on 301C) */
4545 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4546 	       /* Enable "LVDS Driver Power on" (even on 301C) */
4547 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4548 	    }
4549 	 }
4550 
4551 	 tempah = 0xc0;
4552 	 if(SiS_IsDualEdge(SiS_Pr)) {
4553 	    tempah = 0x80;
4554 	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4555 	 }
4556 	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4557 
4558 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4559 
4560 	    SiS_PanelDelay(SiS_Pr, 2);
4561 
4562 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4563 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4564 
4565 	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4566 #ifdef SET_EMI
4567 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4568 		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4569 		  SiS_GenericDelay(SiS_Pr, 2048);
4570 	       }
4571 #endif
4572 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4573 
4574 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4575 #ifdef SET_EMI
4576 		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4577 
4578 		  if(SiS_Pr->SiS_ROMNew) {
4579 		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4580 		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4581 		     if(romptr) {
4582 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4583 			SiS_Pr->EMI_30 = 0;
4584 			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4585 			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4586 			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4587 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4588 			/* emidelay = SISGETROMW((romptr + 0x22)); */
4589 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4590 		     }
4591 		  }
4592 
4593 		  /*                                              (P4_30|0x40)  */
4594 		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4595 		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4596 		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4597 		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4598 		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4599 		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4600 		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4601 		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4602 		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4603 
4604 		  if(SiS_Pr->HaveEMI) {
4605 		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4606 		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4607 		  } else {
4608 		     r30 = 0;
4609 		  }
4610 
4611 		  /* EMI_30 is read at driver start; however, the BIOS sets this
4612 		   * (if it is used) only if the LCD is in use. In case we caught
4613 		   * the machine while on TV output, this bit is not set and we
4614 		   * don't know if it should be set - hence our detection is wrong.
4615 		   * Work-around this here:
4616 		   */
4617 
4618 		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4619 		     switch((cr36 & 0x0f)) {
4620 		     case 2:
4621 			r30 |= 0x40;
4622 			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4623 			if(!SiS_Pr->HaveEMI) {
4624 			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4625 			   if((cr36 & 0xf0) == 0x30) {
4626 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4627 			   }
4628 			}
4629 			break;
4630 		     case 3:  /* 1280x1024 */
4631 			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4632 			if(!SiS_Pr->HaveEMI) {
4633 			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4634 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4635 			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4636 			   }
4637 			}
4638 			break;
4639 		     case 9:  /* 1400x1050 */
4640 			r30 |= 0x40;
4641 			if(!SiS_Pr->HaveEMI) {
4642 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4643 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4644 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4645 			   }
4646 			}
4647 			break;
4648 		     case 11: /* 1600x1200 - unknown */
4649 			r30 |= 0x40;
4650 			if(!SiS_Pr->HaveEMI) {
4651 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4652 			}
4653 		     }
4654                   }
4655 
4656 		  /* BIOS values don't work so well sometimes */
4657 		  if(!SiS_Pr->OverruleEMI) {
4658 #ifdef COMPAL_HACK
4659 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4660 			if((cr36 & 0x0f) == 0x09) {
4661 			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4662 			}
4663  		     }
4664 #endif
4665 #ifdef COMPAQ_HACK
4666 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4667 			if((cr36 & 0x0f) == 0x03) {
4668 			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4669 			}
4670 		     }
4671 #endif
4672 #ifdef ASUS_HACK
4673 		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4674 			if((cr36 & 0x0f) == 0x02) {
4675 			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4676 			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4677 			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4678 			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4679 			}
4680 		     }
4681 #endif
4682 		  }
4683 
4684 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4685 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4686 		     SiS_GenericDelay(SiS_Pr, 2048);
4687 		  }
4688 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4689 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4690 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4691 #endif	/* SET_EMI */
4692 
4693 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4694 
4695 #ifdef SET_EMI
4696 		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4697 		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
4698 		     if(r30 & 0x40) {
4699 			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4700 			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4701 			if(delaylong) {
4702 			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4703 			   delaylong = FALSE;
4704 			}
4705 			SiS_WaitVBRetrace(SiS_Pr);
4706 			SiS_WaitVBRetrace(SiS_Pr);
4707 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4708 			   SiS_GenericDelay(SiS_Pr, 1280);
4709 			}
4710 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4711 			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4712 		     }
4713 		  }
4714 #endif
4715 	       }
4716 	    }
4717 
4718 	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4719 	       if(SiS_IsVAorLCD(SiS_Pr)) {
4720 		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4721 		  if(delaylong) {
4722 		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4723 		  }
4724 		  SiS_WaitVBRetrace(SiS_Pr);
4725 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4726 		     SiS_GenericDelay(SiS_Pr, 2048);
4727 		     SiS_WaitVBRetrace(SiS_Pr);
4728 		  }
4729 		  if(!didpwd) {
4730 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4731 		  } else {
4732 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4733 		  }
4734 	       }
4735 	    }
4736 
4737 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4738 	    SiS_DisplayOn(SiS_Pr);
4739 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4740 
4741 	 }
4742 
4743 	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4744 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4745 	 }
4746 
4747 #endif /* SIS315H */
4748 
4749       }
4750 
4751     } else {	/* ============  For 301 ================ */
4752 
4753        if(SiS_Pr->ChipType < SIS_315H) {
4754 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4755 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4756 	     SiS_PanelDelay(SiS_Pr, 0);
4757 	  }
4758        }
4759 
4760        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4761        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4762 	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4763 	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4764        }
4765        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4766 
4767        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4768 
4769        if(SiS_Pr->ChipType >= SIS_315H) {
4770 	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4771 	  if(!(temp & 0x80)) {
4772 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4773 	  }
4774        }
4775 
4776        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4777 
4778        SiS_VBLongWait(SiS_Pr);
4779        SiS_DisplayOn(SiS_Pr);
4780        if(SiS_Pr->ChipType >= SIS_315H) {
4781 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4782        }
4783        SiS_VBLongWait(SiS_Pr);
4784 
4785        if(SiS_Pr->ChipType < SIS_315H) {
4786 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4787 	     SiS_PanelDelay(SiS_Pr, 1);
4788 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4789 	  }
4790        }
4791 
4792     }
4793 
4794   } else {   /* =================== For LVDS ================== */
4795 
4796     if(SiS_Pr->ChipType < SIS_315H) {
4797 
4798 #ifdef SIS300    /* 300 series */
4799 
4800        if(SiS_CRT2IsLCD(SiS_Pr)) {
4801 	  if(SiS_Pr->ChipType == SIS_730) {
4802 	     SiS_PanelDelay(SiS_Pr, 1);
4803 	     SiS_PanelDelay(SiS_Pr, 1);
4804 	     SiS_PanelDelay(SiS_Pr, 1);
4805 	  }
4806 	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4807 	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4808 	     SiS_PanelDelay(SiS_Pr, 0);
4809 	  }
4810        }
4811 
4812        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4813        SiS_DisplayOn(SiS_Pr);
4814        SiS_UnLockCRT2(SiS_Pr);
4815        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4816        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4817 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4818        } else {
4819 	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4820        }
4821 
4822        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4823 	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4824 	     SiS_WaitVBRetrace(SiS_Pr);
4825 	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4826 	  }
4827        }
4828 
4829        if(SiS_CRT2IsLCD(SiS_Pr)) {
4830 	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4831 	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4832 		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4833 		   SiS_PanelDelay(SiS_Pr, 1);
4834 		   SiS_PanelDelay(SiS_Pr, 1);
4835 		}
4836 		SiS_WaitVBRetrace(SiS_Pr);
4837 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4838 	     }
4839 	  }
4840        }
4841 
4842 #endif  /* SIS300 */
4843 
4844     } else {
4845 
4846 #ifdef SIS315H    /* 315 series */
4847 
4848        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4849 	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
4850 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4851 	  /*}*/
4852        }
4853 
4854        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4855 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4856 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4857 	     SiS_PanelDelay(SiS_Pr, 0);
4858 	  }
4859        }
4860 
4861        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4862        SiS_UnLockCRT2(SiS_Pr);
4863 
4864        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4865 
4866        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4867 	  temp = SiS_GetCH701x(SiS_Pr,0x66);
4868 	  temp &= 0x20;
4869 	  SiS_Chrontel701xBLOff(SiS_Pr);
4870        }
4871 
4872        if(SiS_Pr->ChipType != SIS_550) {
4873 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4874        }
4875 
4876        if(SiS_Pr->ChipType == SIS_740) {
4877 	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4878 	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4879 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4880 	     }
4881 	  }
4882        }
4883 
4884        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4885        if(!(temp1 & 0x80)) {
4886 	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4887        }
4888 
4889        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4890 	  if(temp) {
4891 	     SiS_Chrontel701xBLOn(SiS_Pr);
4892 	  }
4893        }
4894 
4895        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4896 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4897 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4898 	     if(SiS_Pr->ChipType == SIS_550) {
4899 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4900 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4901 	     }
4902 	  }
4903        } else if(SiS_IsVAMode(SiS_Pr)) {
4904 	  if(SiS_Pr->ChipType != SIS_740) {
4905 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4906 	  }
4907        }
4908 
4909        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4910 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4911        }
4912 
4913        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4914 	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4915 	     SiS_Chrontel701xOn(SiS_Pr);
4916 	  }
4917 	  if( (SiS_IsVAMode(SiS_Pr)) ||
4918 	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4919 	     SiS_ChrontelDoSomething1(SiS_Pr);
4920 	  }
4921        }
4922 
4923        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4924 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4925 	     if( (SiS_IsVAMode(SiS_Pr)) ||
4926 		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4927 		SiS_Chrontel701xBLOn(SiS_Pr);
4928 		SiS_ChrontelInitTVVSync(SiS_Pr);
4929 	     }
4930 	  }
4931        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4932 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4933 	     if(SiS_CRT2IsLCD(SiS_Pr)) {
4934 		SiS_PanelDelay(SiS_Pr, 1);
4935 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4936 	     }
4937 	  }
4938        }
4939 
4940 #endif  /* SIS315H */
4941 
4942     } /* 310 series */
4943 
4944   }  /* LVDS */
4945 
4946 }
4947 
4948 /*********************************************/
4949 /*         SET PART 1 REGISTER GROUP         */
4950 /*********************************************/
4951 
4952 /* Set CRT2 OFFSET / PITCH */
4953 static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)4954 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4955 		unsigned short RRTI)
4956 {
4957    unsigned short offset;
4958    unsigned char  temp;
4959 
4960    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4961 
4962    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4963 
4964    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4965    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4966 
4967    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4968    if(offset & 0x07) temp++;
4969    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4970 }
4971 
4972 /* Set CRT2 sync and PanelLink mode */
4973 static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)4974 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4975 {
4976    unsigned short tempah=0, tempbl, infoflag;
4977 
4978    tempbl = 0xC0;
4979 
4980    if(SiS_Pr->UseCustomMode) {
4981       infoflag = SiS_Pr->CInfoFlag;
4982    } else {
4983       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4984    }
4985 
4986    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
4987 
4988       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4989 	 tempah = 0;
4990       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4991 	 tempah = SiS_Pr->SiS_LCDInfo;
4992       } else tempah = infoflag >> 8;
4993       tempah &= 0xC0;
4994       tempah |= 0x20;
4995       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4996       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4997 	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4998 	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4999 	    tempah |= 0xf0;
5000 	 }
5001 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5002 	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
5003 	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5004 	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5005 	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5006 	    tempah |= 0x30;
5007 	 }
5008 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5009 	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5010 	    tempah &= ~0xc0;
5011 	 }
5012       }
5013       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5014 	 if(SiS_Pr->ChipType >= SIS_315H) {
5015 	    tempah >>= 3;
5016 	    tempah &= 0x18;
5017 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5018 	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5019 	 } else {
5020 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5021 	 }
5022       } else {
5023 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5024       }
5025 
5026    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5027 
5028       if(SiS_Pr->ChipType < SIS_315H) {
5029 
5030 #ifdef SIS300  /* ---- 300 series --- */
5031 
5032 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
5033 
5034 	    tempah = infoflag >> 8;
5035 	    tempbl = 0;
5036 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5037 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5038 		  tempah = SiS_Pr->SiS_LCDInfo;
5039 		  tempbl = (tempah >> 6) & 0x03;
5040 	       }
5041 	    }
5042 	    tempah &= 0xC0;
5043 	    tempah |= 0x20;
5044 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5045 	    tempah |= 0xc0;
5046 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5047 	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5048 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5049 	    }
5050 
5051 	 } else {							/* 630 - 301 */
5052 
5053 	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5054 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5055 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5056 
5057 	 }
5058 
5059 #endif /* SIS300 */
5060 
5061       } else {
5062 
5063 #ifdef SIS315H  /* ------- 315 series ------ */
5064 
5065 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
5066 
5067 	    tempbl = 0;
5068 	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5069 	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5070 	       tempah = infoflag >> 8;
5071 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5072 		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5073 	       }
5074 	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5075 		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5076 	       tempah = infoflag >> 8;
5077 	       tempbl = 0x03;
5078 	    } else {
5079 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5080 	       tempbl = (tempah >> 6) & 0x03;
5081 	       tempbl |= 0x08;
5082 	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5083 	    }
5084 	    tempah &= 0xC0;
5085 	    tempah |= 0x20;
5086 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5087 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5088 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5089 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5090 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5091 		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5092 	       }
5093 	    }
5094 
5095 	 } else {							/* 315 - TMDS */
5096 
5097 	    tempah = tempbl = infoflag >> 8;
5098 	    if(!SiS_Pr->UseCustomMode) {
5099 	       tempbl = 0;
5100 	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5101 		  if(ModeNo <= 0x13) {
5102 		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5103 		  }
5104 	       }
5105 	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5106 		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5107 		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5108 		       tempah = SiS_Pr->SiS_LCDInfo;
5109 		       tempbl = (tempah >> 6) & 0x03;
5110 		    }
5111 		  }
5112 	       }
5113 	    }
5114 	    tempah &= 0xC0;
5115 	    tempah |= 0x20;
5116 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5117 	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5118 	       /* Imitate BIOS bug */
5119 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5120 	    }
5121 	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5122 	       tempah >>= 3;
5123 	       tempah &= 0x18;
5124 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5125 	    } else {
5126 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5127 	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5128 		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5129 		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5130 		  }
5131 	       }
5132 	    }
5133 
5134          }
5135 #endif  /* SIS315H */
5136       }
5137    }
5138 }
5139 
5140 /* Set CRT2 FIFO on 300/540/630/730 */
5141 #ifdef SIS300
5142 static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5143 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5144 {
5145   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5146   unsigned short temp, index, modeidindex, refreshratetableindex;
5147   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5148   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5149   unsigned int   data, pci50, pciA0;
5150   static const unsigned char colortharray[] = {
5151   	1, 1, 2, 2, 3, 4
5152   };
5153 
5154   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5155 
5156   if(!SiS_Pr->CRT1UsesCustomMode) {
5157 
5158      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5159      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5160      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5161      SiS_Pr->SiS_SelectCRT2Rate = 0;
5162      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5163 
5164      if(CRT1ModeNo >= 0x13) {
5165         /* Get VCLK */
5166 	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5167 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5168 
5169 	/* Get colordepth */
5170 	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5171 	if(!colorth) colorth++;
5172      }
5173 
5174   } else {
5175 
5176      CRT1ModeNo = 0xfe;
5177 
5178      /* Get VCLK */
5179      VCLK = SiS_Pr->CSRClock_CRT1;
5180 
5181      /* Get color depth */
5182      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5183 
5184   }
5185 
5186   if(CRT1ModeNo >= 0x13) {
5187      /* Get MCLK */
5188      if(SiS_Pr->ChipType == SIS_300) {
5189         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5190      } else {
5191         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5192      }
5193      index &= 0x07;
5194      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5195 
5196      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5197      if(!temp) temp++;
5198      temp <<= 2;
5199 
5200      data2 = temp - ((colorth * VCLK) / MCLK);
5201 
5202      temp = (28 * 16) % data2;
5203      data2 = (28 * 16) / data2;
5204      if(temp) data2++;
5205 
5206      if(SiS_Pr->ChipType == SIS_300) {
5207 
5208 	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5209 	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5210 
5211      } else {
5212 
5213 #ifdef SIS_LINUX_KERNEL
5214 	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5215 	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5216 #else
5217 	pci50 = sis_pci_read_host_bridge_u32(0x50);
5218 	pciA0 = sis_pci_read_host_bridge_u32(0xA0);
5219 #endif
5220 
5221         if(SiS_Pr->ChipType == SIS_730) {
5222 
5223 	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5224 	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
5225 
5226 	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5227 	   index = 0;  /* -- do it like the BIOS anyway... */
5228 
5229 	} else {
5230 
5231 	   pci50 >>= 24;
5232 	   pciA0 >>= 24;
5233 
5234 	   index = (pci50 >> 1) & 0x07;
5235 
5236 	   if(pci50 & 0x01)    index += 6;
5237 	   if(!(pciA0 & 0x01)) index += 24;
5238 
5239 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5240 
5241 	}
5242 
5243 	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5244 	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5245 
5246      }
5247 
5248      data += data2;						/* CRT1 Request Period */
5249 
5250      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5251      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5252 
5253      if(!SiS_Pr->UseCustomMode) {
5254 
5255 	CRT2ModeNo = ModeNo;
5256 	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5257 
5258 	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5259 
5260 	/* Get VCLK  */
5261 	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5262 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5263 
5264 	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5265 	   if(SiS_Pr->SiS_UseROM) {
5266 	      if(ROMAddr[0x220] & 0x01) {
5267 		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5268 	      }
5269            }
5270         }
5271 
5272      } else {
5273 
5274 	/* Get VCLK */
5275 	CRT2ModeNo = 0xfe;
5276 	VCLK = SiS_Pr->CSRClock;
5277 
5278      }
5279 
5280      /* Get colordepth */
5281      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5282      if(!colorth) colorth++;
5283 
5284      data = data * VCLK * colorth;
5285      temp = data % (MCLK << 4);
5286      data = data / (MCLK << 4);
5287      if(temp) data++;
5288 
5289      if(data < 6) data = 6;
5290      else if(data > 0x14) data = 0x14;
5291 
5292      if(SiS_Pr->ChipType == SIS_300) {
5293         temp = 0x16;
5294 	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5295 	   temp = 0x13;
5296      } else {
5297         temp = 0x16;
5298 	if(( (SiS_Pr->ChipType == SIS_630) ||
5299 	     (SiS_Pr->ChipType == SIS_730) )  &&
5300 	   (SiS_Pr->ChipRevision >= 0x30))
5301 	   temp = 0x1b;
5302      }
5303      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5304 
5305      if((SiS_Pr->ChipType == SIS_630) &&
5306 	(SiS_Pr->ChipRevision >= 0x30)) {
5307 	if(data > 0x13) data = 0x13;
5308      }
5309      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5310 
5311   } else {  /* If mode <= 0x13, we just restore everything */
5312 
5313      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5314      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5315 
5316   }
5317 }
5318 #endif
5319 
5320 /* Set CRT2 FIFO on 315/330 series */
5321 #ifdef SIS315H
5322 static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5323 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5324 {
5325   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5326   if( (SiS_Pr->ChipType == SIS_760)      &&
5327       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5328       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5329       (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5330       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5331      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5332      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5333      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5334      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5335      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5336      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5337   } else {
5338      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5339   }
5340 
5341 }
5342 #endif
5343 
5344 static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5345 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5346 {
5347   unsigned int tempax,tempbx;
5348 
5349   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5350   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5351   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5352   return (unsigned short)tempax;
5353 }
5354 
5355 /* Set Part 1 / SiS bridge slave mode */
5356 static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5357 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5358                   unsigned short RefreshRateTableIndex)
5359 {
5360   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5361   static const unsigned short CRTranslation[] = {
5362        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5363 	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5364        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5365 	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5366        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5367 	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5368   };
5369 
5370   if(ModeNo <= 0x13) {
5371      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5372   } else if(SiS_Pr->UseCustomMode) {
5373      modeflag = SiS_Pr->CModeFlag;
5374      xres = SiS_Pr->CHDisplay;
5375   } else {
5376      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5377      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5378   }
5379 
5380   /* The following is only done if bridge is in slave mode: */
5381 
5382   if(SiS_Pr->ChipType >= SIS_315H) {
5383      if(xres >= 1600) {  /* BIOS: == 1600 */
5384         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5385      }
5386   }
5387 
5388   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5389 
5390   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5391   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5392 
5393   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5394   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5395      SiS_Pr->CHBlankStart += 16;
5396   }
5397 
5398   SiS_Pr->CHBlankEnd = 32;
5399   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5400      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5401   }
5402 
5403   temp = SiS_Pr->SiS_VGAHT - 96;
5404   if(!(modeflag & HalfDCLK)) temp -= 32;
5405   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5406      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5407      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5408      temp -= 3;
5409      temp <<= 3;
5410   } else {
5411      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5412   }
5413   SiS_Pr->CHSyncStart = temp;
5414 
5415   SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
5416 
5417   SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
5418 
5419   VGAVDE = SiS_Pr->SiS_VGAVDE;
5420   if     (VGAVDE ==  357) VGAVDE =  350;
5421   else if(VGAVDE ==  360) VGAVDE =  350;
5422   else if(VGAVDE ==  375) VGAVDE =  350;
5423   else if(VGAVDE ==  405) VGAVDE =  400;
5424   else if(VGAVDE ==  420) VGAVDE =  400;
5425   else if(VGAVDE ==  525) VGAVDE =  480;
5426   else if(VGAVDE == 1056) VGAVDE = 1024;
5427   SiS_Pr->CVDisplay = VGAVDE;
5428 
5429   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5430 
5431   SiS_Pr->CVBlankEnd = 1;
5432   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5433 
5434   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5435   SiS_Pr->CVSyncStart = VGAVDE + temp;
5436 
5437   temp >>= 3;
5438   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5439 
5440   SiS_CalcCRRegisters(SiS_Pr, 0);
5441   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5442 
5443   for(i = 0; i <= 7; i++) {
5444      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5445   }
5446   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5447      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5448   }
5449   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5450      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5451   }
5452   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5453      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5454   }
5455 
5456   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5457   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5458 
5459   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5460   if(modeflag & DoubleScanMode) temp |= 0x80;
5461   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5462 
5463   temp = 0;
5464   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5465   if(modeflag & HalfDCLK) temp |= 0x08;
5466   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5467 
5468   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
5469   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
5470 
5471   temp = 0;
5472   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5473      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5474   }
5475   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
5476 
5477   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5478   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
5479 
5480 #ifdef SIS_XORG_XF86
5481 #ifdef TWDEBUG
5482    xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
5483 	SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5484 	SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5485 	SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5486 
5487    xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5488 	SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5489 	SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5490 	SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5491 	SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5492    xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5493 	SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5494 	SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5495 	SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5496 	SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5497    xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5498 #endif
5499 #endif
5500 }
5501 
5502 /* Setup panel link
5503  * This is used for LVDS, LCDA and Chrontel TV output
5504  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5505  */
5506 static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5507 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5508 		unsigned short RefreshRateTableIndex)
5509 {
5510   unsigned short modeflag, resinfo = 0;
5511   unsigned short push2, tempax, tempbx, tempcx, temp;
5512   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5513   BOOLEAN islvds = FALSE, issis  = FALSE, chkdclkfirst = FALSE;
5514   BOOLEAN lvds550 = FALSE;
5515 #ifdef SIS300
5516   unsigned short crt2crtc = 0;
5517 #endif
5518 #ifdef SIS315H
5519   unsigned short pushcx;
5520 #endif
5521 
5522   if(ModeNo <= 0x13) {
5523      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5524      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5525 #ifdef SIS300
5526      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5527 #endif
5528   } else if(SiS_Pr->UseCustomMode) {
5529      modeflag = SiS_Pr->CModeFlag;
5530   } else {
5531      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5532      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5533 #ifdef SIS300
5534      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5535 #endif
5536   }
5537 
5538   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5539   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5540      islvds = TRUE;
5541   }
5542 
5543   if(SiS_Pr->ChipType == SIS_550 &&
5544      SiS_Pr->SiS_IF_DEF_LVDS     &&
5545      !SiS_Pr->SiS_IF_DEF_FSTN    &&
5546      !SiS_Pr->SiS_IF_DEF_DSTN) {
5547      lvds550 = TRUE;
5548   }
5549 
5550   /* is really sis if sis bridge, but not 301B-DH */
5551   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5552      issis = TRUE;
5553   }
5554 
5555   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5556      if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) {
5557         chkdclkfirst = TRUE;
5558      }
5559   }
5560 
5561 #ifdef SIS315H
5562   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5563      if(IS_SIS330) {
5564         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5565      } else if(IS_SIS740) {
5566         if(islvds) {
5567            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5568 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5569         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5570            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5571         }
5572      } else {
5573         if(islvds) {
5574            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5575 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5576         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5577            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5578 	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5579 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5580 	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5581 	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5582 	      }
5583 	   }
5584         }
5585      }
5586   }
5587 #endif
5588 
5589   /* Horizontal */
5590 
5591   tempax = SiS_Pr->SiS_LCDHDES;
5592   if(islvds) {
5593      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5594 	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) {
5595 	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5596 	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5597 	      tempax -= 8;
5598 	   }
5599 	}
5600      }
5601   }
5602 
5603   temp = (tempax & 0x0007);
5604   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5605   temp = (tempax >> 3) & 0x00FF;
5606   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5607 
5608   tempbx = SiS_Pr->SiS_HDE;
5609   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5610      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5611         tempbx = SiS_Pr->PanelXRes;
5612      }
5613      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5614         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5615         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5616         tempbx >>= 1;
5617      }
5618   }
5619 
5620   tempax += tempbx;
5621   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5622 
5623   temp = tempax;
5624   if(temp & 0x07) temp += 8;
5625   temp >>= 3;
5626   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5627 
5628   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5629 
5630   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5631      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5632         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5633      }
5634   }
5635 
5636   tempcx += tempax;
5637   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5638 
5639   temp = (tempcx >> 3) & 0x00FF;
5640   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5641      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5642 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5643 	   switch(ModeNo) {
5644 	   case 0x04:
5645 	   case 0x05:
5646 	   case 0x0d: temp = 0x56; break;
5647 	   case 0x10: temp = 0x60; break;
5648 	   case 0x13: temp = 0x5f; break;
5649 	   case 0x40:
5650 	   case 0x41:
5651 	   case 0x4f:
5652 	   case 0x43:
5653 	   case 0x44:
5654 	   case 0x62:
5655 	   case 0x56:
5656 	   case 0x53:
5657 	   case 0x5d:
5658 	   case 0x5e: temp = 0x54; break;
5659 	   }
5660 	}
5661      }
5662   }
5663   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5664 
5665   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5666      temp += 2;
5667      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5668 	temp += 8;
5669 	if(SiS_Pr->PanelHRE != 999) {
5670 	   temp = tempcx + SiS_Pr->PanelHRE;
5671 	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5672 	   temp >>= 3;
5673 	}
5674      }
5675   } else {
5676      temp += 10;
5677   }
5678 
5679   temp &= 0x1F;
5680   temp |= ((tempcx & 0x07) << 5);
5681   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5682 
5683   /* Vertical */
5684 
5685   tempax = SiS_Pr->SiS_VGAVDE;
5686   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5687      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5688 	tempax = SiS_Pr->PanelYRes;
5689      }
5690   }
5691 
5692   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5693   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5694 
5695   push2 = tempbx;
5696 
5697   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5698   if((SiS_Pr->ChipType < SIS_315H) || lvds550) {
5699      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5700 	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5701 	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5702 	}
5703      }
5704   }
5705   if(islvds) tempcx >>= 1;
5706   else       tempcx >>= 2;
5707 
5708   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5709       (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5710       (SiS_Pr->PanelVRS != 999) ) {
5711      tempcx = SiS_Pr->PanelVRS;
5712      tempbx += tempcx;
5713      if(issis || lvds550) tempbx++;
5714   } else {
5715      tempbx += tempcx;
5716      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5717      else if(issis || lvds550)       tempbx++;
5718   }
5719 
5720   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5721 
5722   temp = tempbx & 0x00FF;
5723   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5724      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5725 	if(ModeNo == 0x10) temp = 0xa9;
5726      }
5727   }
5728   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
5729 
5730   tempcx >>= 3;
5731   tempcx++;
5732 
5733   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5734      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5735         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5736      }
5737   }
5738 
5739   tempcx += tempbx;
5740   temp = tempcx & 0x000F;
5741   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5742 
5743   temp = ((tempbx >> 8) & 0x07) << 3;
5744   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN || lvds550) {
5745      if(SiS_Pr->SiS_HDE != 640) {
5746         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5747      }
5748   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5749   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5750   tempbx = 0x87;
5751   if((SiS_Pr->ChipType >= SIS_315H) ||
5752      (SiS_Pr->ChipRevision >= 0x30)) {
5753      tempbx = 0x07;
5754      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5755 	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5756      }
5757      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5758      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5759 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5760 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5761 	} else {
5762 	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5763 	}
5764      }
5765   }
5766   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5767 
5768   tempbx = push2;						/* BPLVDEE */
5769 
5770   tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
5771 
5772   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5773      switch(SiS_Pr->SiS_LCDResInfo) {
5774      case Panel_640x480:
5775 	tempbx = SiS_Pr->SiS_VGAVDE - 1;
5776 	tempcx = SiS_Pr->SiS_VGAVDE;
5777 	break;
5778      case Panel_800x600:
5779 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5780 	   if(resinfo == SIS_RI_800x600) tempcx++;
5781 	}
5782 	break;
5783      case Panel_1024x600:
5784 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5785 	   if(resinfo == SIS_RI_1024x600) tempcx++;
5786 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5787 	      if(resinfo == SIS_RI_800x600) tempcx++;
5788 	   }
5789 	}
5790 	break;
5791      case Panel_1024x768:
5792 	if(SiS_Pr->ChipType < SIS_315H) {
5793 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5794 	      if(resinfo == SIS_RI_1024x768) tempcx++;
5795 	   }
5796 	}
5797 	break;
5798      }
5799   }
5800 
5801   temp = ((tempbx >> 8) & 0x07) << 3;
5802   temp |= ((tempcx >> 8) & 0x07);
5803   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5804   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5805   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5806 
5807   /* Vertical scaling */
5808 
5809   if(SiS_Pr->ChipType < SIS_315H) {
5810 
5811 #ifdef SIS300      /* 300 series */
5812      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5813      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5814      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5815      if(temp) tempeax++;
5816 
5817      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5818 
5819      temp = (unsigned short)(tempeax & 0x00FF);
5820      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5821      tempvcfact = temp;
5822 #endif /* SIS300 */
5823 
5824   } else {
5825 
5826 #ifdef SIS315H  /* 315 series */
5827      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5828      tempebx = SiS_Pr->SiS_VDE;
5829      temp = (tempeax % tempebx);
5830      tempeax = tempeax / tempebx;
5831      if(temp) tempeax++;
5832      tempvcfact = tempeax;
5833 
5834      temp = (unsigned short)(tempeax & 0x00FF);
5835      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5836      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5837      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5838      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5839      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5840      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5841 
5842      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5843         temp = (unsigned short)(tempeax & 0x00FF);
5844         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5845         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5846         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5847         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5848         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5849         temp = 0;
5850         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5851         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5852      }
5853 #endif
5854 
5855   }
5856 
5857   /* Horizontal scaling */
5858 
5859   tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5860   if(chkdclkfirst) {
5861      if(modeflag & HalfDCLK) tempeax >>= 1;
5862   }
5863   tempebx = tempeax << 16;
5864   if(SiS_Pr->SiS_HDE == tempeax) {
5865      tempecx = 0xFFFF;
5866   } else {
5867      tempecx = tempebx / SiS_Pr->SiS_HDE;
5868      if(SiS_Pr->ChipType >= SIS_315H) {
5869         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5870      }
5871   }
5872 
5873   if(SiS_Pr->ChipType >= SIS_315H) {
5874      tempeax = (tempebx / tempecx) - 1;
5875   } else {
5876      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5877   }
5878   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5879   temp = (unsigned short)(tempecx & 0x00FF);
5880   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5881 
5882   if(SiS_Pr->ChipType >= SIS_315H) {
5883      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5884      tempbx = (unsigned short)(tempeax & 0xFFFF);
5885   } else {
5886      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5887      tempbx = tempvcfact & 0x3f;
5888      if(tempbx == 0) tempbx = 64;
5889      tempeax /= tempbx;
5890      tempbx = (unsigned short)(tempeax & 0xFFFF);
5891   }
5892   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5893   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5894      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5895      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
5896   }
5897 
5898   temp = ((tempbx >> 8) & 0x07) << 3;
5899   temp = temp | ((tempecx >> 8) & 0x07);
5900   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5901   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5902 
5903   tempecx >>= 16;						/* BPLHCFACT  */
5904   if(!chkdclkfirst) {
5905      if(modeflag & HalfDCLK) tempecx >>= 1;
5906   }
5907   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5908   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5909   temp = (unsigned short)(tempecx & 0x00FF);
5910   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5911 
5912 #ifdef SIS315H
5913   if(SiS_Pr->ChipType >= SIS_315H) {
5914      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5915         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5916            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5917 	}
5918      } else {
5919         if(islvds) {
5920            if(SiS_Pr->ChipType == SIS_740) {
5921               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5922            } else {
5923 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5924            }
5925         }
5926      }
5927   }
5928 #endif
5929 
5930 #ifdef SIS300
5931   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5932      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5933      unsigned char *trumpdata;
5934      int   i, j = crt2crtc;
5935      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
5936      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5937      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5938 
5939      if(SiS_Pr->SiS_UseROM) {
5940 	trumpdata = &ROMAddr[0x8001 + (j * 80)];
5941      } else {
5942 	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5943 	trumpdata = &SiS300_TrumpionData[j][0];
5944      }
5945 
5946      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5947      for(i=0; i<5; i++) {
5948 	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5949      }
5950      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5951 	if(ModeNo == 0x13) {
5952 	   for(i=0; i<4; i++) {
5953 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5954 	   }
5955 	} else if(ModeNo == 0x10) {
5956 	   for(i=0; i<4; i++) {
5957 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5958 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5959 	   }
5960 	}
5961      }
5962      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5963   }
5964 #endif
5965 
5966 #ifdef SIS315H
5967   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5968      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5969      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5970      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5971      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5972      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5973      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5974      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5975      tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5976      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5977         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5978         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5979      tempax += 64;
5980      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5981      temp = (tempax >> 8) << 3;
5982      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5983      tempax += 32;						/* Blpe = lBlps+32 */
5984      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5985      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
5986      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5987 
5988      tempax = SiS_Pr->SiS_VDE;
5989      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5990         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5991         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5992      tempax >>= 1;
5993      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5994      temp = (tempax >> 8) << 3;
5995      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5996 
5997      tempeax = SiS_Pr->SiS_HDE;
5998      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5999         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6000         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6001      tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
6002      temp = tempeax & 0x7f;
6003      tempeax >>= 7;
6004      if(temp) tempeax++;
6005      temp = tempeax & 0x3f;
6006      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6007      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
6008      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6009      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6010      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6011 
6012      tempax = SiS_Pr->SiS_HDE;
6013      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6014         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6015         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6016      tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
6017      pushcx = tempax;
6018      temp = tempax & 0x00FF;
6019      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6020      temp = ((tempax & 0xFF00) >> 8) << 3;
6021      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6022 
6023      tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6024      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6025         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6026         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6027      tempeax = tempax * pushcx;
6028      temp = tempeax & 0xFF;
6029      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6030      temp = (tempeax & 0xFF00) >> 8;
6031      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6032      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6033      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6034      temp = ((tempeax & 0x01000000) >> 24) << 7;
6035      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6036 
6037      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6038      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6039      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6040      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6041      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6042 
6043      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6044         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6045         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6046         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6047         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6048         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6049         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6050         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6051         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6052         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6053         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6054         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6055         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6056         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6057         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6058         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6059         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6060         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6061         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6062         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6063         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6064      }
6065   }
6066 #endif  /* SIS315H */
6067 }
6068 
6069 /* Set Part 1 */
6070 static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6071 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6072 		unsigned short RefreshRateTableIndex)
6073 {
6074 #if defined(SIS300) || defined(SIS315H)
6075   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6076 #endif
6077   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6078   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0, lvds550=0;
6079 #ifdef SIS315H
6080   unsigned short  tempbl=0;
6081 #endif
6082 
6083   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6084      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6085      return;
6086   }
6087 
6088   if(ModeNo <= 0x13) {
6089      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6090   } else if(SiS_Pr->UseCustomMode) {
6091      modeflag = SiS_Pr->CModeFlag;
6092   } else {
6093      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6094      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6095      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6096   }
6097 
6098   if(SiS_Pr->ChipType == SIS_550 &&
6099      SiS_Pr->SiS_IF_DEF_LVDS     &&
6100      !SiS_Pr->SiS_IF_DEF_DSTN    &&
6101      !SiS_Pr->SiS_IF_DEF_FSTN) {
6102      lvds550 = 1;
6103   }
6104 
6105   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6106 
6107   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6108          (!lvds550)                     &&
6109          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6110          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6111 
6112      if(SiS_Pr->ChipType < SIS_315H ) {
6113 #ifdef SIS300
6114 	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6115 #endif
6116      } else {
6117 #ifdef SIS315H
6118 	SiS_SetCRT2FIFO_310(SiS_Pr);
6119 #endif
6120      }
6121 
6122      /* 1. Horizontal setup */
6123 
6124      if(SiS_Pr->ChipType < SIS_315H) {
6125 
6126 #ifdef SIS300   /* ------------- 300 series --------------*/
6127 
6128 	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
6129 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6130 
6131 	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6132 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6133 
6134 	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6135 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6136 
6137 	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6138 	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6139 	tempbx = pushbx + tempcx;
6140 	tempcx <<= 1;
6141 	tempcx += tempbx;
6142 
6143 	bridgeadd = 12;
6144 
6145 #endif /* SIS300 */
6146 
6147      } else {
6148 
6149 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
6150 
6151 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
6152 	if(modeflag & HalfDCLK) {
6153 	   if((SiS_Pr->SiS_VBType & VB_SISVB) || lvds550) {
6154 	      tempcx >>= 1;
6155 	   } else {
6156 	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
6157 	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6158 	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6159 	         tempcx = SiS_Pr->SiS_HT - tempax;
6160 	      }
6161 	   }
6162 	}
6163 	tempcx--;
6164 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6165 	temp = (tempcx >> 4) & 0xF0;
6166 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6167 
6168 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
6169 	tempbx = SiS_Pr->SiS_VGAHDE;
6170 	tempcx -= tempbx;
6171 	tempcx >>= 2;
6172 	if(modeflag & HalfDCLK) {
6173 	   tempbx >>= 1;
6174 	   tempcx >>= 1;
6175 	}
6176 	tempbx += 16;
6177 
6178 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6179 
6180 	pushbx = tempbx;
6181 	if(!lvds550) tempcx >>= 1;
6182 	tempbx += tempcx;
6183 	tempcx += tempbx;
6184 	if(lvds550) tempcx += 20;
6185 
6186 	bridgeadd = 16;
6187 
6188 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6189 	   if(SiS_Pr->ChipType >= SIS_661) {
6190 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6191 		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6192 		 if(resinfo == SIS_RI_1280x1024) {
6193 		    tempcx = (tempcx & 0xff00) | 0x30;
6194 		 } else if(resinfo == SIS_RI_1600x1200) {
6195 		    tempcx = (tempcx & 0xff00) | 0xff;
6196 		 }
6197 	      }
6198 	   }
6199         }
6200 
6201 #endif  /* SIS315H */
6202 
6203      }  /* 315/330 series */
6204 
6205      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6206 
6207 	if(SiS_Pr->UseCustomMode) {
6208 	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6209 	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6210 	   tempax = SiS_Pr->SiS_VGAHT;
6211 	   if(modeflag & HalfDCLK) tempax >>= 1;
6212 	   tempax--;
6213 	   if(tempcx > tempax) tempcx = tempax;
6214 	}
6215 
6216 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6217 	   unsigned char cr4, cr14, cr5, cr15;
6218 	   if(SiS_Pr->UseCustomMode) {
6219 	      cr4  = SiS_Pr->CCRT1CRTC[4];
6220 	      cr14 = SiS_Pr->CCRT1CRTC[14];
6221 	      cr5  = SiS_Pr->CCRT1CRTC[5];
6222 	      cr15 = SiS_Pr->CCRT1CRTC[15];
6223 	   } else {
6224 	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6225 	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6226 	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6227 	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6228 	   }
6229 	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6230 	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6231 	   tempcx &= 0x00FF;
6232 	   tempcx |= (tempbx & 0xFF00);
6233 	   tempbx += bridgeadd;
6234 	   tempcx += bridgeadd;
6235 	   tempax = SiS_Pr->SiS_VGAHT;
6236 	   if(modeflag & HalfDCLK) tempax >>= 1;
6237 	   tempax--;
6238 	   if(tempcx > tempax) tempcx = tempax;
6239 	}
6240 
6241 	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6242 	   tempbx = 1040;
6243 	   tempcx = 1044;   /* HWCursor bug! */
6244 	}
6245 
6246      }
6247 
6248      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6249 
6250      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6251 
6252      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6253      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6254 
6255      /* 2. Vertical setup */
6256 
6257      tempcx = SiS_Pr->SiS_VGAVT - 1;
6258      temp = tempcx & 0x00FF;
6259      if((SiS_Pr->ChipType < SIS_661) && !lvds550)  {
6260         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6261 	   if(SiS_Pr->ChipType < SIS_315H) {
6262 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6263 	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6264 	            temp--;
6265 	         }
6266 	      }
6267 	   } else {
6268 	      temp--;
6269 	   }
6270 	} else if(SiS_Pr->ChipType >= SIS_315H) {
6271 	   temp--;
6272 	}
6273      }
6274      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6275 
6276      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6277      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6278 
6279      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6280      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6281 
6282      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661) && !lvds550) {
6283 	tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
6284 	tempbx = SiS_Pr->SiS_VGAVDE + tempcx;
6285 	if(tempcx < 4) tempcx = 4;
6286 	tempcx = (tempcx >> 2) + tempbx + 1;
6287      } else {
6288 	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6289 	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6290      }
6291 
6292      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6293 	if(SiS_Pr->UseCustomMode) {
6294 	   tempbx = SiS_Pr->CVSyncStart;
6295 	   tempcx = SiS_Pr->CVSyncEnd;
6296 	}
6297 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6298 	   unsigned char cr8, cr7, cr13;
6299 	   if(SiS_Pr->UseCustomMode) {
6300 	      cr8    = SiS_Pr->CCRT1CRTC[8];
6301 	      cr7    = SiS_Pr->CCRT1CRTC[7];
6302 	      cr13   = SiS_Pr->CCRT1CRTC[13];
6303 	      tempcx = SiS_Pr->CCRT1CRTC[9];
6304 	   } else {
6305 	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6306 	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6307 	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6308 	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6309 	   }
6310 	   tempbx = cr8;
6311 	   if(cr7  & 0x04) tempbx |= 0x0100;
6312 	   if(cr7  & 0x80) tempbx |= 0x0200;
6313 	   if(cr13 & 0x08) tempbx |= 0x0400;
6314 	}
6315      }
6316      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6317 
6318      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6319      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6320 
6321      /* 3. Panel delay compensation */
6322 
6323      if(SiS_Pr->ChipType < SIS_315H) {
6324 
6325 #ifdef SIS300  /* ---------- 300 series -------------- */
6326 
6327 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6328 	   temp = 0x20;
6329 	   if(SiS_Pr->ChipType == SIS_300) {
6330 	      temp = 0x10;
6331 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6332 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6333 	   }
6334 	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6335 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6336 	   }
6337 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6338 	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6339 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6340 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6341 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6342 	      else 					    temp = 0x20;
6343 	   }
6344 	   if(SiS_Pr->SiS_UseROM) {
6345 	      if(ROMAddr[0x220] & 0x80) {
6346 		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6347 		    temp = ROMAddr[0x221];
6348 		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6349 		    temp = ROMAddr[0x222];
6350 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6351 		    temp = ROMAddr[0x223];
6352 		 else
6353 		    temp = ROMAddr[0x224];
6354 	      }
6355 	   }
6356 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6357 	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6358 	   }
6359 
6360 	} else {
6361 	   temp = 0x20;
6362 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6363 	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6364 	   }
6365 	   if(SiS_Pr->SiS_UseROM) {
6366 	      if(ROMAddr[0x220] & 0x80) {
6367 	         temp = ROMAddr[0x220];
6368 	      }
6369 	   }
6370 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6371 	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6372 	   }
6373 	}
6374 
6375 	temp &= 0x3c;
6376 
6377 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6378 
6379 #endif  /* SIS300 */
6380 
6381      } else {
6382 
6383 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
6384 
6385 	if(SiS_Pr->ChipType < SIS_661) {
6386 
6387 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6388 
6389 	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6390 	      else 		              temp = 0x00;
6391 
6392 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6393 	      tempbl = 0xF0;
6394 	      if(SiS_Pr->ChipType == SIS_650) {
6395 		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6396 		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6397 		 }
6398 	      }
6399 
6400 	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN || lvds550) {
6401 		 temp = 0x08;
6402 		 tempbl = 0;
6403 		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6404 		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6405 		 }
6406 	      }
6407 
6408 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6409 	   }
6410 
6411 	} /* < 661 */
6412 
6413 	tempax = 0;
6414 	if(modeflag & DoubleScanMode) tempax |= 0x80;
6415 	if(modeflag & HalfDCLK)       tempax |= 0x40;
6416 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6417 
6418 #endif  /* SIS315H */
6419 
6420      }
6421 
6422   }  /* Slavemode */
6423 
6424   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6425      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6426 	/* For 301BDH with LCD, we set up the Panel Link */
6427 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6428      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6429 	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6430      }
6431   } else {
6432      if(SiS_Pr->ChipType < SIS_315H) {
6433 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6434      } else {
6435 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6436 	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6437 	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6438 	   }
6439 	} else {
6440 	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6441 	}
6442      }
6443   }
6444 }
6445 
6446 /*********************************************/
6447 /*         SET PART 2 REGISTER GROUP         */
6448 /*********************************************/
6449 
6450 #ifdef SIS315H
6451 static BOOLEAN
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6452 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6453 		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6454 		    unsigned short *ResIndex)
6455 {
6456 
6457   if(SiS_Pr->ChipType < SIS_315H) return FALSE;
6458 
6459   if(ModeNo <= 0x13)
6460      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6461   else
6462      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6463 
6464   (*ResIndex) &= 0x3f;
6465   (*CRT2Index) = 0;
6466 
6467   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6468      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6469         (*CRT2Index) = 200;
6470      }
6471   }
6472 
6473   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6474      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6475         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6476      }
6477   }
6478   return (((*CRT2Index) != 0));
6479 }
6480 #endif
6481 
6482 #ifdef SIS300
6483 static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6484 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6485 {
6486    unsigned short tempcx;
6487    static const unsigned char atable[] = {
6488        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6489        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6490    };
6491 
6492    if(!SiS_Pr->UseCustomMode) {
6493       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6494 	      (SiS_Pr->ChipType == SIS_730) ) &&
6495 	    (SiS_Pr->ChipRevision > 2) )  &&
6496 	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6497 	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6498 	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6499 	 if(ModeNo == 0x13) {
6500 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6501 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6502 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6503 	 } else if((crt2crtc & 0x3F) == 4) {
6504 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6505 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6506 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6507 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6508 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6509 	 }
6510       }
6511 
6512       if(SiS_Pr->ChipType < SIS_315H) {
6513 	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6514 	    crt2crtc &= 0x1f;
6515 	    tempcx = 0;
6516 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6517 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6518 		  tempcx += 7;
6519 	       }
6520 	    }
6521 	    tempcx += crt2crtc;
6522 	    if(crt2crtc >= 4) {
6523 	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6524 	    }
6525 
6526 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6527 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6528 		  if(crt2crtc == 4) {
6529 		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6530 		  }
6531 	       }
6532 	    }
6533 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6534 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6535 	 }
6536       }
6537    }
6538 }
6539 
6540 /* For ECS A907. Highly preliminary. */
6541 static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6542 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6543 		    unsigned short ModeNo)
6544 {
6545   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6546   unsigned short crt2crtc, resindex;
6547   int i, j;
6548 
6549   if(SiS_Pr->ChipType != SIS_300) return;
6550   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6551   if(SiS_Pr->UseCustomMode) return;
6552 
6553   if(ModeNo <= 0x13) {
6554      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6555   } else {
6556      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6557   }
6558 
6559   resindex = crt2crtc & 0x3F;
6560   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6561   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6562 
6563   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6564   if(ModeNo > 0x13) {
6565      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6566      resindex = 4;
6567   }
6568 
6569   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6570   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6571   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6572      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6573   }
6574   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6575      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6576   }
6577   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6578      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6579   }
6580   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6581   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6582 }
6583 #endif
6584 
6585 static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6586 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6587 {
6588   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6589   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
6590   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p)) return;
6591 
6592   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6593      if(SiS_Pr->SiS_TVMode & TVSetHiVi960540) {
6594         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6595 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x47);
6596         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0xea);
6597         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x00);
6598         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0e);
6599         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x00);
6600         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0xe6);
6601 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x90);
6602 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x09);
6603 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x03);
6604      }
6605   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
6606 #ifndef OLD1280720P
6607      if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
6608         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
6609 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x23);
6610         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x1c);
6611         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x10);
6612         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0b);
6613         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x10);
6614         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x2c);
6615 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x68);
6616 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x01);
6617 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x05);
6618      }
6619 #endif
6620   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
6621      if(SiS_Pr->SiS_TVMode & TVSet525p1024) {
6622         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x77);
6623         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,0x13);
6624         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2b,0x78);
6625         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2c,0x04);
6626         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x42,0x14);
6627         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x73);
6628         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,0xaf);
6629         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1e,0x71);
6630         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,0xbb);
6631         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,0xb5);
6632         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x26,0xdc);
6633         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,0x3c);
6634         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x45,0x11);
6635         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x00);
6636      }
6637   } else if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6638      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6639         static const unsigned char specialtv[] = {
6640 		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6641 		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6642 		0x58,0xe4,0x73,0xda,0x13
6643 	};
6644 	int i, j;
6645 	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6646 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6647 	}
6648 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6649 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6650 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6651 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6652 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6653 	   } else {
6654 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6655 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6656 	   }
6657 	}
6658      }
6659   } else {
6660      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6661         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6662         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6663         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6664      } else {
6665         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6666         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6667      }
6668   }
6669 }
6670 
6671 static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6672 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6673 {
6674   unsigned short temp;
6675 
6676   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6677      if(SiS_Pr->SiS_VGAVDE == 525) {
6678 	temp = 0xc3;
6679 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6680 	   temp++;
6681 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6682 	}
6683 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6684 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6685      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6686 	temp = 0x4d;
6687 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6688 	   temp++;
6689 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6690 	}
6691 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6692      }
6693   }
6694 
6695   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6696      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6697 	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6698 	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6699 	   /* Not always for LV, see SetGrp2 */
6700 	}
6701 	temp = 1;
6702 	if(ModeNo <= 0x13) temp = 3;
6703 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6704      }
6705   }
6706 }
6707 
6708 static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6709 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6710 		unsigned short RefreshRateTableIndex)
6711 {
6712   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6713   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6714   unsigned int   longtemp, PhaseIndex;
6715   BOOLEAN        newtvphase;
6716   const unsigned char *TimingPoint;
6717 #ifdef SIS315H
6718   unsigned short resindex, CRT2Index;
6719   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6720 
6721   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6722 #endif
6723 
6724   if(ModeNo <= 0x13) {
6725      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6726      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6727   } else if(SiS_Pr->UseCustomMode) {
6728      modeflag = SiS_Pr->CModeFlag;
6729      crt2crtc = 0;
6730   } else {
6731      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6732      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6733   }
6734 
6735   temp = 0;
6736   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6737   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6738   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6739   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6740 
6741   if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming))  temp |= 0x10;
6742 
6743   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6744 
6745   PhaseIndex  = 0x01; /* SiS_PALPhase */
6746   TimingPoint = SiS_Pr->SiS_PALTiming;
6747 
6748   newtvphase = FALSE;
6749   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6750       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6751 	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6752      newtvphase = TRUE;
6753   }
6754 
6755   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6756 
6757      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6758      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6759         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6760         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6761 	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6762         }
6763      }
6764 
6765   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6766 
6767      i = 0;
6768      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6769      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6770      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i) i = 3;
6771      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p) i = 4;
6772 
6773      TimingPoint = &SiS_YPbPrTable[i][0];
6774 
6775      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6776 
6777   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6778 
6779      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6780 
6781   } else {
6782 
6783      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6784      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
6785      if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
6786 
6787   }
6788 
6789   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6790      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
6791      if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
6792   }
6793 
6794   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6795      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6796         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6797      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6798         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6799      } else {
6800         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6801      }
6802   }
6803 
6804   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6805      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6806   }
6807 
6808   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6809      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6810   }
6811   for(i = 0x39; i <= 0x45; i++, j++) {
6812      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6813   }
6814 
6815   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6816      if(SiS_Pr->SiS_ModeType != ModeText) {
6817         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6818      }
6819   }
6820 
6821   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6822 
6823   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6824   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6825   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6826   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6827 
6828   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
6829   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempax = 680;
6830   else if(SiS_Pr->SiS_TVMode & TVSetPALTiming)	tempax = 520;
6831   else						tempax = 440; /* NTSC, YPbPr 525 */
6832 
6833   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_VDE <= tempax)) {
6834 
6835      tempax -= SiS_Pr->SiS_VDE;
6836      tempax >>= 1;
6837      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) {
6838         tempax >>= 1;
6839      }
6840      tempax &= 0x00ff;
6841 
6842      temp = tempax + (unsigned short)TimingPoint[0];
6843      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6844 
6845      temp = tempax + (unsigned short)TimingPoint[1];
6846      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6847   }
6848 
6849   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6850      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6851         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6852         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6853      } else {
6854         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6855         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6856      }
6857   }
6858 
6859   tempcx = SiS_Pr->SiS_HT;
6860   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6861   tempcx--;
6862   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6863   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6864   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6865 
6866   tempcx = SiS_Pr->SiS_HT >> 1;
6867   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6868   tempcx += 7;
6869   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6870   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6871 
6872   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6873   tempbx += tempcx;
6874   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6875   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6876 
6877   tempbx += 8;
6878   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6879      tempbx -= 4;
6880      tempcx = tempbx;
6881   }
6882   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6883 
6884   j += 2;
6885   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6886   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6887   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6888 
6889   tempcx += 8;
6890   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6891   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6892 
6893   tempcx = SiS_Pr->SiS_HT >> 1;
6894   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6895   j += 2;
6896   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6897   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6898 
6899   tempcx -= 11;
6900   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6901      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6902   }
6903   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6904 
6905   tempbx = SiS_Pr->SiS_VDE;
6906   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6907      if(SiS_Pr->SiS_VGAVDE == 360)      tempbx = 746;
6908      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6909      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6910   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6911              (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) {
6912      tempbx >>= 1;
6913      if(SiS_Pr->ChipType >= SIS_315H) {
6914         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6915 	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6916 	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6917 	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6918 	      if(crt2crtc == 4) tempbx++;
6919 	   }
6920 	}
6921      }
6922      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6923         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6924 	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6925 	}
6926 	if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming)) {
6927 	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6928         }
6929      }
6930   }
6931   tempbx -= 2;
6932   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6933 
6934   temp = (tempcx >> 8) & 0x0F;
6935   temp |= ((tempbx >> 2) & 0xC0);
6936   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6937      temp |= 0x10;
6938      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6939   }
6940   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6941 
6942   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6943      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6944   }
6945 
6946   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6947      tempbx = SiS_Pr->SiS_VDE;
6948      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6949          (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) {
6950         tempbx >>= 1;
6951      }
6952      tempbx -= 3;
6953      temp = ((tempbx >> 3) & 0x60) | 0x18;
6954      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6955      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6956 
6957      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6958 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6959      }
6960   }
6961 
6962   tempax = tempbx = tempcx = 0;
6963   if(!(modeflag & HalfDCLK)) {
6964      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6965         tempbx |= 0x20;
6966      }
6967   }
6968 
6969   tempch = tempcl = 1;
6970   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6971      if(SiS_Pr->SiS_VGAHDE >= 960) {
6972         if(!(modeflag & HalfDCLK)) {
6973 	   tempcl = 32;
6974 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
6975               tempch = 20;
6976               tempbx &= ~0x20;
6977            } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6978               tempch = 25;
6979            } else {
6980 	      tempch = 25; /* OK */
6981 	   }
6982         }
6983      }
6984   }
6985 
6986   if(!(tempbx & 0x20)) {
6987      if(modeflag & HalfDCLK) tempcl <<= 1;
6988      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6989      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6990      tempax = longtemp / SiS_Pr->SiS_HDE;
6991      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6992      tempbx |= ((tempax >> 8) & 0x1F);
6993      tempcx = tempax >> 13;
6994   }
6995 
6996   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6997   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6998 
6999   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7000 
7001      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,(tempcx & 0x07));
7002 
7003      if(SiS_Pr->SiS_TVMode & TVSetPALTiming) {
7004         tempbx = 0x0382;
7005         tempcx = 0x007e;
7006      } else {
7007         tempbx = 0x0369;
7008         tempcx = 0x0061;
7009      }
7010      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7011      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7012      temp = (tempcx & 0x0300) >> 6;
7013      temp |= ((tempbx >> 8) & 0x03);
7014      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7015         temp |= 0x10;
7016 	if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp |= 0x20;
7017 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)		 temp |= 0x40;
7018      }
7019      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7020 
7021      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7022      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7023 
7024      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7025 
7026      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7027         temp = 0;
7028         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7029         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7030      }
7031 
7032   }
7033 
7034   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7035      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7036         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7037         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7038      }
7039      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7040   }
7041 
7042   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7043      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7044         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7045      }
7046   }
7047 
7048   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7049 
7050   /* From here: Part2 LCD setup */
7051 
7052   tempbx = SiS_Pr->SiS_HDE;
7053   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7054   tempbx--;			         	/* RHACTE = HDE - 1 */
7055   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7056   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7057 
7058   temp = 0x01;
7059   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7060      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7061         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7062            temp = 0x02;
7063            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7064               temp = 0x01;
7065 	   }
7066         }
7067      }
7068   }
7069   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7070 
7071   tempbx = SiS_Pr->SiS_VDE - 1;
7072   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7073   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7074 
7075   tempcx = SiS_Pr->SiS_VT - 1;
7076   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7077   temp = (tempcx >> 3) & 0xE0;
7078   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7079      /* Enable dithering; only do this for 32bpp mode */
7080      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7081         temp |= 0x10;
7082      }
7083   }
7084   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7085 
7086   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7087   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7088 
7089   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7090   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7091 
7092 #ifdef SIS315H
7093   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7094                           			&CRT2Index, &resindex)) {
7095       switch(CRT2Index) {
7096         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7097 	default:
7098         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7099       }
7100 
7101       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7102       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7103       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7104         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7105       }
7106       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7107         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7108       }
7109       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7110         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7111       }
7112       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7113       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7114 
7115       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7116 
7117   } else {
7118 #endif
7119 
7120     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7121     /*             Clevo dual-link 1024x768 */
7122     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7123     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7124 
7125     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7126        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7127           tempbx = SiS_Pr->SiS_VDE - 1;
7128           tempcx = SiS_Pr->SiS_VT - 1;
7129        } else {
7130           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7131 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7132        }
7133     } else {
7134        tempbx = SiS_Pr->PanelYRes;
7135        tempcx = SiS_Pr->SiS_VT;
7136        tempax = 1;
7137        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7138           tempax = SiS_Pr->PanelYRes;
7139 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7140           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7141              tempax = tempcx = 0;
7142           } else {
7143              tempax -= SiS_Pr->SiS_VDE;
7144           }
7145           tempax >>= 1;
7146        }
7147        tempcx -= tempax; /* lcdvdes */
7148        tempbx -= tempax; /* lcdvdee */
7149     }
7150 
7151     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7152 
7153 #ifdef SIS_XORG_XF86
7154 #ifdef TWDEBUG
7155     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7156 #endif
7157 #endif
7158 
7159     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7160     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7161 
7162     temp = (tempbx >> 5) & 0x38;
7163     temp |= ((tempcx >> 8) & 0x07);
7164     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7165 
7166     tempax = SiS_Pr->SiS_VDE;
7167     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7168        tempax = SiS_Pr->PanelYRes;
7169     }
7170     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7171     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7172        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7173 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7174        }
7175     }
7176 
7177     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7178     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7179        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7180           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7181              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7182 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7183 	     else           { tempax >>= 2;           }
7184              tempbx -= (tempax - 1);
7185 	  } else {
7186 	     tempbx -= 10;
7187 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7188 	  }
7189        }
7190     }
7191     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7192        tempbx++;
7193        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7194           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7195 	     tempbx = 770;
7196 	     tempcx = 3;
7197 	  }
7198        }
7199     }
7200 
7201     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7202 
7203     if(SiS_Pr->UseCustomMode) {
7204        tempbx = SiS_Pr->CVSyncStart;
7205     }
7206 
7207 #ifdef SIS_XORG_XF86
7208 #ifdef TWDEBUG
7209     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7210 #endif
7211 #endif
7212 
7213     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7214 
7215     temp = (tempbx >> 4) & 0xF0;
7216     tempbx += (tempcx + 1);
7217     temp |= (tempbx & 0x0F);
7218 
7219     if(SiS_Pr->UseCustomMode) {
7220        temp &= 0xf0;
7221        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7222     }
7223 
7224 #ifdef SIS_XORG_XF86
7225 #ifdef TWDEBUG
7226     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7227 #endif
7228 #endif
7229 
7230     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7231 
7232 #ifdef SIS300
7233     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7234 #endif
7235 
7236     bridgeoffset = 7;
7237     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7238     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7239     if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7240     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7241     /* Higher bridgeoffset shifts to the LEFT */
7242 
7243     temp = 0;
7244     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7245        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7246 	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7247 	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7248        }
7249     }
7250     temp += bridgeoffset;
7251     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7252     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7253 
7254     tempcx = SiS_Pr->SiS_HT;
7255     tempax = tempbx = SiS_Pr->SiS_HDE;
7256     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7257        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7258           tempax = SiS_Pr->PanelXRes;
7259           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7260        }
7261     }
7262     if(SiS_IsDualLink(SiS_Pr)) {
7263        tempcx >>= 1;
7264        tempbx >>= 1;
7265        tempax >>= 1;
7266     }
7267 
7268 #ifdef SIS_XORG_XF86
7269 #ifdef TWDEBUG
7270     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7271 #endif
7272 #endif
7273 
7274     tempbx += bridgeoffset;
7275 
7276     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7277     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7278 
7279     tempcx = (tempcx - tempax) >> 2;
7280 
7281     tempbx += tempcx;
7282     push2 = tempbx;
7283 
7284     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7285        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7286           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7287              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7288 	  }
7289        }
7290     }
7291 
7292     if(SiS_Pr->UseCustomMode) {
7293        tempbx = SiS_Pr->CHSyncStart;
7294        if(modeflag & HalfDCLK) tempbx <<= 1;
7295        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7296        tempbx += bridgeoffset;
7297     }
7298 
7299 #ifdef SIS_XORG_XF86
7300 #ifdef TWDEBUG
7301     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7302 #endif
7303 #endif
7304 
7305     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7306     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7307 
7308     tempbx = push2;
7309 
7310     tempcx <<= 1;
7311     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7312        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7313     }
7314     tempbx += tempcx;
7315 
7316     if(SiS_Pr->UseCustomMode) {
7317        tempbx = SiS_Pr->CHSyncEnd;
7318        if(modeflag & HalfDCLK) tempbx <<= 1;
7319        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7320        tempbx += bridgeoffset;
7321     }
7322 
7323 #ifdef SIS_XORG_XF86
7324 #ifdef TWDEBUG
7325     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7326 #endif
7327 #endif
7328 
7329     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7330 
7331     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7332 
7333 #ifdef SIS300
7334     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7335 #endif
7336 #ifdef SIS315H
7337   } /* CRT2-LCD from table */
7338 #endif
7339 }
7340 
7341 /*********************************************/
7342 /*         SET PART 3 REGISTER GROUP         */
7343 /*********************************************/
7344 
7345 static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7346 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7347 {
7348   unsigned short i;
7349   const unsigned char *tempdi;
7350 
7351   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7352 
7353 #ifndef SIS_CP
7354   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7355 #else
7356   SIS_CP_INIT301_CP
7357 #endif
7358 
7359   if(SiS_Pr->SiS_TVMode & TVSetPALTiming) {
7360      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7361      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7362   } else {
7363      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7364      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7365   }
7366 
7367   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7368      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7369      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7370      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7371   }
7372 
7373   tempdi = NULL;
7374   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7375      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7376      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7377         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7378      }
7379   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7380      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr625i))) {
7381         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)
7382 	   tempdi = SiS_HiTVGroup3_2;
7383         else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)
7384 	   tempdi = SiS_HiTVGroup3_1;
7385      }
7386   }
7387   if(tempdi) {
7388      for(i=0; i<=0x3E; i++) {
7389         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7390      }
7391      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7392 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7393 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7394 	}
7395      }
7396   }
7397 
7398 #ifdef SIS_CP
7399   SIS_CP_INIT301_CP2
7400 #endif
7401 }
7402 
7403 /*********************************************/
7404 /*         SET PART 4 REGISTER GROUP         */
7405 /*********************************************/
7406 
7407 #ifdef SIS315H
7408 #if 0
7409 static void
7410 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7411 {
7412    unsigned short temp, temp1, temp2;
7413 
7414    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7415    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7416    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7417    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7418    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7419    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7420    temp = (unsigned short)((int)(temp) + shift);
7421    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7422    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7423    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7424    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7425    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7426    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7427 }
7428 #endif
7429 
7430 static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7431 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7432 {
7433    unsigned short temp, temp1;
7434    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7435 
7436    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7437    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7438 
7439    if(SiS_Pr->ChipType >= XGI_20) return;
7440 
7441    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7442       if(!(ROMAddr[0x61] & 0x04)) return;
7443    }
7444 
7445    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7446    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7447    if(!(temp & 0x01)) {
7448       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7449       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7450       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7451          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7452       }
7453       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7454       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)			    temp = 0x0000;
7455       else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp = 0x0002;
7456       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)		    temp = 0x0400;
7457       else							    temp = 0x0402;
7458       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7459          temp1 = 0;
7460 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7461 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7462 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7463 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7464 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7465 	 if(ModeNo > 0x13) {
7466             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7467          }
7468       } else {
7469          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7470 	 if(temp1 == 0x01) temp |= 0x01;
7471 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7472 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7473 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7474 	 if(ModeNo > 0x13) {
7475             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7476          }
7477       }
7478 
7479 #if 0
7480       if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7481          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7482             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7483 	       if(resinfo == SIS_RI_1024x768) {
7484 	          SiS_ShiftXPos(SiS_Pr, 97);
7485 	       } else {
7486 	          SiS_ShiftXPos(SiS_Pr, 111);
7487 	       }
7488 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7489 	       SiS_ShiftXPos(SiS_Pr, 136);
7490 	    }
7491          }
7492       }
7493 #endif
7494 
7495    }
7496 
7497 }
7498 #endif
7499 
7500 static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7501 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7502                  unsigned short RefreshRateTableIndex)
7503 {
7504   unsigned short vclkindex, temp, reg1, reg2;
7505 
7506   if(SiS_Pr->UseCustomMode) {
7507      reg1 = SiS_Pr->CSR2B;
7508      reg2 = SiS_Pr->CSR2C;
7509   } else {
7510      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7511      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7512      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7513   }
7514 
7515   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7516      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7517         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7518  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7519 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7520      } else {
7521         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7522         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7523      }
7524   } else {
7525      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7526      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7527      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7528   }
7529   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7530   temp = 0x08;
7531   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7532   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7533 }
7534 
7535 static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7536 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7537 {
7538   if(SiS_Pr->ChipType >= SIS_315H) {
7539      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7540 	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7541 	   (SiS_IsVAMode(SiS_Pr))) {
7542 	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7543 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7544 	   } else {
7545 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7546 	   }
7547 	}
7548      }
7549   }
7550   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7551      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7552 #ifdef SET_EMI
7553      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7554 #endif
7555      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7556   }
7557 }
7558 
7559 static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7560 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7561 		unsigned short RefreshRateTableIndex)
7562 {
7563   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7564   unsigned int   tempebx, tempeax, templong;
7565 
7566   if(ModeNo <= 0x13) {
7567      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7568      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7569   } else if(SiS_Pr->UseCustomMode) {
7570      modeflag = SiS_Pr->CModeFlag;
7571      resinfo = 0;
7572   } else {
7573      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7574      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7575   }
7576 
7577   if(SiS_Pr->ChipType >= SIS_315H) {
7578      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7579 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7580 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7581 	}
7582      }
7583   }
7584 
7585   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7586      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7587 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7588      }
7589   }
7590 
7591   if(SiS_Pr->ChipType >= SIS_315H) {
7592      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7593 	SiS_SetDualLinkEtc(SiS_Pr);
7594 	return;
7595      }
7596   }
7597 
7598   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7599 
7600   tempbx = SiS_Pr->SiS_RVBHCMAX;
7601   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7602 
7603   temp = (tempbx >> 1) & 0x80;
7604 
7605   tempcx = SiS_Pr->SiS_VGAHT - 1;
7606   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7607 
7608   temp |= ((tempcx >> 5) & 0x78);
7609 
7610   tempcx = SiS_Pr->SiS_VGAVT - 1;
7611   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7612   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7613 
7614   temp |= ((tempcx >> 8) & 0x07);
7615   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7616 
7617   tempbx = SiS_Pr->SiS_VGAHDE;
7618   if(modeflag & HalfDCLK)    tempbx >>= 1;
7619   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7620 
7621   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7622      temp = 0;
7623      if(tempbx > 800)        temp = 0x60;
7624   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7625      temp = 0;
7626      if(tempbx > 1024)       temp = 0xC0;
7627      else if(tempbx >= 960)  temp = 0xA0;
7628   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) {
7629      temp = 0;
7630      if(tempbx >= 1280)      temp = 0x40;
7631      else if(tempbx >= 1024) temp = 0x20;
7632   } else {
7633      temp = 0x80;
7634      if(tempbx >= 1024)      temp = 0xA0;
7635   }
7636 
7637   temp |= SiS_Pr->Init_P4_0E;
7638 
7639   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7640      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7641         temp &= 0xf0;
7642         temp |= 0x0A;
7643      }
7644   }
7645 
7646   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7647 
7648   tempeax = SiS_Pr->SiS_VGAVDE;
7649   tempebx = SiS_Pr->SiS_VDE;
7650   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7651      if(!(temp & 0xE0)) tempebx >>= 1;
7652   }
7653 
7654   tempcx = SiS_Pr->SiS_RVBHRS;
7655   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7656   tempcx >>= 8;
7657   tempcx |= 0x40;
7658 
7659   if(tempeax <= tempebx) {
7660      tempcx ^= 0x40;
7661   } else {
7662      tempeax -= tempebx;
7663   }
7664 
7665   tempeax *= (256 * 1024);
7666   templong = tempeax % tempebx;
7667   tempeax /= tempebx;
7668   if(templong) tempeax++;
7669 
7670   temp = (unsigned short)(tempeax & 0x000000FF);
7671   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7672   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7673   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7674   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7675   temp |= (tempcx & 0x4F);
7676   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7677 
7678   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7679 
7680      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7681 
7682      /* Calc Linebuffer max address and set/clear decimode */
7683      tempbx = 0;
7684      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7685      tempax = SiS_Pr->SiS_VGAHDE;
7686      if(modeflag & HalfDCLK)    tempax >>= 1;
7687      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7688      if(tempax > 800) {
7689         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7690 	   tempax -= 800;
7691 	} else {
7692 	   tempbx = 0x08;
7693 	   if(tempax == 960)	   tempax *= 25; /* Correct */
7694            else if(tempax == 1024) tempax *= 25;
7695            else			   tempax *= 20;
7696 	   temp = tempax % 32;
7697 	   tempax /= 32;
7698 	   if(temp) tempax++;
7699 	   tempax++;
7700 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7701 	      if(resinfo == SIS_RI_1024x768 ||
7702 	         resinfo == SIS_RI_1024x576 ||
7703 		 resinfo == SIS_RI_1280x1024 ||
7704 		 resinfo == SIS_RI_1280x720) {
7705 	         /* Otherwise white line or garbage at right edge */
7706 	         tempax = (tempax & 0xff00) | 0x20;
7707 	      } else if(resinfo == SIS_RI_960x540) {
7708 	         tempax = (tempax & 0xff00) | 0xed;
7709 	      }
7710 	   }
7711 	}
7712      }
7713      tempax--;
7714      temp = ((tempax >> 4) & 0x30) | tempbx;
7715      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7716      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7717 
7718      temp = 0x0036; tempbx = 0xD0;
7719      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7720 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7721      }
7722      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7723         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 |
7724 				   TVSetHiVision |
7725 				   TVSetYPbPrProg))) {
7726 	   temp |= 0x01;
7727 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7728 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7729   	         temp &= ~0x01;
7730 	      }
7731 	   }
7732 	}
7733      }
7734      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7735 
7736      tempbx = SiS_Pr->SiS_HT >> 1;
7737      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7738      tempbx -= 2;
7739      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7740      temp = (tempbx >> 5) & 0x38;
7741      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7742 
7743      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7744 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7745            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7746 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7747 	}
7748      }
7749 
7750      SiS_SetDualLinkEtc(SiS_Pr);
7751 
7752   }  /* 301B */
7753 
7754   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7755 }
7756 
7757 /*********************************************/
7758 /*         SET PART 5 REGISTER GROUP         */
7759 /*********************************************/
7760 
7761 static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7762 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7763 {
7764 
7765   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7766 
7767   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7768      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7769         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7770         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7771      }
7772   }
7773 }
7774 
7775 /*********************************************/
7776 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7777 /*********************************************/
7778 
7779 static BOOLEAN
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7780 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7781 		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7782 		   unsigned short *DisplayType)
7783  {
7784   unsigned short modeflag = 0;
7785   BOOLEAN checkhd = TRUE;
7786 
7787   /* Pass 1:1 not supported here */
7788 
7789   if(ModeNo <= 0x13) {
7790      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7791      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7792   } else {
7793      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7794      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7795   }
7796 
7797   (*ResIndex) &= 0x3F;
7798 
7799   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7800 
7801      (*DisplayType) = 80;
7802      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7803       	(*DisplayType) = 82;
7804 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7805 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7806 	}
7807      }
7808      if((*DisplayType) != 84) {
7809         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7810      }
7811 
7812   } else {
7813 
7814      (*DisplayType = 0);
7815      switch(SiS_Pr->SiS_LCDResInfo) {
7816      case Panel_320x240_1: (*DisplayType) = 50;
7817 			   checkhd = FALSE;
7818 			   break;
7819      case Panel_320x240_2: (*DisplayType) = 14;
7820 			   break;
7821      case Panel_320x240_3: (*DisplayType) = 18;
7822 			   break;
7823      case Panel_640x480:   (*DisplayType) = 10;
7824 			   break;
7825      case Panel_1024x600:  (*DisplayType) = 26;
7826 			   break;
7827      default: return TRUE;
7828      }
7829 
7830      if(checkhd) {
7831         if(modeflag & HalfDCLK) (*DisplayType)++;
7832      }
7833 
7834      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7835         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7836      }
7837 
7838   }
7839 
7840   return TRUE;
7841 }
7842 
7843 static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7844 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7845                 unsigned short RefreshRateTableIndex)
7846 {
7847   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7848   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr = NULL;
7849   static const unsigned short CRIdx[] = {
7850 	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7851 	0x07, 0x10, 0x11, 0x15, 0x16
7852   };
7853 
7854   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7855      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7856      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
7857      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7858      return;
7859 
7860   if(SiS_Pr->SiS_IF_DEF_LVDS) {
7861      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7862         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7863      }
7864   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7865      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7866   } else return;
7867 
7868   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7869 
7870   if(SiS_Pr->ChipType < SIS_315H) {
7871      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7872   }
7873 
7874   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7875                           &ResIndex, &DisplayType))) {
7876      return;
7877   }
7878 
7879   switch(DisplayType) {
7880     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
7881     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
7882     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
7883     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
7884     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
7885     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
7886     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
7887 #if 0 /* Works better with calculated numbers */
7888     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7889     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7890     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7891     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7892 #endif
7893     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7894     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7895     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7896     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7897     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
7898   }
7899 
7900   if(LVDSCRT1Ptr) {
7901 
7902      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7903 
7904      for(i = 0; i <= 10; i++) {
7905         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7906         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7907      }
7908 
7909      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7910         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7911         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7912      }
7913 
7914      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7915      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7916 
7917      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7918      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7919 
7920      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7921      if(modeflag & DoubleScanMode) tempah |= 0x80;
7922      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7923 
7924   } else {
7925 
7926      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7927 
7928   }
7929 }
7930 
7931 /*********************************************/
7932 /*              SET CRT2 ECLK                */
7933 /*********************************************/
7934 
7935 static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7936 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7937            unsigned short RefreshRateTableIndex)
7938 {
7939   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7940   unsigned short clkbase, vclkindex = 0;
7941   unsigned char  sr2b, sr2c;
7942 
7943   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7944      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7945      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7946 	RefreshRateTableIndex--;
7947      }
7948      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7949                                     RefreshRateTableIndex);
7950      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7951   } else {
7952      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7953                                     RefreshRateTableIndex);
7954   }
7955 
7956   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7957   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7958 
7959   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7960      if(SiS_Pr->SiS_UseROM) {
7961 	if(ROMAddr[0x220] & 0x01) {
7962 	   sr2b = ROMAddr[0x227];
7963 	   sr2c = ROMAddr[0x228];
7964 	}
7965      }
7966   }
7967 
7968   clkbase = 0x02B;
7969   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7970      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7971 	clkbase += 3;
7972      }
7973   }
7974 
7975   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7976   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7977   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7978   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7979   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7980   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7981   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7982   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7983   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7984 }
7985 
7986 /*********************************************/
7987 /*           SET UP CHRONTEL CHIPS           */
7988 /*********************************************/
7989 
7990 static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7991 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7992                unsigned short RefreshRateTableIndex)
7993 {
7994    unsigned short TVType, resindex;
7995    const struct SiS_CHTVRegData *CHTVRegData = NULL;
7996 
7997    if(ModeNo <= 0x13)
7998       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7999    else
8000       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8001 
8002    resindex &= 0x3F;
8003 
8004    TVType = 0;
8005    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8006    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8007       TVType += 2;
8008       if(SiS_Pr->SiS_ModeType > ModeVGA) {
8009 	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8010       }
8011       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8012 	 TVType = 4;
8013 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8014       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8015 	 TVType = 6;
8016 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8017       }
8018    }
8019 
8020    switch(TVType) {
8021       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8022       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8023       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8024       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8025       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8026       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8027       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8028       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8029       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8030       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8031    }
8032 
8033 
8034    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8035 
8036 #ifdef SIS300
8037 
8038       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8039 
8040       /* We don't support modes >800x600 */
8041       if (resindex > 5) return;
8042 
8043       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8044 	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8045 	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
8046       } else {
8047 	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8048 	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
8049       }
8050 
8051       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
8052       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
8053       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
8054       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
8055       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
8056 
8057       /* Set minimum flicker filter for Luma channel (SR1-0=00),
8058                 minimum text enhancement (S3-2=10),
8059    	        maximum flicker filter for Chroma channel (S5-4=10)
8060 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8061        */
8062       SiS_SetCH700x(SiS_Pr,0x01,0x28);
8063 
8064       /* Set video bandwidth
8065             High bandwith Luma composite video filter(S0=1)
8066             low bandwith Luma S-video filter (S2-1=00)
8067 	    disable peak filter in S-video channel (S3=0)
8068 	    high bandwidth Chroma Filter (S5-4=11)
8069 	    =00110001=0x31
8070       */
8071       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
8072 
8073       /* Register 0x3D does not exist in non-macrovision register map
8074             (Maybe this is a macrovision register?)
8075        */
8076 #ifndef SIS_CP
8077       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8078 #endif
8079 
8080       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8081              all other bits a read-only. Macrovision?
8082        */
8083       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8084 
8085       /* Register 0x11 only contains 3 writable bits (S0-S2) for
8086              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8087        */
8088       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8089 
8090       /* Clear DSEN
8091        */
8092       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8093 
8094       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
8095          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8096             if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
8097       	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8098                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
8099             } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
8100                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
8101                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8102                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8103                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8104                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8105                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8106                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8107                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8108                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
8109                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
8110             }
8111          } else {
8112             if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
8113                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8114                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8115             } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
8116 #if 0
8117                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8118                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
8119                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
8120                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8121                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8122                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8123                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8124                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8125                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
8126                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
8127 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8128 	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
8129                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8130             }
8131          }
8132       } else {						/* ---- PAL ---- */
8133          /* We don't play around with FSCI in PAL mode */
8134          if(resindex == 0x04) {
8135             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8136             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
8137          } else {
8138             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8139             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
8140          }
8141       }
8142 
8143 #endif  /* 300 */
8144 
8145    } else {
8146 
8147       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8148 
8149 #ifdef SIS315H
8150 
8151       unsigned short temp;
8152 
8153       /* We don't support modes >1024x768 */
8154       if (resindex > 6) return;
8155 
8156       temp = CHTVRegData[resindex].Reg[0];
8157       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8158       SiS_SetCH701x(SiS_Pr,0x00,temp);
8159 
8160       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8161       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8162       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8163       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8164       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8165       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8166 
8167       temp = CHTVRegData[resindex].Reg[7];
8168       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8169       SiS_SetCH701x(SiS_Pr,0x07,temp);
8170 
8171       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8172       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8173       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8174       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8175       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8176       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8177       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8178       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8179 
8180       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8181       /* D1 should be set for PAL, PAL-N and NTSC-J,
8182          but I won't do that for PAL unless somebody
8183 	 tells me to do so. Since the BIOS uses
8184 	 non-default CIV values and blacklevels,
8185 	 this might be compensated anyway.
8186        */
8187       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8188       SiS_SetCH701x(SiS_Pr,0x21,temp);
8189 
8190 #endif	/* 315 */
8191 
8192    }
8193 
8194 #ifdef SIS_CP
8195    SIS_CP_INIT301_CP3
8196 #endif
8197 
8198 }
8199 
8200 #ifdef SIS315H  /* ----------- 315 series only ---------- */
8201 
8202 void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8203 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8204 {
8205    unsigned short temp;
8206 
8207    /* Enable Chrontel 7019 LCD panel backlight */
8208    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8209       if(SiS_Pr->ChipType == SIS_740) {
8210 	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8211       } else {
8212 	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8213 	 temp |= 0x20;
8214 	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8215       }
8216    }
8217 }
8218 
8219 void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8220 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8221 {
8222    unsigned short temp;
8223 
8224    /* Disable Chrontel 7019 LCD panel backlight */
8225    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8226       temp = SiS_GetCH701x(SiS_Pr,0x66);
8227       temp &= 0xDF;
8228       SiS_SetCH701x(SiS_Pr,0x66,temp);
8229    }
8230 }
8231 
8232 static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8233 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8234 {
8235   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8236   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8237   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8238   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8239   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8240   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8241   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8242   const unsigned char *tableptr = NULL;
8243   int i;
8244 
8245   /* Set up Power up/down timing */
8246 
8247   if(SiS_Pr->ChipType == SIS_740) {
8248      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8249 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8250 	else    			          tableptr = table1024_740;
8251      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8252 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8253 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8254 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8255         else					  tableptr = table1400_740;
8256      } else return;
8257   } else {
8258      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8259 	tableptr = table1024_650;
8260      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8261 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8262 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8263 	tableptr = table1400_650;
8264      } else return;
8265   }
8266 
8267   for(i=0; i<5; i++) {
8268      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8269   }
8270 }
8271 
8272 static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8273 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8274 {
8275   const unsigned char *tableptr = NULL;
8276   unsigned short tempbh;
8277   int i;
8278   static const unsigned char regtable[] = {
8279 		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8280 		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8281   };
8282   static const unsigned char table1024_740[] = {
8283 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8284 		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8285   };
8286   static const unsigned char table1280_740[] = {
8287 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8288 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8289   };
8290   static const unsigned char table1400_740[] = {
8291 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8292 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8293   };
8294   static const unsigned char table1600_740[] = {
8295 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8296 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8297   };
8298   static const unsigned char table1024_650[] = {
8299 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8300 		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8301   };
8302   static const unsigned char table1280_650[] = {
8303 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8304 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8305   };
8306   static const unsigned char table1400_650[] = {
8307 		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8308 		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8309   };
8310   static const unsigned char table1600_650[] = {
8311 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8312 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8313   };
8314 
8315   if(SiS_Pr->ChipType == SIS_740) {
8316      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8317      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8318      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8319      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8320      else return;
8321   } else {
8322      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8323      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8324      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8325      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8326      else return;
8327   }
8328 
8329   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8330   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8331      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8332      if(tempbh == 0xc8) {
8333         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8334      } else if(tempbh == 0xdb) {
8335         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8336 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8337      } else if(tempbh == 0xde) {
8338         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8339      }
8340   }
8341 
8342   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8343   else     			  tempbh = 0x0c;
8344 
8345   for(i = 0; i < tempbh; i++) {
8346      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8347   }
8348   SiS_ChrontelPowerSequencing(SiS_Pr);
8349   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8350   tempbh |= 0xc0;
8351   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8352 
8353   if(SiS_Pr->ChipType == SIS_740) {
8354      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8355      tempbh &= 0xfb;
8356      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8357      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8358      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8359      tempbh |= 0x40;
8360      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8361      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8362      tempbh &= 0x3f;
8363      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8364   }
8365 }
8366 
8367 static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8368 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8369 {
8370   unsigned char temp, temp1;
8371 
8372   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8373   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8374   temp = SiS_GetCH701x(SiS_Pr,0x47);
8375   temp &= 0x7f;	/* Use external VSYNC */
8376   SiS_SetCH701x(SiS_Pr,0x47,temp);
8377   SiS_LongDelay(SiS_Pr, 3);
8378   temp = SiS_GetCH701x(SiS_Pr,0x47);
8379   temp |= 0x80;	/* Use internal VSYNC */
8380   SiS_SetCH701x(SiS_Pr,0x47,temp);
8381   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8382 }
8383 
8384 static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8385 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8386 {
8387   unsigned short temp;
8388 
8389   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8390      if(SiS_Pr->ChipType == SIS_740) {
8391         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8392         temp |= 0x04;	/* Invert XCLK phase */
8393         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8394      }
8395      if(SiS_IsYPbPr(SiS_Pr)) {
8396         temp = SiS_GetCH701x(SiS_Pr,0x01);
8397 	temp &= 0x3f;
8398 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8399 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8400      }
8401      if(SiS_IsChScart(SiS_Pr)) {
8402         temp = SiS_GetCH701x(SiS_Pr,0x01);
8403 	temp &= 0x3f;
8404 	temp |= 0xc0;	/* Enable SCART + CVBS */
8405 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8406      }
8407      if(SiS_Pr->ChipType == SIS_740) {
8408         SiS_ChrontelResetVSync(SiS_Pr);
8409         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8410      } else {
8411         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8412         temp = SiS_GetCH701x(SiS_Pr,0x49);
8413         if(SiS_IsYPbPr(SiS_Pr)) {
8414            temp = SiS_GetCH701x(SiS_Pr,0x73);
8415 	   temp |= 0x60;
8416 	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8417         }
8418         temp = SiS_GetCH701x(SiS_Pr,0x47);
8419         temp &= 0x7f;
8420         SiS_SetCH701x(SiS_Pr,0x47,temp);
8421         SiS_LongDelay(SiS_Pr, 2);
8422         temp = SiS_GetCH701x(SiS_Pr,0x47);
8423         temp |= 0x80;
8424         SiS_SetCH701x(SiS_Pr,0x47,temp);
8425      }
8426   }
8427 }
8428 
8429 static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8430 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8431 {
8432   unsigned short temp;
8433 
8434   /* Complete power down of LVDS */
8435   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8436      if(SiS_Pr->ChipType == SIS_740) {
8437         SiS_LongDelay(SiS_Pr, 1);
8438 	SiS_GenericDelay(SiS_Pr, 5887);
8439 	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8440 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8441      } else {
8442         SiS_LongDelay(SiS_Pr, 2);
8443 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8444 	temp &= 0xfc;
8445 	SiS_SetCH701x(SiS_Pr,0x76,temp);
8446 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8447      }
8448   }
8449 }
8450 
8451 static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8452 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8453 {
8454      unsigned short temp;
8455 
8456      if(SiS_Pr->ChipType == SIS_740) {
8457 
8458         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8459         temp &= 0x01;
8460         if(!temp) {
8461 
8462            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8463 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8464 	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8465 	   }
8466 
8467 	   /* Reset Chrontel 7019 datapath */
8468            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8469            SiS_LongDelay(SiS_Pr, 1);
8470            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8471 
8472 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8473 	      SiS_ChrontelResetVSync(SiS_Pr);
8474 	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8475 	   }
8476 
8477         } else {
8478 
8479 	   /* Clear/set/clear GPIO */
8480            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8481 	   temp &= 0xef;
8482 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8483 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8484 	   temp |= 0x10;
8485 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8486 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8487 	   temp &= 0xef;
8488 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8489 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8490 	   if(!temp) {
8491 	      SiS_SetCH701xForLCD(SiS_Pr);
8492 	   }
8493         }
8494 
8495      } else { /* 650 */
8496         /* Reset Chrontel 7019 datapath */
8497         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8498         SiS_LongDelay(SiS_Pr, 1);
8499         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8500      }
8501 }
8502 
8503 static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8504 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8505 {
8506      unsigned short temp;
8507 
8508      if(SiS_Pr->ChipType == SIS_740) {
8509 
8510         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8511            SiS_ChrontelResetVSync(SiS_Pr);
8512         }
8513 
8514      } else {
8515 
8516         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8517         temp = SiS_GetCH701x(SiS_Pr,0x49);
8518         temp &= 1;
8519         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8520 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8521 	   temp &= 0x70;
8522 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8523 	   SiS_LongDelay(SiS_Pr, 3);
8524 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8525 	   temp |= 0x80;
8526 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8527         }
8528 
8529      }
8530 }
8531 
8532 static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8533 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8534 {
8535      unsigned short temp,temp1;
8536 
8537      if(SiS_Pr->ChipType == SIS_740) {
8538 
8539         temp = SiS_GetCH701x(SiS_Pr,0x61);
8540         if(temp < 1) {
8541            temp++;
8542 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8543         }
8544         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8545         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8546         SiS_LongDelay(SiS_Pr, 1);
8547         SiS_GenericDelay(SiS_Pr, 5887);
8548 
8549      } else {  /* 650 */
8550 
8551         temp1 = 0;
8552         temp = SiS_GetCH701x(SiS_Pr,0x61);
8553         if(temp < 2) {
8554            temp++;
8555 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8556 	   temp1 = 1;
8557         }
8558         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8559         temp = SiS_GetCH701x(SiS_Pr,0x66);
8560         temp |= 0x5f;
8561         SiS_SetCH701x(SiS_Pr,0x66,temp);
8562         if(ModeNo > 0x13) {
8563            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8564 	      SiS_GenericDelay(SiS_Pr, 1023);
8565 	   } else {
8566 	      SiS_GenericDelay(SiS_Pr, 767);
8567 	   }
8568         } else {
8569            if(!temp1)
8570 	      SiS_GenericDelay(SiS_Pr, 767);
8571         }
8572         temp = SiS_GetCH701x(SiS_Pr,0x76);
8573         temp |= 0x03;
8574         SiS_SetCH701x(SiS_Pr,0x76,temp);
8575         temp = SiS_GetCH701x(SiS_Pr,0x66);
8576         temp &= 0x7f;
8577         SiS_SetCH701x(SiS_Pr,0x66,temp);
8578         SiS_LongDelay(SiS_Pr, 1);
8579 
8580      }
8581 }
8582 
8583 static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8584 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8585 {
8586      unsigned short temp,tempcl,tempch;
8587 
8588      SiS_LongDelay(SiS_Pr, 1);
8589      tempcl = 3;
8590      tempch = 0;
8591 
8592      do {
8593        temp = SiS_GetCH701x(SiS_Pr,0x66);
8594        temp &= 0x04;  /* PLL stable? -> bail out */
8595        if(temp == 0x04) break;
8596 
8597        if(SiS_Pr->ChipType == SIS_740) {
8598           /* Power down LVDS output, PLL normal operation */
8599           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8600        }
8601 
8602        SiS_SetCH701xForLCD(SiS_Pr);
8603 
8604        if(tempcl == 0) {
8605            if(tempch == 3) break;
8606 	   SiS_ChrontelResetDB(SiS_Pr);
8607 	   tempcl = 3;
8608 	   tempch++;
8609        }
8610        tempcl--;
8611        temp = SiS_GetCH701x(SiS_Pr,0x76);
8612        temp &= 0xfb;  /* Reset PLL */
8613        SiS_SetCH701x(SiS_Pr,0x76,temp);
8614        SiS_LongDelay(SiS_Pr, 2);
8615        temp = SiS_GetCH701x(SiS_Pr,0x76);
8616        temp |= 0x04;  /* PLL normal operation */
8617        SiS_SetCH701x(SiS_Pr,0x76,temp);
8618        if(SiS_Pr->ChipType == SIS_740) {
8619           SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8620        } else {
8621           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8622        }
8623        SiS_LongDelay(SiS_Pr, 2);
8624     } while(0);
8625 
8626     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8627 }
8628 
8629 static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8630 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8631 {
8632      unsigned short temp;
8633 
8634      temp = SiS_GetCH701x(SiS_Pr,0x03);
8635      temp |= 0x80;	/* Set datapath 1 to TV   */
8636      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8637      SiS_SetCH701x(SiS_Pr,0x03,temp);
8638 
8639      if(SiS_Pr->ChipType == SIS_740) {
8640 
8641         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8642         temp &= 0xfb;	/* Normal XCLK phase */
8643         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8644 
8645         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8646 
8647         temp = SiS_GetCH701x(SiS_Pr,0x64);
8648         temp |= 0x40;	/* ? Bit not defined */
8649         SiS_SetCH701x(SiS_Pr,0x64,temp);
8650 
8651         temp = SiS_GetCH701x(SiS_Pr,0x03);
8652         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8653         SiS_SetCH701x(SiS_Pr,0x03,temp);
8654 
8655 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8656 	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8657 	   SiS_LongDelay(SiS_Pr, 1);
8658 	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8659 	   SiS_ChrontelResetDB(SiS_Pr);
8660 	   SiS_ChrontelDoSomething2(SiS_Pr);
8661 	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8662 	} else {
8663            temp = SiS_GetCH701x(SiS_Pr,0x66);
8664            if(temp != 0x45) {
8665               SiS_ChrontelResetDB(SiS_Pr);
8666               SiS_ChrontelDoSomething2(SiS_Pr);
8667               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8668            }
8669 	}
8670 
8671      } else { /* 650 */
8672 
8673         SiS_ChrontelResetDB(SiS_Pr);
8674         SiS_ChrontelDoSomething2(SiS_Pr);
8675         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8676         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8677         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8678 
8679      }
8680 
8681 }
8682 #endif  /* 315 series  */
8683 
8684 /*********************************************/
8685 /*      MAIN: SET CRT2 REGISTER GROUP        */
8686 /*********************************************/
8687 
8688 BOOLEAN
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8689 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8690 {
8691 #ifdef SIS300
8692    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8693 #endif
8694    unsigned short ModeIdIndex, RefreshRateTableIndex;
8695 
8696    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8697 
8698    if(!SiS_Pr->UseCustomMode) {
8699       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8700    } else {
8701       ModeIdIndex = 0;
8702    }
8703 
8704    /* Used for shifting CR33 */
8705    SiS_Pr->SiS_SelectCRT2Rate = 4;
8706 
8707    SiS_UnLockCRT2(SiS_Pr);
8708 
8709    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8710 
8711    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8712 
8713    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8714       SiS_DisableBridge(SiS_Pr);
8715       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8716          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8717       }
8718       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8719    }
8720 
8721    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8722       SiS_LockCRT2(SiS_Pr);
8723       SiS_DisplayOn(SiS_Pr);
8724       return TRUE;
8725    }
8726 
8727    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8728 
8729    /* Set up Panel Link for LVDS and LCDA */
8730    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8731    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8732        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8733        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8734       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8735    }
8736 
8737 #ifdef SIS_XORG_XF86
8738 #ifdef TWDEBUG
8739   xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8740   xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8741   xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8742   xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8743   xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8744 #endif
8745 #endif
8746 
8747    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8748       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8749    }
8750 
8751    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8752 
8753       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8754 
8755 	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8756 #ifdef SIS315H
8757 	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8758 #endif
8759 	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8760 	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8761 #ifdef SIS315H
8762 	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8763 #endif
8764 	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8765 
8766 	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8767 
8768 	 /* For 301BDH (Panel link initialization): */
8769 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8770 
8771 	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8772 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8773 		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8774 	       }
8775             }
8776 	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8777 	 }
8778       }
8779 
8780    } else {
8781 
8782       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8783 
8784       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8785 
8786       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8787 
8788       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8789 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8790 	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8791 	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8792 #ifdef SIS315H
8793 		  SiS_SetCH701xForLCD(SiS_Pr);
8794 #endif
8795 	       }
8796 	    }
8797 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8798 	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8799 	    }
8800 	 }
8801       }
8802 
8803    }
8804 
8805 #ifdef SIS300
8806    if(SiS_Pr->ChipType < SIS_315H) {
8807       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8808 	 if(SiS_Pr->SiS_UseOEM) {
8809 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8810 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8811 		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8812 	       }
8813 	    } else {
8814 	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8815 	    }
8816 	 }
8817 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8818 	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8819 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8820 	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8821 	    }
8822 	    SiS_DisplayOn(SiS_Pr);
8823          }
8824       }
8825    }
8826 #endif
8827 
8828 #ifdef SIS315H
8829    if(SiS_Pr->ChipType >= SIS_315H) {
8830       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8831 	 if(SiS_Pr->ChipType < SIS_661) {
8832 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8833 	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8834 	 } else {
8835 	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8836 	 }
8837 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8838       }
8839    }
8840 #endif
8841 
8842    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8843       SiS_EnableBridge(SiS_Pr);
8844    }
8845 
8846    SiS_DisplayOn(SiS_Pr);
8847 
8848    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8849       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8850 	 /* Disable LCD panel when using TV */
8851 	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8852       } else {
8853 	 /* Disable TV when using LCD */
8854 	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8855       }
8856    }
8857 
8858    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8859       SiS_LockCRT2(SiS_Pr);
8860    }
8861 
8862    return TRUE;
8863 }
8864 
8865 
8866 /*********************************************/
8867 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8868 /*********************************************/
8869 
8870 void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)8871 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8872 {
8873   /* Switch on LCD backlight on SiS30xLV */
8874   SiS_DDC2Delay(SiS_Pr,0xff00);
8875   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8876      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8877      SiS_WaitVBRetrace(SiS_Pr);
8878   }
8879   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8880      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8881   }
8882 }
8883 
8884 void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)8885 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8886 {
8887   /* Switch off LCD backlight on SiS30xLV */
8888   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8889   SiS_DDC2Delay(SiS_Pr,0xff00);
8890 }
8891 
8892 /*********************************************/
8893 /*          DDC RELATED FUNCTIONS            */
8894 /*********************************************/
8895 
8896 static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)8897 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8898 {
8899   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8900   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
8901   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8902      SiS_Pr->SiS_DDC_NData &= 0x0f;
8903      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
8904   }
8905 }
8906 
8907 #ifdef SIS300
8908 static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8909 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8910 {
8911   int i, j, num;
8912   unsigned short tempah,temp;
8913   unsigned char *mydataptr;
8914 
8915   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8916      mydataptr = dataptr;
8917      num = *mydataptr++;
8918      if(!num) return mydataptr;
8919      if(i) {
8920         SiS_SetStop(SiS_Pr);
8921 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8922      }
8923      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
8924      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8925      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
8926      if(temp) continue;				/*    (ERROR: no ack) */
8927      tempah = *mydataptr++;
8928      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
8929      if(temp) continue;				/*    (ERROR: no ack) */
8930      for(j=0; j<num; j++) {
8931         tempah = *mydataptr++;
8932         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8933 	if(temp) break;
8934      }
8935      if(temp) continue;
8936      if(SiS_SetStop(SiS_Pr)) continue;
8937      return mydataptr;
8938   }
8939   return NULL;
8940 }
8941 
8942 static BOOLEAN
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8943 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8944 {
8945   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
8946   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8947   SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
8948   SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
8949   SiS_SetupDDCN(SiS_Pr);
8950 
8951   SiS_SetSwitchDDC2(SiS_Pr);
8952 
8953   while(*dataptr) {
8954      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8955      if(!dataptr) return FALSE;
8956   }
8957 #ifdef SIS_XORG_XF86
8958 #ifdef TWDEBUG
8959   xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8960 #endif
8961 #endif
8962   return TRUE;
8963 }
8964 #endif
8965 
8966 /* The Chrontel 700x is connected to the 630/730 via
8967  * the 630/730's DDC/I2C port.
8968  *
8969  * On 630(S)T chipset, the index changed from 0x11 to
8970  * 0x0a, possibly for working around the DDC problems
8971  */
8972 
8973 static BOOLEAN
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)8974 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8975 {
8976   unsigned short temp, i;
8977 
8978   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8979      if(i) {
8980 	SiS_SetStop(SiS_Pr);
8981 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8982      }
8983      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
8984      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
8985      if(temp) continue;							/*    (ERROR: no ack) */
8986      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
8987      if(temp) continue;							/*    (ERROR: no ack) */
8988      temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
8989      if(temp) continue;							/*    (ERROR: no ack) */
8990      if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
8991      SiS_Pr->SiS_ChrontelInit = 1;
8992      return TRUE;
8993   }
8994   return FALSE;
8995 }
8996 
8997 /* Write to Chrontel 700x */
8998 void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)8999 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9000 {
9001   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9002 
9003   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9004 
9005   if(!(SiS_Pr->SiS_ChrontelInit)) {
9006      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9007      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9008      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9009      SiS_SetupDDCN(SiS_Pr);
9010   }
9011 
9012   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9013       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9014      SiS_Pr->SiS_DDC_Index = 0x0a;
9015      SiS_Pr->SiS_DDC_Data  = 0x80;
9016      SiS_Pr->SiS_DDC_Clk   = 0x40;
9017      SiS_SetupDDCN(SiS_Pr);
9018 
9019      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9020   }
9021 }
9022 
9023 /* Write to Chrontel 701x */
9024 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9025 void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9026 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9027 {
9028   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9029   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9030   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9031   SiS_SetupDDCN(SiS_Pr);
9032   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
9033   SiS_SetChReg(SiS_Pr, reg, val, 0);
9034 }
9035 
9036 #ifdef SIS_LINUX_KERNEL
9037 static
9038 #endif
9039 void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9040 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9041 {
9042   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9043      SiS_SetCH700x(SiS_Pr, reg, val);
9044   else
9045      SiS_SetCH701x(SiS_Pr, reg, val);
9046 }
9047 
9048 static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)9049 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9050 {
9051   unsigned short tempah, temp, i;
9052 
9053   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
9054      if(i) {
9055 	SiS_SetStop(SiS_Pr);
9056 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9057      }
9058      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9059      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9060      if(temp) continue;							/*        (ERROR: no ack) */
9061      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
9062      if(temp) continue;							/*        (ERROR: no ack) */
9063      if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
9064      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9065      if(temp) continue;							/*        (ERROR: no ack) */
9066      tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
9067      if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
9068      SiS_Pr->SiS_ChrontelInit = 1;
9069      return tempah;
9070   }
9071   return 0xFFFF;
9072 }
9073 
9074 /* Read from Chrontel 700x */
9075 /* Parameter is [Register no (S7-S0)] */
9076 unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9077 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9078 {
9079   unsigned short result;
9080 
9081   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9082 
9083   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9084 
9085   if(!(SiS_Pr->SiS_ChrontelInit)) {
9086      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9087      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9088      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9089      SiS_SetupDDCN(SiS_Pr);
9090   }
9091 
9092   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9093 
9094   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9095       (!SiS_Pr->SiS_ChrontelInit) ) {
9096 
9097      SiS_Pr->SiS_DDC_Index = 0x0a;
9098      SiS_Pr->SiS_DDC_Data  = 0x80;
9099      SiS_Pr->SiS_DDC_Clk   = 0x40;
9100      SiS_SetupDDCN(SiS_Pr);
9101 
9102      result = SiS_GetChReg(SiS_Pr,0x80);
9103   }
9104   return result;
9105 }
9106 
9107 /* Read from Chrontel 701x */
9108 /* Parameter is [Register no (S7-S0)] */
9109 unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9110 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9111 {
9112   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9113   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9114   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9115   SiS_SetupDDCN(SiS_Pr);
9116   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9117 
9118   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9119 
9120   return SiS_GetChReg(SiS_Pr,0);
9121 }
9122 
9123 /* Read from Chrontel 70xx */
9124 /* Parameter is [Register no (S7-S0)] */
9125 #ifdef SIS_LINUX_KERNEL
9126 static
9127 #endif
9128 unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)9129 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9130 {
9131   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9132      return SiS_GetCH700x(SiS_Pr, tempbx);
9133   else
9134      return SiS_GetCH701x(SiS_Pr, tempbx);
9135 }
9136 
9137 void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)9138 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9139 		unsigned char myor, unsigned short myand)
9140 {
9141   unsigned short tempbl;
9142 
9143   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9144   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9145 }
9146 
9147 /* Our own DDC functions */
9148 #ifndef SIS_XORG_XF86
9149 static
9150 #endif
9151 unsigned short
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,BOOLEAN checkcr32,unsigned int VBFlags2)9152 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9153                 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
9154 		unsigned int VBFlags2)
9155 {
9156      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9157      unsigned char flag, cr32;
9158      unsigned short        temp = 0, myadaptnum = adaptnum;
9159 
9160      if(adaptnum != 0) {
9161 	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9162 	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9163      }
9164 
9165      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9166 
9167      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9168 
9169      SiS_Pr->SiS_DDC_SecAddr = 0;
9170      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9171      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9172      SiS_Pr->SiS_DDC_Index = 0x11;
9173      flag = 0xff;
9174 
9175      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9176 
9177 #if 0
9178      if(VBFlags2 & VB2_SISBRIDGE) {
9179 	if(myadaptnum == 0) {
9180 	   if(!(cr32 & 0x20)) {
9181 	      myadaptnum = 2;
9182 	      if(!(cr32 & 0x10)) {
9183 	         myadaptnum = 1;
9184 		 if(!(cr32 & 0x08)) {
9185 		    myadaptnum = 0;
9186 		 }
9187 	      }
9188 	   }
9189         }
9190      }
9191 #endif
9192 
9193      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9194 
9195         if(myadaptnum != 0) {
9196 	   flag = 0;
9197 	   if(VBFlags2 & VB2_SISBRIDGE) {
9198 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9199               SiS_Pr->SiS_DDC_Index = 0x0f;
9200 	   }
9201         }
9202 
9203 	if(!(VBFlags2 & VB2_301)) {
9204 	   if((cr32 & 0x80) && (checkcr32)) {
9205               if(myadaptnum >= 1) {
9206 	         if(!(cr32 & 0x08)) {
9207 		     myadaptnum = 1;
9208 		     if(!(cr32 & 0x10)) return 0xFFFF;
9209                  }
9210 	      }
9211 	   }
9212 	}
9213 
9214 	temp = 4 - (myadaptnum * 2);
9215 	if(flag) temp = 0;
9216 
9217      } else {						/* 315/330 series */
9218 
9219 	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9220 
9221 	if(VBFlags2 & VB2_SISBRIDGE) {
9222 	   if(myadaptnum == 2) {
9223 	      myadaptnum = 1;
9224 	   }
9225 	}
9226 
9227         if(myadaptnum == 1) {
9228 	   flag = 0;
9229 	   if(VBFlags2 & VB2_SISBRIDGE) {
9230 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9231               SiS_Pr->SiS_DDC_Index = 0x0f;
9232 	   }
9233         }
9234 
9235         if((cr32 & 0x80) && (checkcr32)) {
9236            if(myadaptnum >= 1) {
9237 	      if(!(cr32 & 0x08)) {
9238 	         myadaptnum = 1;
9239 		 if(!(cr32 & 0x10)) return 0xFFFF;
9240 	      }
9241 	   }
9242         }
9243 
9244         temp = myadaptnum;
9245         if(myadaptnum == 1) {
9246            temp = 0;
9247 	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9248         }
9249 
9250 	if(flag) temp = 0;
9251     }
9252 
9253     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9254     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9255 
9256     SiS_SetupDDCN(SiS_Pr);
9257 
9258 #ifdef SIS_XORG_XF86
9259 #ifdef TWDEBUG
9260     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9261     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9262 #endif
9263 #endif
9264     return 0;
9265 }
9266 
9267 static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9268 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9269 {
9270    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9271    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9272       return 0xFFFF;
9273    }
9274    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9275       return 0xFFFF;
9276    }
9277    return 0;
9278 }
9279 
9280 static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9281 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9282 {
9283    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9284    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9285       return 0xFFFF;
9286    }
9287    return 0;
9288 }
9289 
9290 static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9291 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9292 {
9293    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9294    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9295    return 0;
9296 }
9297 
9298 static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9299 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9300 {
9301    SiS_SetSCLKLow(SiS_Pr);
9302    if(yesno) {
9303       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9304 		      SiS_Pr->SiS_DDC_Index,
9305 		      SiS_Pr->SiS_DDC_NData,
9306 		      SiS_Pr->SiS_DDC_Data);
9307    } else {
9308       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9309 		      SiS_Pr->SiS_DDC_Index,
9310 		      SiS_Pr->SiS_DDC_NData,
9311 		      0);
9312    }
9313    SiS_SetSCLKHigh(SiS_Pr);
9314 }
9315 
9316 static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9317 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9318 {
9319     unsigned char mask, value;
9320     unsigned short  temp, ret=0;
9321     BOOLEAN failed = FALSE;
9322 
9323     SiS_SetSwitchDDC2(SiS_Pr);
9324     if(SiS_PrepareDDC(SiS_Pr)) {
9325          SiS_SetStop(SiS_Pr);
9326 #ifdef SIS_XORG_XF86
9327 #ifdef TWDEBUG
9328          xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9329 #endif
9330 #endif
9331          return 0xFFFF;
9332     }
9333     mask = 0xf0;
9334     value = 0x20;
9335     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9336        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9337        SiS_SendACK(SiS_Pr, 0);
9338        if(temp == 0) {
9339            mask = 0xff;
9340 	   value = 0xff;
9341        } else {
9342            failed = TRUE;
9343 	   ret = 0xFFFF;
9344 #ifdef SIS_XORG_XF86
9345 #ifdef TWDEBUG
9346            xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9347 #endif
9348 #endif
9349        }
9350     }
9351     if(failed == FALSE) {
9352        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9353        SiS_SendACK(SiS_Pr, 1);
9354        temp &= mask;
9355        if(temp == value) ret = 0;
9356        else {
9357           ret = 0xFFFF;
9358 #ifdef SIS_XORG_XF86
9359 #ifdef TWDEBUG
9360           xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9361 #endif
9362 #endif
9363           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9364              if(temp == 0x30) ret = 0;
9365           }
9366        }
9367     }
9368     SiS_SetStop(SiS_Pr);
9369     return ret;
9370 }
9371 
9372 #ifndef SIS_XORG_XF86
9373 static
9374 #endif
9375 unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9376 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9377 {
9378    unsigned short flag;
9379 
9380    flag = 0x180;
9381    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9382    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9383    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9384    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9385    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9386    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9387    if(!(flag & 0x1a)) flag = 0;
9388    return flag;
9389 }
9390 
9391 #ifndef SIS_XORG_XF86
9392 static
9393 #endif
9394 unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9395 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9396 {
9397    unsigned short flag, length, i;
9398    unsigned char chksum,gotcha;
9399 
9400    if(DDCdatatype > 4) return 0xFFFF;
9401 
9402    flag = 0;
9403    SiS_SetSwitchDDC2(SiS_Pr);
9404    if(!(SiS_PrepareDDC(SiS_Pr))) {
9405       length = 127;
9406       if(DDCdatatype != 1) length = 255;
9407       chksum = 0;
9408       gotcha = 0;
9409       for(i=0; i<length; i++) {
9410 	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9411 	 chksum += buffer[i];
9412 	 gotcha |= buffer[i];
9413 	 SiS_SendACK(SiS_Pr, 0);
9414       }
9415       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9416       chksum += buffer[i];
9417       SiS_SendACK(SiS_Pr, 1);
9418       if(gotcha) flag = (unsigned short)chksum;
9419       else flag = 0xFFFF;
9420    } else {
9421       flag = 0xFFFF;
9422    }
9423    SiS_SetStop(SiS_Pr);
9424    return flag;
9425 }
9426 
9427 /* Our private DDC functions
9428 
9429    It complies somewhat with the corresponding VESA function
9430    in arguments and return values.
9431 
9432    Since this is probably called before the mode is changed,
9433    we use our pre-detected pSiS-values instead of SiS_Pr as
9434    regards chipset and video bridge type.
9435 
9436    Arguments:
9437        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9438                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9439 		 LCDA is CRT1, but DDC is read from CRT2 port.
9440        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9441        buffer: ptr to 256 data bytes which will be filled with read data.
9442 
9443    Returns 0xFFFF if error, otherwise
9444        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9445        if DDCdatatype = 0:  Returns supported DDC modes
9446 
9447  */
9448 unsigned short
SiS_HandleDDC(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,unsigned char * buffer,unsigned int VBFlags2)9449 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9450               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9451 	      unsigned int VBFlags2)
9452 {
9453    unsigned char  sr1f, cr17=1;
9454    unsigned short result;
9455 
9456    if(adaptnum > 2)
9457       return 0xFFFF;
9458 
9459    if(DDCdatatype > 4)
9460       return 0xFFFF;
9461 
9462    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9463       return 0xFFFF;
9464 
9465    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
9466       return 0xFFFF;
9467 
9468    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9469    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9470    if(VGAEngine == SIS_300_VGA) {
9471       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9472       if(!cr17) {
9473          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9474          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9475          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9476       }
9477    }
9478    if((sr1f) || (!cr17)) {
9479       SiS_WaitRetrace1(SiS_Pr);
9480       SiS_WaitRetrace1(SiS_Pr);
9481       SiS_WaitRetrace1(SiS_Pr);
9482       SiS_WaitRetrace1(SiS_Pr);
9483    }
9484 
9485    if(DDCdatatype == 0) {
9486       result = SiS_ProbeDDC(SiS_Pr);
9487    } else {
9488       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9489       if((!result) && (DDCdatatype == 1)) {
9490          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9491 	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9492 	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9493 	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9494 	    (buffer[0x12] == 1)) {
9495 	    if(!SiS_Pr->DDCPortMixup) {
9496 	       if(adaptnum == 1) {
9497 	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9498 	       } else {
9499 	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9500 	       }
9501 	    }
9502 	 }
9503       }
9504    }
9505    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9506    if(VGAEngine == SIS_300_VGA) {
9507       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9508    }
9509    return result;
9510 }
9511 
9512 /* Generic I2C functions for Chrontel & DDC --------- */
9513 
9514 static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9515 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9516 {
9517   SiS_SetSCLKHigh(SiS_Pr);
9518   SiS_WaitRetrace1(SiS_Pr);
9519 
9520   SiS_SetSCLKLow(SiS_Pr);
9521   SiS_WaitRetrace1(SiS_Pr);
9522 }
9523 
9524 unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9525 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9526 {
9527    SiS_WaitRetrace1(SiS_Pr);
9528    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9529 }
9530 
9531 /* Set I2C start condition */
9532 /* This is done by a SD high-to-low transition while SC is high */
9533 static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9534 SiS_SetStart(struct SiS_Private *SiS_Pr)
9535 {
9536   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9537   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9538 		  SiS_Pr->SiS_DDC_Index,
9539 		  SiS_Pr->SiS_DDC_NData,
9540 		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9541   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9542   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9543 		  SiS_Pr->SiS_DDC_Index,
9544 		  SiS_Pr->SiS_DDC_NData,
9545 		  0x00);					/* SD->low = start condition */
9546   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9547   return 0;
9548 }
9549 
9550 /* Set I2C stop condition */
9551 /* This is done by a SD low-to-high transition while SC is high */
9552 static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9553 SiS_SetStop(struct SiS_Private *SiS_Pr)
9554 {
9555   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9556   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9557 		  SiS_Pr->SiS_DDC_Index,
9558 		  SiS_Pr->SiS_DDC_NData,
9559 		  0x00);					/* SD->low   */
9560   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9561   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9562 		  SiS_Pr->SiS_DDC_Index,
9563 		  SiS_Pr->SiS_DDC_NData,
9564 		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9565   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9566   return 0;
9567 }
9568 
9569 /* Write 8 bits of data */
9570 static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9571 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9572 {
9573   unsigned short i,flag,temp;
9574 
9575   flag = 0x80;
9576   for(i = 0; i < 8; i++) {
9577     SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9578     if(tempax & flag) {
9579       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9580 		      SiS_Pr->SiS_DDC_Index,
9581 		      SiS_Pr->SiS_DDC_NData,
9582 		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9583     } else {
9584       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9585 		      SiS_Pr->SiS_DDC_Index,
9586 		      SiS_Pr->SiS_DDC_NData,
9587 		      0x00);					/* Write bit (0) to SD */
9588     }
9589     SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9590     flag >>= 1;
9591   }
9592   temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9593   return temp;
9594 }
9595 
9596 static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9597 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9598 {
9599   unsigned short i, temp, getdata;
9600 
9601   getdata = 0;
9602   for(i = 0; i < 8; i++) {
9603     getdata <<= 1;
9604     SiS_SetSCLKLow(SiS_Pr);
9605     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9606 		    SiS_Pr->SiS_DDC_Index,
9607 		    SiS_Pr->SiS_DDC_NData,
9608 		    SiS_Pr->SiS_DDC_Data);
9609     SiS_SetSCLKHigh(SiS_Pr);
9610     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9611     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9612   }
9613   return getdata;
9614 }
9615 
9616 static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9617 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9618 {
9619   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9620 		  SiS_Pr->SiS_DDC_Index,
9621 		  SiS_Pr->SiS_DDC_NClk,
9622 		  0x00);					/* SetSCLKLow()  */
9623   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9624   return 0;
9625 }
9626 
9627 static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9628 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9629 {
9630   unsigned short temp, watchdog=1000;
9631 
9632   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9633 		  SiS_Pr->SiS_DDC_Index,
9634 		  SiS_Pr->SiS_DDC_NClk,
9635 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9636   do {
9637     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9638   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9639   if (!watchdog) {
9640 #ifdef SIS_XORG_XF86
9641 #ifdef TWDEBUG
9642         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
9643 #endif
9644 #endif
9645   	return 0xFFFF;
9646   }
9647   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9648   return 0;
9649 }
9650 
9651 /* Check I2C acknowledge */
9652 /* Returns 0 if ack ok, non-0 if ack not ok */
9653 static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9654 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9655 {
9656   unsigned short tempah;
9657 
9658   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9659   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9660 		  SiS_Pr->SiS_DDC_Index,
9661 		  SiS_Pr->SiS_DDC_NData,
9662 		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9663   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9664   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9665   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9666   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9667   return 0;
9668 }
9669 
9670 /* End of I2C functions ----------------------- */
9671 
9672 
9673 /* =============== SiS 315/330 O.E.M. ================= */
9674 
9675 #ifdef SIS315H
9676 
9677 static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9678 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9679 {
9680   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9681   unsigned short romptr;
9682 
9683   if(SiS_Pr->ChipType < SIS_330) {
9684      romptr = SISGETROMW(0x128);
9685      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9686         romptr = SISGETROMW(0x12a);
9687   } else {
9688      romptr = SISGETROMW(0x1a8);
9689      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9690         romptr = SISGETROMW(0x1aa);
9691   }
9692   return romptr;
9693 }
9694 
9695 static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9696 GetLCDromptr(struct SiS_Private *SiS_Pr)
9697 {
9698   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9699   unsigned short romptr;
9700 
9701   if(SiS_Pr->ChipType < SIS_330) {
9702      romptr = SISGETROMW(0x120);
9703      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9704         romptr = SISGETROMW(0x122);
9705   } else {
9706      romptr = SISGETROMW(0x1a0);
9707      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9708         romptr = SISGETROMW(0x1a2);
9709   }
9710   return romptr;
9711 }
9712 
9713 static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9714 GetTVromptr(struct SiS_Private *SiS_Pr)
9715 {
9716   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9717   unsigned short romptr;
9718 
9719   if(SiS_Pr->ChipType < SIS_330) {
9720      romptr = SISGETROMW(0x114);
9721      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9722         romptr = SISGETROMW(0x11a);
9723   } else {
9724      romptr = SISGETROMW(0x194);
9725      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9726         romptr = SISGETROMW(0x19a);
9727   }
9728   return romptr;
9729 }
9730 
9731 static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9732 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9733 {
9734   unsigned short index;
9735 
9736   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9737      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9738         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9739 	   index >>= 4;
9740 	   index *= 3;
9741 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9742            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9743            return index;
9744 	}
9745      }
9746   }
9747 
9748   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9749   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9750   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9751      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9752      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9753   } else {
9754      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9755   }
9756   index--;
9757   index *= 3;
9758   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9759   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9760   return index;
9761 }
9762 
9763 static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9764 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9765 {
9766   unsigned short index;
9767 
9768   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9769   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9770   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9771   return index;
9772 }
9773 
9774 static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9775 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9776 {
9777   unsigned short index;
9778 
9779   index = 0;
9780   if(SiS_Pr->SiS_TVMode & TVSetPALTiming)    index = 1;
9781   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9782 
9783   index <<= 1;
9784 
9785   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9786      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9787      index++;
9788   }
9789 
9790   return index;
9791 }
9792 
9793 static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9794 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9795 {
9796    unsigned short index = 0, temp = 0;
9797 
9798    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9799    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9800    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9801    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9802    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9803       index = 4;
9804       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9805       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9806    }
9807 
9808    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9809       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9810          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9811 	 index += addme;
9812 	 temp++;
9813       }
9814       temp += 0x0100;
9815    }
9816    return (unsigned int)(index | (temp << 16));
9817 }
9818 
9819 static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9820 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9821 {
9822    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9823 }
9824 
9825 #if 0
9826 static unsigned int
9827 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9828 {
9829    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9830 }
9831 #endif
9832 
9833 static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9834 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9835 {
9836    int index = 0;
9837 
9838    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p))
9839       return 0xffff;
9840 
9841    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9842    if(SiS_Pr->SiS_ROMNew) {
9843       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9844       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9845       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9846       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9847    } else {
9848       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9849       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9850       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9851       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9852    }
9853 
9854    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9855 
9856    return index;
9857 }
9858 
9859 static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9860 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9861 {
9862   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9863   unsigned short delay=0,index,myindex,temp,romptr=0;
9864   BOOLEAN dochiptest = TRUE;
9865 
9866   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9867      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9868   } else {
9869      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9870   }
9871 
9872   /* Find delay (from ROM, internal tables, PCI subsystem) */
9873 
9874   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9875 
9876      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9877         romptr = GetRAMDACromptr(SiS_Pr);
9878      }
9879      if(romptr) delay = ROMAddr[romptr];
9880      else {
9881         delay = 0x04;
9882         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9883 	   if(IS_SIS650) {
9884 	      delay = 0x0a;
9885 	   } else if(IS_SIS740) {
9886 	      delay = 0x00;
9887 	   } else if(SiS_Pr->ChipType < SIS_330) {
9888 	      delay = 0x0c;
9889 	   } else {
9890 	      delay = 0x0c;
9891 	   }
9892 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9893            delay = 0x00;
9894 	}
9895      }
9896 
9897   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9898 
9899      BOOLEAN gotitfrompci = FALSE;
9900 
9901      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9902 
9903      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9904 	if(SiS_Pr->PDC != -1) {
9905            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9906 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9907 	   return;
9908 	}
9909      } else {
9910 	if(SiS_Pr->PDCA != -1) {
9911 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9912 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9913 	   return;
9914 	}
9915      }
9916 
9917      /* Custom Panel? */
9918 
9919      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9920         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9921 	   delay = 0x00;
9922 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9923 	      delay = 0x20;
9924 	   }
9925 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9926 	} else {
9927 	   delay = 0x0c;
9928 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9929 	      delay = 0x03;
9930 	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9931 	         delay = 0x00;
9932 	      }
9933 	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9934 	      if(IS_SIS740) delay = 0x01;
9935 	      else          delay = 0x03;
9936 	   }
9937 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9938 	}
9939         return;
9940      }
9941 
9942      /* This is a piece of typical SiS crap: They code the OEM LCD
9943       * delay into the code, at no defined place in the BIOS.
9944       * We now have to start doing a PCI subsystem check here.
9945       */
9946 
9947      switch(SiS_Pr->SiS_CustomT) {
9948      case CUT_COMPAQ1280:
9949      case CUT_COMPAQ12802:
9950 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9951 	   gotitfrompci = TRUE;
9952 	   dochiptest = FALSE;
9953 	   delay = 0x03;
9954 	}
9955 	break;
9956      case CUT_CLEVO1400:
9957      case CUT_CLEVO14002:
9958 	gotitfrompci = TRUE;
9959 	dochiptest = FALSE;
9960 	delay = 0x02;
9961 	break;
9962      case CUT_CLEVO1024:
9963      case CUT_CLEVO10242:
9964         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9965 	   gotitfrompci = TRUE;
9966 	   dochiptest = FALSE;
9967 	   delay = 0x33;
9968 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9969 	   delay &= 0x0f;
9970 	}
9971 	break;
9972      }
9973 
9974      /* Could we find it through the PCI ID? If no, use ROM or table */
9975 
9976      if(!gotitfrompci) {
9977 
9978         index = GetLCDPtrIndexBIOS(SiS_Pr);
9979         myindex = GetLCDPtrIndex(SiS_Pr);
9980 
9981         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9982 
9983            if(SiS_IsNotM650orLater(SiS_Pr)) {
9984 
9985               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9986 	         /* Always use the second pointer on 650; some BIOSes */
9987                  /* still carry old 301 data at the first location    */
9988 	         /* romptr = SISGETROMW(0x120);                       */
9989 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
9990 	         romptr = SISGETROMW(0x122);
9991 	         if(!romptr) return;
9992 	         delay = ROMAddr[(romptr + index)];
9993 	      } else {
9994                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9995 	      }
9996 
9997           } else {
9998 
9999              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10000 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10001 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10002 
10003           }
10004 
10005         } else if(SiS_Pr->SiS_UseROM 			      &&
10006 		  (!(SiS_Pr->SiS_ROMNew))		      &&
10007 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10008 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10009 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
10010 		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
10011 		  ((romptr = GetLCDromptr(SiS_Pr)))) {
10012 
10013 	   /* Data for 1280x1024 wrong in 301B BIOS */
10014 	   /* Data for 1600x1200 wrong in 301C BIOS */
10015 	   delay = ROMAddr[(romptr + index)];
10016 
10017         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10018 
10019 	   if(IS_SIS740) delay = 0x03;
10020 	   else          delay = 0x00;
10021 
10022 	} else {
10023 
10024            delay = SiS310_LCDDelayCompensation_301[myindex];
10025 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10026 	      if(IS_SIS740) delay = 0x01;
10027 	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10028 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10029 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10030 	      if(IS_SIS740) delay = 0x01;  /* ? */
10031 	      else          delay = 0x03;
10032 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10033 	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10034 	      if(IS_SIS740) delay = 0x01;
10035 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10036 	   }
10037 
10038         }
10039 
10040      }  /* got it from PCI */
10041 
10042      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10043 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10044 	dochiptest = FALSE;
10045      }
10046 
10047   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
10048 
10049      index = GetTVPtrIndex(SiS_Pr);
10050 
10051      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10052 
10053         if(SiS_IsNotM650orLater(SiS_Pr)) {
10054 
10055            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10056 	      /* Always use the second pointer on 650; some BIOSes */
10057               /* still carry old 301 data at the first location    */
10058               /* romptr = SISGETROMW(0x114);			   */
10059 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10060 	      romptr = SISGETROMW(0x11a);
10061 	      if(!romptr) return;
10062 	      delay = ROMAddr[romptr + index];
10063 
10064 	   } else {
10065 
10066 	      delay = SiS310_TVDelayCompensation_301B[index];
10067 
10068 	   }
10069 
10070         } else {
10071 
10072            switch(SiS_Pr->SiS_CustomT) {
10073 	   case CUT_COMPAQ1280:
10074 	   case CUT_COMPAQ12802:
10075 	   case CUT_CLEVO1400:
10076 	   case CUT_CLEVO14002:
10077 	      delay = 0x02;
10078 	      dochiptest = FALSE;
10079 	      break;
10080 	   case CUT_CLEVO1024:
10081 	   case CUT_CLEVO10242:
10082 	      delay = 0x03;
10083 	      dochiptest = FALSE;
10084    	      break;
10085 	   default:
10086               delay = SiS310_TVDelayCompensation_651301LV[index];
10087 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10088 	         delay = SiS310_TVDelayCompensation_651302LV[index];
10089 	      }
10090 	   }
10091         }
10092 
10093      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10094 
10095         romptr = GetTVromptr(SiS_Pr);
10096 	if(!romptr) return;
10097 	delay = ROMAddr[romptr + index];
10098 
10099      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10100 
10101         delay = SiS310_TVDelayCompensation_LVDS[index];
10102 
10103      } else {
10104 
10105 	delay = SiS310_TVDelayCompensation_301[index];
10106         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10107 	   if(IS_SIS740) {
10108 	      delay = SiS310_TVDelayCompensation_740301B[index];
10109 	      /* LV: use 301 data? BIOS bug? */
10110 	   } else {
10111               delay = SiS310_TVDelayCompensation_301B[index];
10112 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10113 	   }
10114 	}
10115 
10116      }
10117 
10118      if(SiS_LCDAEnabled(SiS_Pr)) {
10119 	delay &= 0x0f;
10120 	dochiptest = FALSE;
10121      }
10122 
10123   } else return;
10124 
10125   /* Write delay */
10126 
10127   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10128 
10129      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10130 
10131         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10132         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
10133 	   delay &= 0x0f;
10134 	   delay |= 0xb0;
10135         } else if(temp == 6) {
10136            delay &= 0x0f;
10137 	   delay |= 0xc0;
10138         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
10139 	   delay = 0x35;
10140         }
10141         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10142 
10143      } else {
10144 
10145         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10146 
10147      }
10148 
10149   } else {  /* LVDS */
10150 
10151      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10152         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10153      } else {
10154         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10155            delay <<= 4;
10156            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10157         } else {
10158            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10159         }
10160      }
10161 
10162   }
10163 
10164 }
10165 
10166 static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10167 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10168 {
10169   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10170   unsigned short index,temp,temp1,romptr=0;
10171 
10172   if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) return;
10173 
10174   if(ModeNo<=0x13)
10175      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10176   else
10177      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10178 
10179   temp = GetTVPtrIndex(SiS_Pr);
10180   temp >>= 1;  	  /* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */
10181   temp1 = temp;
10182 
10183   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10184      if(SiS_Pr->ChipType >= SIS_661) {
10185         temp1 = GetOEMTVPtr661(SiS_Pr);
10186 	if(temp1 != 0xffff) {
10187            temp1 >>= 1;
10188            romptr = SISGETROMW(0x260);
10189            if(SiS_Pr->ChipType >= SIS_760) {
10190 	      romptr = SISGETROMW(0x360);
10191 	   }
10192 	}
10193      } else if(SiS_Pr->ChipType >= SIS_330) {
10194         romptr = SISGETROMW(0x192);
10195      } else {
10196         romptr = SISGETROMW(0x112);
10197      }
10198   }
10199 
10200   if(romptr) {
10201      temp1 <<= 1;
10202      temp = ROMAddr[romptr + temp1 + index];
10203   } else {
10204      temp = SiS310_TVAntiFlick1[temp][index];
10205   }
10206   temp <<= 4;
10207 
10208   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10209 }
10210 
10211 static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10212 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10213 {
10214   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10215   unsigned short index,temp,temp1,romptr=0;
10216 
10217   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */
10218 
10219   if(ModeNo <= 0x13)
10220      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10221   else
10222      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10223 
10224   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10225      if(SiS_Pr->ChipType >= SIS_661) {
10226 	temp1 = GetOEMTVPtr661(SiS_Pr);
10227 	if(temp1 != 0xffff) {
10228            temp1 >>= 1;
10229 	   romptr = SISGETROMW(0x26c);
10230            if(SiS_Pr->ChipType >= SIS_760) {
10231 	      romptr = SISGETROMW(0x36c);
10232 	   }
10233 	}
10234      } else if(SiS_Pr->ChipType >= SIS_330) {
10235         romptr = SISGETROMW(0x1a4);
10236      } else {
10237         romptr = SISGETROMW(0x124);
10238      }
10239   }
10240 
10241   if(romptr) {
10242      temp1 <<= 1;
10243      temp = ROMAddr[romptr + temp1 + index];
10244   } else {
10245      temp = SiS310_TVEdge1[temp][index];
10246   }
10247   temp <<= 5;
10248   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10249 }
10250 
10251 static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10252 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10253 {
10254   unsigned short index, temp, i, j;
10255 
10256   if(ModeNo <= 0x13) {
10257      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10258   } else {
10259      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10260   }
10261 
10262   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10263 
10264   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10265   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10266   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10267   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10268 
10269   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10270      for(i=0x35, j=0; i<=0x38; i++, j++) {
10271         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10272      }
10273      for(i=0x48; i<=0x4A; i++, j++) {
10274         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10275      }
10276   } else {
10277      for(i=0x35, j=0; i<=0x38; i++, j++) {
10278         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10279      }
10280   }
10281 }
10282 
10283 static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10284 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10285 {
10286   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10287   unsigned short index,temp,i,j,resinfo,romptr=0;
10288   unsigned int  lindex;
10289 
10290   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10291 
10292   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10293   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10294 
10295   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10296      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10297      lindex <<= 2;
10298      for(j=0, i=0x31; i<=0x34; i++, j++) {
10299         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10300      }
10301      return;
10302   }
10303 
10304   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10305   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10306 
10307   if(ModeNo<=0x13) {
10308      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10309   } else {
10310      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10311   }
10312 
10313   temp = GetTVPtrIndex(SiS_Pr);
10314   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10315    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10316    */
10317   if(SiS_Pr->SiS_UseROM) {
10318      romptr = SISGETROMW(0x116);
10319      if(SiS_Pr->ChipType >= SIS_330) {
10320         romptr = SISGETROMW(0x196);
10321      }
10322      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10323         romptr = SISGETROMW(0x11c);
10324 	if(SiS_Pr->ChipType >= SIS_330) {
10325 	   romptr = SISGETROMW(0x19c);
10326 	}
10327 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10328 	   romptr = SISGETROMW(0x116);
10329 	   if(SiS_Pr->ChipType >= SIS_330) {
10330               romptr = SISGETROMW(0x196);
10331            }
10332 	}
10333      }
10334   }
10335   if(romptr) {
10336      romptr += (temp << 2);
10337      for(j=0, i=0x31; i<=0x34; i++, j++) {
10338         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10339      }
10340   } else {
10341      index = temp % 2;
10342      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10343      for(j=0, i=0x31; i<=0x34; i++, j++) {
10344         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10345 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10346         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10347            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10348         else
10349            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10350      }
10351   }
10352 
10353   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10354      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPrProg))) && (ModeNo > 0x13)) {
10355         if((resinfo == SIS_RI_640x480) ||
10356 	   (resinfo == SIS_RI_800x600)) {
10357 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10358 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10359 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10360 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10361 	} else if(resinfo == SIS_RI_1024x768) {
10362 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10363 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10364 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10365 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10366 	}
10367      }
10368   }
10369 }
10370 
10371 static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10372 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10373                 unsigned short ModeIdIndex, unsigned short RTI)
10374 {
10375    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10376    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10377 
10378    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10379       return;
10380 
10381    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10382    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10383 
10384    if(SiS_Pr->SiS_ROMNew) {
10385       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10386          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10387 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10388          index = 25;
10389          if(SiS_Pr->UseCustomMode) {
10390 	    index = SiS_Pr->CSRClock;
10391          } else if(ModeNo > 0x13) {
10392             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10393             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10394          }
10395 	 if(index < 25) index = 25;
10396          index = ((index / 25) - 1) << 1;
10397          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10398 	    index++;
10399 	 }
10400 	 romptr = SISGETROMW(0x104);
10401          delay = ROMAddr[romptr + index];
10402          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10403             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10404             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10405          } else {
10406             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10407 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10408          }
10409          return;
10410       }
10411    }
10412 
10413    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10414 
10415    if(SiS_Pr->UseCustomMode) delay = 0x04;
10416    else if(ModeNo <= 0x13)   delay = 0x04;
10417    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10418    delay |= (delay << 8);
10419 
10420    if(SiS_Pr->ChipType >= XGI_20) {
10421 
10422       delay = 0x0606;
10423 
10424       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10425 	 delay = 0x0404;
10426          if(SiS_Pr->SiS_XGIROM) {
10427 	     index = GetTVPtrIndex(SiS_Pr);
10428 	     if((romptr = SISGETROMW(0x35e))) {
10429 	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10430 		delay |= (delay << 8);
10431 	     }
10432 	 }
10433 
10434 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10435 	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10436 	       delay -= 0x0404;
10437 	    }
10438 	 }
10439       }
10440 
10441    } else if(SiS_Pr->ChipType >= SIS_340) {
10442 
10443       delay = 0x0606;
10444       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10445          delay = 0x0404;
10446       }
10447       /* TODO (eventually) */
10448 
10449    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10450 
10451       /* 3. TV */
10452 
10453       index = GetOEMTVPtr661(SiS_Pr);
10454       if((SiS_Pr->SiS_ROMNew) && (index != 0xffff)) {
10455          romptr = SISGETROMW(0x106);
10456 	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10457          delay = ROMAddr[romptr + index];
10458       } else {
10459          delay = 0x04;
10460 	 if(index > 3 || index == 0xffff) delay = 0;
10461       }
10462 
10463    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10464 
10465       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10466 
10467       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10468           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10469 
10470 	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10471 
10472 	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10473 	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10474 	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10475 
10476       } else {
10477 
10478          /* TMDS: Set our own, since BIOS has no idea */
10479 	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10480          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10481 	    switch(SiS_Pr->SiS_LCDResInfo) {
10482 	    case Panel_1024x768:  delay = 0x0008; break;
10483 	    case Panel_1280x720:  delay = 0x0004; break;
10484 	    case Panel_1280x768:
10485 	    case Panel_1280x768_2:delay = 0x0004; break;
10486 	    case Panel_1280x800:
10487 	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10488 	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10489 	    case Panel_1280x1024: delay = 0x1e04; break;
10490 	    case Panel_1400x1050: delay = 0x0004; break;
10491 	    case Panel_1600x1200: delay = 0x0400; break;
10492 	    case Panel_1680x1050: delay = 0x0e04; break;
10493 	    default:
10494                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10495 	          delay = 0x0008;
10496 	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10497 	          delay = 0x1e04;
10498                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10499 	          delay = 0x0004;
10500 	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10501 	          delay = 0x0400;
10502                } else
10503 	          delay = 0x0e04;
10504 	       break;
10505 	    }
10506          }
10507 
10508 	 /* Override by detected or user-set values */
10509 	 /* (but only if, for some reason, we can't read value from BIOS) */
10510          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10511             delay = SiS_Pr->PDC & 0x1f;
10512          }
10513          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10514             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10515          }
10516 
10517       }
10518 
10519    }
10520 
10521    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10522       delay >>= 8;
10523       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10524       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10525    } else {
10526       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10527       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10528    }
10529 }
10530 
10531 static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10532 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10533 {
10534    unsigned short infoflag;
10535    unsigned char  temp;
10536 
10537    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10538 
10539       if(ModeNo <= 0x13) {
10540          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10541       } else if(SiS_Pr->UseCustomMode) {
10542          infoflag = SiS_Pr->CInfoFlag;
10543       } else {
10544          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10545       }
10546 
10547       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10548          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10549       }
10550 
10551       infoflag &= 0xc0;
10552 
10553       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10554          temp = (infoflag >> 6) | 0x0c;
10555          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10556 	    temp ^= 0x04;
10557 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10558 	 }
10559          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10560       } else {
10561          temp = 0x30;
10562          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10563          temp |= infoflag;
10564          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10565          temp = 0;
10566          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10567 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10568 	 }
10569          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10570       }
10571 
10572    }
10573 }
10574 
10575 static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10576 SetPanelParms661(struct SiS_Private *SiS_Pr)
10577 {
10578    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10579    unsigned short romptr, temp1, temp2;
10580 
10581    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10582       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10583    }
10584 
10585    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10586       if(SiS_Pr->LVDSHL != -1) {
10587          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10588       }
10589    }
10590 
10591    if(SiS_Pr->SiS_ROMNew) {
10592 
10593       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10594          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10595             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10596 	    temp2 = 0xfc;
10597 	    if(SiS_Pr->LVDSHL != -1) {
10598 	      temp1 &= 0xfc;
10599 	      temp2 = 0xf3;
10600 	    }
10601 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10602          }
10603 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10604             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10605             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10606 	 }
10607       }
10608 
10609    }
10610 }
10611 
10612 static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10613 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10614 {
10615    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10616       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10617       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10618          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10619          SetPanelParms661(SiS_Pr);
10620       }
10621    } else {
10622       SetDelayComp(SiS_Pr,ModeNo);
10623    }
10624 
10625    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10626       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10627       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10628       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10629       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10630          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10631       }
10632    }
10633 }
10634 
10635 static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10636 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10637 			unsigned short ModeIdIndex, unsigned short RRTI)
10638 {
10639    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10640 
10641       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10642 
10643       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10644          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10645          SetPanelParms661(SiS_Pr);
10646       }
10647 
10648       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10649          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10650          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10651          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10652          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10653             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10654          }
10655       }
10656    }
10657 }
10658 
10659 /* FinalizeLCD
10660  * This finalizes some CRT2 registers for the very panel used.
10661  * If we have a backup if these registers, we use it; otherwise
10662  * we set the register according to most BIOSes. However, this
10663  * function looks quite different in every BIOS, so you better
10664  * pray that we have a backup...
10665  */
10666 static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10667 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10668 {
10669   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10670   unsigned short resinfo,modeflag;
10671 
10672   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10673   if(SiS_Pr->SiS_ROMNew) return;
10674 
10675   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10676      if(SiS_Pr->LVDSHL != -1) {
10677         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10678      }
10679   }
10680 
10681   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10682   if(SiS_Pr->UseCustomMode) return;
10683 
10684   switch(SiS_Pr->SiS_CustomT) {
10685   case CUT_COMPAQ1280:
10686   case CUT_COMPAQ12802:
10687   case CUT_CLEVO1400:
10688   case CUT_CLEVO14002:
10689      return;
10690   }
10691 
10692   if(ModeNo <= 0x13) {
10693      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10694      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10695   } else {
10696      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10697      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10698   }
10699 
10700   if(IS_SIS650) {
10701      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10702         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10703 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10704 	} else {
10705            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10706 	}
10707      }
10708   }
10709 
10710   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10711      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10712         /* Maybe all panels? */
10713         if(SiS_Pr->LVDSHL == -1) {
10714            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10715 	}
10716 	return;
10717      }
10718   }
10719 
10720   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10721      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10722         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10723 	   if(SiS_Pr->LVDSHL == -1) {
10724 	      /* Maybe all panels? */
10725               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10726 	   }
10727 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10728 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10729 	      if(tempch == 3) {
10730 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10731 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10732 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10733 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10734 	      }
10735 	   }
10736 	   return;
10737 	}
10738      }
10739   }
10740 
10741   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10742      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10743 	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10744 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10745 #ifdef SET_EMI
10746 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10747 #endif
10748 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10749 	}
10750      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10751         if(SiS_Pr->LVDSHL == -1) {
10752            /* Maybe ACER only? */
10753            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10754 	}
10755      }
10756      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10757      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10758 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10759 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10760 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10761 	   if(tempch == 0x03) {
10762 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10763 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10764 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10765 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10766 	   }
10767 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
10768 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10769 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10770 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10771 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10772 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10773 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10774 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10775 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10776 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10777 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10778 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10779 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10780 	      if(ModeNo <= 0x13) {
10781 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10782 		 if((resinfo == 0) || (resinfo == 2)) return;
10783 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10784 		 if((resinfo == 1) || (resinfo == 3)) return;
10785 	      }
10786 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10787 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10788 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10789 #if 0
10790 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10791 		 tempbx--;
10792 		 temp = tempbx & 0xff;
10793 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10794 		 temp = (tempbx >> 8) & 0x03;
10795 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10796 #endif
10797 	      }
10798 	   } else if(ModeNo <= 0x13) {
10799 	      if(ModeNo <= 1) {
10800 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10801 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10802 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10803 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10804 	      }
10805 	      if(!(modeflag & HalfDCLK)) {
10806 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10807 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10808 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10809 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10810 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10811 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10812 		 if(ModeNo == 0x12) {
10813 		    switch(tempch) {
10814 		       case 0:
10815 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10816 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10817 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10818 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10819 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10820 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10821 			  break;
10822 		       case 2:
10823 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10824 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10825 			  break;
10826 		       case 3:
10827 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10828 			  break;
10829 		    }
10830 		 }
10831 	      }
10832 	   }
10833 	}
10834      } else {
10835         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10836 	tempcl &= 0x0f;
10837 	tempbh &= 0x70;
10838 	tempbh >>= 4;
10839 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10840 	tempbx = (tempbh << 8) | tempbl;
10841 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10842 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10843 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10844 	      	 tempbx = 770;
10845 	      } else {
10846 	         if(tempbx > 770) tempbx = 770;
10847 		 if(SiS_Pr->SiS_VGAVDE < 600) {
10848 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10849 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10850 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10851 		    tempbx -= tempax;
10852 		 }
10853 	      }
10854 	   } else return;
10855 	}
10856 	temp = tempbx & 0xff;
10857 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10858 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10859 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10860      }
10861   }
10862 }
10863 
10864 #endif
10865 
10866 /*  =================  SiS 300 O.E.M. ================== */
10867 
10868 #ifdef SIS300
10869 
10870 static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10871 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10872 		unsigned short RefTabIndex)
10873 {
10874   unsigned short crt2crtc=0, modeflag, myindex=0;
10875   unsigned char  temp;
10876   int i;
10877 
10878   if(ModeNo <= 0x13) {
10879      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10880      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10881   } else {
10882      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10883      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10884   }
10885 
10886   crt2crtc &= 0x3f;
10887 
10888   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10889      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10890   }
10891 
10892   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10893      if(modeflag & HalfDCLK) myindex = 1;
10894 
10895      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10896         for(i=0; i<7; i++) {
10897            if(barco_p1[myindex][crt2crtc][i][0]) {
10898 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10899 	                      barco_p1[myindex][crt2crtc][i][0],
10900 	   	   	      barco_p1[myindex][crt2crtc][i][2],
10901 			      barco_p1[myindex][crt2crtc][i][1]);
10902 	   }
10903         }
10904      }
10905      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10906      if(temp & 0x80) {
10907         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10908         temp++;
10909         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10910      }
10911   }
10912 }
10913 
10914 static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10915 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10916 {
10917   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10918   unsigned short tempbx=0,romptr=0;
10919   static const unsigned char customtable300[] = {
10920 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10921 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10922   };
10923   static const unsigned char customtable630[] = {
10924 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10925 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10926   };
10927 
10928   if(SiS_Pr->ChipType == SIS_300) {
10929 
10930     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10931     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10932     tempbx -= 2;
10933     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10934     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10935        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10936     }
10937     if(SiS_Pr->SiS_UseROM) {
10938        if(ROMAddr[0x235] & 0x80) {
10939           tempbx = SiS_Pr->SiS_LCDTypeInfo;
10940           if(Flag) {
10941 	     romptr = SISGETROMW(0x255);
10942 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10943 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10944              if(tempbx == 0xFF) return 0xFFFF;
10945           }
10946 	  tempbx <<= 1;
10947 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10948        }
10949     }
10950 
10951   } else {
10952 
10953     if(Flag) {
10954        if(SiS_Pr->SiS_UseROM) {
10955           romptr = SISGETROMW(0x255);
10956 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10957 	  else 	     tempbx = 0xff;
10958        } else {
10959           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10960        }
10961        if(tempbx == 0xFF) return 0xFFFF;
10962        tempbx <<= 2;
10963        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10964        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10965        return tempbx;
10966     }
10967     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10968     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10969     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10970 
10971   }
10972 
10973   return tempbx;
10974 }
10975 
10976 static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10977 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10978 {
10979   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10980   unsigned short index,temp,romptr=0;
10981 
10982   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10983 
10984   if(SiS_Pr->SiS_UseROM) {
10985      if(!(ROMAddr[0x237] & 0x01)) return;
10986      if(!(ROMAddr[0x237] & 0x02)) return;
10987      romptr = SISGETROMW(0x24b);
10988   }
10989 
10990   /* The Panel Compensation Delay should be set according to tables
10991    * here. Unfortunately, various BIOS versions don't care about
10992    * a uniform way using eg. ROM byte 0x220, but use different
10993    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10994    * Thus we don't set this if the user selected a custom pdc or if
10995    * we otherwise detected a valid pdc.
10996    */
10997   if(SiS_Pr->PDC != -1) return;
10998 
10999   temp = GetOEMLCDPtr(SiS_Pr, 0);
11000 
11001   if(SiS_Pr->UseCustomMode)
11002      index = 0;
11003   else
11004      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11005 
11006   if(SiS_Pr->ChipType != SIS_300) {
11007      if(romptr) {
11008 	romptr += (temp * 2);
11009 	romptr = SISGETROMW(romptr);
11010 	romptr += index;
11011 	temp = ROMAddr[romptr];
11012      } else {
11013 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
11014     	   temp = SiS300_OEMLCDDelay2[temp][index];
11015 	} else {
11016            temp = SiS300_OEMLCDDelay3[temp][index];
11017         }
11018      }
11019   } else {
11020      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11021 	if(romptr) {
11022 	   romptr += (temp * 2);
11023 	   romptr = SISGETROMW(romptr);
11024 	   romptr += index;
11025 	   temp = ROMAddr[romptr];
11026 	} else {
11027 	   temp = SiS300_OEMLCDDelay5[temp][index];
11028 	}
11029      } else {
11030         if(SiS_Pr->SiS_UseROM) {
11031 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11032 	   if(romptr) {
11033 	      romptr += (temp * 2);
11034 	      romptr = SISGETROMW(romptr);
11035 	      romptr += index;
11036 	      temp = ROMAddr[romptr];
11037 	   } else {
11038 	      temp = SiS300_OEMLCDDelay4[temp][index];
11039 	   }
11040 	} else {
11041 	   temp = SiS300_OEMLCDDelay4[temp][index];
11042 	}
11043      }
11044   }
11045   temp &= 0x3c;
11046   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11047 }
11048 
11049 static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11050 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11051 {
11052 #if 0  /* Unfinished; Data table missing */
11053   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11054   unsigned short index,temp;
11055 
11056   if((SiS_Pr->SiS_UseROM) {
11057      if(!(ROMAddr[0x237] & 0x01)) return;
11058      if(!(ROMAddr[0x237] & 0x04)) return;
11059      /* No rom pointer in BIOS header! */
11060   }
11061 
11062   temp = GetOEMLCDPtr(SiS_Pr, 1);
11063   if(temp == 0xFFFF) return;
11064 
11065   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11066   for(i=0x14, j=0; i<=0x17; i++, j++) {
11067       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11068   }
11069   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11070 
11071   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11072   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11073   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11074   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11075   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11076       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11077   }
11078 #endif
11079 }
11080 
11081 static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)11082 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11083 {
11084   unsigned short index;
11085 
11086   index = 0;
11087   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11088   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11089      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11090      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11091      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11092   } else {
11093      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11094      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11095   }
11096   return index;
11097 }
11098 
11099 static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11100 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11101 {
11102   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11103   unsigned short index,temp,romptr=0;
11104 
11105   if(SiS_Pr->SiS_UseROM) {
11106      if(!(ROMAddr[0x238] & 0x01)) return;
11107      if(!(ROMAddr[0x238] & 0x02)) return;
11108      romptr = SISGETROMW(0x241);
11109   }
11110 
11111   temp = GetOEMTVPtr(SiS_Pr);
11112 
11113   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11114 
11115   if(romptr) {
11116      romptr += (temp * 2);
11117      romptr = SISGETROMW(romptr) + index;
11118      temp = ROMAddr[romptr];
11119   } else {
11120      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11121         temp = SiS300_OEMTVDelay301[temp][index];
11122      } else {
11123         temp = SiS300_OEMTVDelayLVDS[temp][index];
11124      }
11125   }
11126   temp &= 0x3c;
11127   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11128 }
11129 
11130 static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11131 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11132 {
11133   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11134   unsigned short index,temp,romptr=0;
11135 
11136   if(SiS_Pr->SiS_UseROM) {
11137      if(!(ROMAddr[0x238] & 0x01)) return;
11138      if(!(ROMAddr[0x238] & 0x04)) return;
11139      romptr = SISGETROMW(0x243);
11140   }
11141 
11142   temp = GetOEMTVPtr(SiS_Pr);
11143 
11144   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11145 
11146   if(romptr) {
11147      romptr += (temp * 2);
11148      romptr = SISGETROMW(romptr);
11149      romptr += index;
11150      temp = ROMAddr[romptr];
11151   } else {
11152      temp = SiS300_OEMTVFlicker[temp][index];
11153   }
11154   temp &= 0x70;
11155   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11156 }
11157 
11158 static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11159 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11160 {
11161   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11162   unsigned short index,i,j,temp,romptr=0;
11163 
11164   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11165 
11166   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11167 
11168   if(SiS_Pr->SiS_UseROM) {
11169      if(!(ROMAddr[0x238] & 0x01)) return;
11170      if(!(ROMAddr[0x238] & 0x08)) return;
11171      romptr = SISGETROMW(0x245);
11172   }
11173 
11174   temp = GetOEMTVPtr(SiS_Pr);
11175 
11176   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11177 
11178   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11179      for(i=0x31, j=0; i<=0x34; i++, j++) {
11180         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11181      }
11182   } else {
11183      if(romptr) {
11184         romptr += (temp * 2);
11185 	romptr = SISGETROMW(romptr);
11186 	romptr += (index * 4);
11187         for(i=0x31, j=0; i<=0x34; i++, j++) {
11188 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11189 	}
11190      } else {
11191         for(i=0x31, j=0; i<=0x34; i++, j++) {
11192            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11193 	}
11194      }
11195   }
11196 }
11197 
11198 static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11199 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11200 {
11201   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11202   unsigned short index,temp,i,j,romptr=0;
11203 
11204   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11205 
11206   if(SiS_Pr->SiS_UseROM) {
11207      if(!(ROMAddr[0x238] & 0x01)) return;
11208      if(!(ROMAddr[0x238] & 0x10)) return;
11209      romptr = SISGETROMW(0x247);
11210   }
11211 
11212   temp = GetOEMTVPtr(SiS_Pr);
11213 
11214   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11215   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11216   /* NTSCJ uses NTSC filters */
11217 
11218   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11219 
11220   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11221       for(i=0x35, j=0; i<=0x38; i++, j++) {
11222        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11223       }
11224       for(i=0x48; i<=0x4A; i++, j++) {
11225      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11226       }
11227   } else {
11228       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11229          romptr += (temp * 2);
11230 	 romptr = SISGETROMW(romptr);
11231 	 romptr += (index * 4);
11232 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11233        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11234          }
11235       } else {
11236          for(i=0x35, j=0; i<=0x38; i++, j++) {
11237        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11238          }
11239       }
11240   }
11241 }
11242 
11243 static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11244 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11245 {
11246    unsigned short ModeIdIndex;
11247    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11248 
11249    if(*ModeNo <= 5) *ModeNo |= 1;
11250 
11251    for(ModeIdIndex=0; ; ModeIdIndex++) {
11252       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11253       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11254    }
11255 
11256    if(*ModeNo != 0x07) {
11257       if(*ModeNo > 0x03) return ModeIdIndex;
11258       if(VGAINFO & 0x80) return ModeIdIndex;
11259       ModeIdIndex++;
11260    }
11261 
11262    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11263 	                               /* else 350 lines */
11264    return ModeIdIndex;
11265 }
11266 
11267 static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11268 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11269 		  unsigned short RefTableIndex)
11270 {
11271   unsigned short OEMModeIdIndex = 0;
11272 
11273   if(!SiS_Pr->UseCustomMode) {
11274      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11275      if(!(OEMModeIdIndex)) return;
11276   }
11277 
11278   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11279      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11280      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11281         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11282      }
11283   }
11284   if(SiS_Pr->UseCustomMode) return;
11285   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11286      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11287      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11288         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11289     	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11290        	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11291      }
11292   }
11293 }
11294 #endif
11295 
11296