1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4  * Mode initializing code (CRT2 section)
5  * for SiS 300/305/540/630/730,
6  *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7  *     XGI V3XT/V5/V8, Z7
8  * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9  *
10  * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11  *
12  * If distributed as part of the Linux kernel, the following license terms
13  * apply:
14  *
15  * * This program is free software; you can redistribute it and/or modify
16  * * it under the terms of the GNU General Public License as published by
17  * * the Free Software Foundation; either version 2 of the named License,
18  * * or any later version.
19  * *
20  * * This program is distributed in the hope that it will be useful,
21  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * * GNU General Public License for more details.
24  * *
25  * * You should have received a copy of the GNU General Public License
26  * * along with this program; if not, write to the Free Software
27  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28  *
29  * Otherwise, the following license terms apply:
30  *
31  * * Redistribution and use in source and binary forms, with or without
32  * * modification, are permitted provided that the following conditions
33  * * are met:
34  * * 1) Redistributions of source code must retain the above copyright
35  * *    notice, this list of conditions and the following disclaimer.
36  * * 2) Redistributions in binary form must reproduce the above copyright
37  * *    notice, this list of conditions and the following disclaimer in the
38  * *    documentation and/or other materials provided with the distribution.
39  * * 3) The name of the author may not be used to endorse or promote products
40  * *    derived from this software without specific prior written permission.
41  * *
42  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52  *
53  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
54  *
55  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56  * Used by permission.
57  *
58  */
59 
60 #if 1
61 #define SET_EMI		/* 302LV/ELV: Set EMI values */
62 #endif
63 
64 #if 1
65 #define SET_PWD		/* 301/302LV: Set PWD */
66 #endif
67 
68 #define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */
69 #define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */
70 #define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */
71 
72 #include "init301.h"
73 
74 #ifdef CONFIG_FB_SIS_300
75 #include "oem300.h"
76 #endif
77 
78 #ifdef CONFIG_FB_SIS_315
79 #include "oem310.h"
80 #endif
81 
82 #define SiS_I2CDELAY      1000
83 #define SiS_I2CDELAYSHORT  150
84 
85 static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
86 static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
87 
88 /*********************************************/
89 /*         HELPER: Lock/Unlock CRT2          */
90 /*********************************************/
91 
92 void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)93 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
94 {
95    if(SiS_Pr->ChipType == XGI_20)
96       return;
97    else if(SiS_Pr->ChipType >= SIS_315H)
98       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99    else
100       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101 }
102 
103 static
104 void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)105 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
106 {
107    if(SiS_Pr->ChipType == XGI_20)
108       return;
109    else if(SiS_Pr->ChipType >= SIS_315H)
110       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
111    else
112       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
113 }
114 
115 /*********************************************/
116 /*            HELPER: Write SR11             */
117 /*********************************************/
118 
119 static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)120 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
121 {
122    if(SiS_Pr->ChipType >= SIS_661) {
123       DataAND &= 0x0f;
124       DataOR  &= 0x0f;
125    }
126    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
127 }
128 
129 /*********************************************/
130 /*    HELPER: Get Pointer to LCD structure   */
131 /*********************************************/
132 
133 #ifdef CONFIG_FB_SIS_315
134 static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)135 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
136 {
137    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
138    unsigned char  *myptr = NULL;
139    unsigned short romindex = 0, reg = 0, idx = 0;
140 
141    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
142     * due to the variaty of panels the BIOS doesn't know about.
143     * Exception: If the BIOS has better knowledge (such as in case
144     * of machines with a 301C and a panel that does not support DDC)
145     * use the BIOS data as well.
146     */
147 
148    if((SiS_Pr->SiS_ROMNew) &&
149       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
150 
151       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
152       else                           reg = 0x7d;
153 
154       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
155 
156       if(idx < (8*26)) {
157          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
158       }
159       romindex = SISGETROMW(0x100);
160       if(romindex) {
161          romindex += idx;
162          myptr = &ROMAddr[romindex];
163       }
164    }
165    return myptr;
166 }
167 
168 static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)169 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
170 {
171    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
172    unsigned short romptr = 0;
173 
174    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
175     * due to the variaty of panels the BIOS doesn't know about.
176     * Exception: If the BIOS has better knowledge (such as in case
177     * of machines with a 301C and a panel that does not support DDC)
178     * use the BIOS data as well.
179     */
180 
181    if((SiS_Pr->SiS_ROMNew) &&
182       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
183       romptr = SISGETROMW(0x102);
184       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
185    }
186 
187    return romptr;
188 }
189 #endif
190 
191 /*********************************************/
192 /*           Adjust Rate for CRT2            */
193 /*********************************************/
194 
195 static bool
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)196 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
197 		unsigned short RRTI, unsigned short *i)
198 {
199    unsigned short checkmask=0, modeid, infoflag;
200 
201    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
202 
203    if(SiS_Pr->SiS_VBType & VB_SISVB) {
204 
205       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
206 
207 	 checkmask |= SupportRAMDAC2;
208 	 if(SiS_Pr->ChipType >= SIS_315H) {
209 	    checkmask |= SupportRAMDAC2_135;
210 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
211 	       checkmask |= SupportRAMDAC2_162;
212 	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
213 		  checkmask |= SupportRAMDAC2_202;
214 	       }
215 	    }
216 	 }
217 
218       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
219 
220 	 checkmask |= SupportLCD;
221 	 if(SiS_Pr->ChipType >= SIS_315H) {
222 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
223 	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
224 	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
225 	       }
226 	    }
227 	 }
228 
229       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
230 
231 	 checkmask |= SupportHiVision;
232 
233       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
234 
235 	 checkmask |= SupportTV;
236 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
237 	    checkmask |= SupportTV1024;
238 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
239 	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
240 	          checkmask |= SupportYPbPr750p;
241 	       }
242 	    }
243 	 }
244 
245       }
246 
247    } else {	/* LVDS */
248 
249       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
250 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
251 	    checkmask |= SupportCHTV;
252 	 }
253       }
254 
255       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
256 	 checkmask |= SupportLCD;
257       }
258 
259    }
260 
261    /* Look backwards in table for matching CRT2 mode */
262    for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
263       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
264       if(infoflag & checkmask) return true;
265       if((*i) == 0) break;
266    }
267 
268    /* Look through the whole mode-section of the table from the beginning
269     * for a matching CRT2 mode if no mode was found yet.
270     */
271    for((*i) = 0; ; (*i)++) {
272       if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
273       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
274       if(infoflag & checkmask) return true;
275    }
276    return false;
277 }
278 
279 /*********************************************/
280 /*              Get rate index               */
281 /*********************************************/
282 
283 unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)284 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
285 {
286    unsigned short RRTI,i,backup_i;
287    unsigned short modeflag,index,temp,backupindex;
288    static const unsigned short LCDRefreshIndex[] = {
289 		0x00, 0x00, 0x01, 0x01,
290 		0x01, 0x01, 0x01, 0x01,
291 		0x01, 0x01, 0x01, 0x01,
292 		0x01, 0x01, 0x01, 0x01,
293 		0x00, 0x00, 0x00, 0x00
294    };
295 
296    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
297    if(ModeNo == 0xfe) return 0;
298 
299    if(ModeNo <= 0x13) {
300       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
301    } else {
302       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
303    }
304 
305    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
306       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
307 	 if(modeflag & HalfDCLK) return 0;
308       }
309    }
310 
311    if(ModeNo < 0x14) return 0xFFFF;
312 
313    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
314    backupindex = index;
315 
316    if(index > 0) index--;
317 
318    if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
319       if(SiS_Pr->SiS_VBType & VB_SISVB) {
320 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
321 	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
322 	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
323 	 }
324 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
325 	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
326 	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
327 	       if(index > temp) index = temp;
328 	    }
329 	 }
330       } else {
331 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
332 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
333 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
334 	 }
335       }
336    }
337 
338    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
339    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
340 
341    if(SiS_Pr->ChipType >= SIS_315H) {
342       if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
343 	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
344 	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
345 	    if(backupindex <= 1) RRTI++;
346 	 }
347       }
348    }
349 
350    i = 0;
351    do {
352       if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
353       temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
354       temp &= ModeTypeMask;
355       if(temp < SiS_Pr->SiS_ModeType) break;
356       i++;
357       index--;
358    } while(index != 0xFFFF);
359 
360    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
361       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
362 	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
363 	 if(temp & InterlaceMode) i++;
364       }
365    }
366 
367    i--;
368 
369    if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
370       backup_i = i;
371       if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
372 	 i = backup_i;
373       }
374    }
375 
376    return (RRTI + i);
377 }
378 
379 /*********************************************/
380 /*            STORE CRT2 INFO in CR34        */
381 /*********************************************/
382 
383 static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)384 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
385 {
386    unsigned short temp1, temp2;
387 
388    /* Store CRT1 ModeNo in CR34 */
389    SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
390    temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
391    temp2 = ~(SetInSlaveMode >> 8);
392    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
393 }
394 
395 /*********************************************/
396 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
397 /*********************************************/
398 
399 #ifdef CONFIG_FB_SIS_300
400 static bool
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)401 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
402 {
403    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
404    unsigned short temp,temp1;
405 
406    if(SiS_Pr->SiS_UseROM) {
407       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
408 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
409 	 temp1 = SISGETROMW(0x23b);
410 	 if(temp1 & temp) return true;
411       }
412    }
413    return false;
414 }
415 
416 static bool
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)417 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
418 {
419    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
420    unsigned short temp,temp1;
421 
422    if(SiS_Pr->SiS_UseROM) {
423       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
424 	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
425 	 temp1 = SISGETROMW(0x23d);
426 	 if(temp1 & temp) return true;
427       }
428    }
429    return false;
430 }
431 #endif
432 
433 /*********************************************/
434 /*          HELPER: DELAY FUNCTIONS          */
435 /*********************************************/
436 
437 void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)438 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
439 {
440    while (delaytime-- > 0)
441       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
442 }
443 
444 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
445 static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)446 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
447 {
448    SiS_DDC2Delay(SiS_Pr, delay * 36);
449 }
450 #endif
451 
452 #ifdef CONFIG_FB_SIS_315
453 static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)454 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
455 {
456    while(delay--) {
457       SiS_GenericDelay(SiS_Pr, 6623);
458    }
459 }
460 #endif
461 
462 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
463 static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)464 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
465 {
466    while(delay--) {
467       SiS_GenericDelay(SiS_Pr, 66);
468    }
469 }
470 #endif
471 
472 static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)473 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
474 {
475 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
476    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
477    unsigned short PanelID, DelayIndex, Delay=0;
478 #endif
479 
480    if(SiS_Pr->ChipType < SIS_315H) {
481 
482 #ifdef CONFIG_FB_SIS_300
483 
484       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
485       if(SiS_Pr->SiS_VBType & VB_SISVB) {
486 	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
487 	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
488       }
489       DelayIndex = PanelID >> 4;
490       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
491 	 Delay = 3;
492       } else {
493 	 if(DelayTime >= 2) DelayTime -= 2;
494 	 if(!(DelayTime & 0x01)) {
495 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
496 	 } else {
497 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
498 	 }
499 	 if(SiS_Pr->SiS_UseROM) {
500 	    if(ROMAddr[0x220] & 0x40) {
501 	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
502 	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
503 	    }
504 	 }
505       }
506       SiS_ShortDelay(SiS_Pr, Delay);
507 
508 #endif  /* CONFIG_FB_SIS_300 */
509 
510    } else {
511 
512 #ifdef CONFIG_FB_SIS_315
513 
514       if((SiS_Pr->ChipType >= SIS_661)    ||
515 	 (SiS_Pr->ChipType <= SIS_315PRO) ||
516 	 (SiS_Pr->ChipType == SIS_330)    ||
517 	 (SiS_Pr->SiS_ROMNew)) {
518 
519 	 if(!(DelayTime & 0x01)) {
520 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
521 	 } else {
522 	    SiS_DDC2Delay(SiS_Pr, 0x4000);
523 	 }
524 
525       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
526 	 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
527 	 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {			/* 315 series, LVDS; Special */
528 
529 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
530 	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
531 	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
532 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
533 	    }
534 	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
535 	       DelayIndex = PanelID & 0x0f;
536 	    } else {
537 	       DelayIndex = PanelID >> 4;
538 	    }
539 	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
540 	       Delay = 3;
541 	    } else {
542 	       if(DelayTime >= 2) DelayTime -= 2;
543 	       if(!(DelayTime & 0x01)) {
544 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
545 		} else {
546 		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
547 	       }
548 	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
549 		  if(ROMAddr[0x13c] & 0x40) {
550 		     if(!(DelayTime & 0x01)) {
551 			Delay = (unsigned short)ROMAddr[0x17e];
552 		     } else {
553 			Delay = (unsigned short)ROMAddr[0x17f];
554 		     }
555 		  }
556 	       }
557 	    }
558 	    SiS_ShortDelay(SiS_Pr, Delay);
559 	 }
560 
561       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
562 
563 	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
564 	 if(!(DelayTime & 0x01)) {
565 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
566 	 } else {
567 	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
568 	 }
569 	 Delay <<= 8;
570 	 SiS_DDC2Delay(SiS_Pr, Delay);
571 
572       }
573 
574 #endif /* CONFIG_FB_SIS_315 */
575 
576    }
577 }
578 
579 #ifdef CONFIG_FB_SIS_315
580 static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)581 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
582 {
583    int i;
584    for(i = 0; i < DelayLoop; i++) {
585       SiS_PanelDelay(SiS_Pr, DelayTime);
586    }
587 }
588 #endif
589 
590 /*********************************************/
591 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
592 /*********************************************/
593 
594 void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)595 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
596 {
597    unsigned short watchdog;
598 
599    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
600    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
601 
602    watchdog = 65535;
603    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
604    watchdog = 65535;
605    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
606 }
607 
608 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
609 static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)610 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
611 {
612    unsigned short watchdog;
613 
614    watchdog = 65535;
615    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
616    watchdog = 65535;
617    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
618 }
619 #endif
620 
621 static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)622 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
623 {
624    if(SiS_Pr->ChipType < SIS_315H) {
625 #ifdef CONFIG_FB_SIS_300
626       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
627 	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
628       }
629       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
630 	 SiS_WaitRetrace1(SiS_Pr);
631       } else {
632 	 SiS_WaitRetrace2(SiS_Pr, 0x25);
633       }
634 #endif
635    } else {
636 #ifdef CONFIG_FB_SIS_315
637       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
638 	 SiS_WaitRetrace1(SiS_Pr);
639       } else {
640 	 SiS_WaitRetrace2(SiS_Pr, 0x30);
641       }
642 #endif
643    }
644 }
645 
646 static void
SiS_VBWait(struct SiS_Private * SiS_Pr)647 SiS_VBWait(struct SiS_Private *SiS_Pr)
648 {
649    unsigned short tempal,temp,i,j;
650 
651    temp = 0;
652    for(i = 0; i < 3; i++) {
653      for(j = 0; j < 100; j++) {
654         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
655         if(temp & 0x01) {
656 	   if((tempal & 0x08))  continue;
657 	   else break;
658         } else {
659 	   if(!(tempal & 0x08)) continue;
660 	   else break;
661         }
662      }
663      temp ^= 0x01;
664    }
665 }
666 
667 static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)668 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
669 {
670    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
671       SiS_VBWait(SiS_Pr);
672    } else {
673       SiS_WaitRetrace1(SiS_Pr);
674    }
675 }
676 
677 /*********************************************/
678 /*               HELPER: MISC                */
679 /*********************************************/
680 
681 #ifdef CONFIG_FB_SIS_300
682 static bool
SiS_Is301B(struct SiS_Private * SiS_Pr)683 SiS_Is301B(struct SiS_Private *SiS_Pr)
684 {
685    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
686    return false;
687 }
688 #endif
689 
690 static bool
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)691 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
692 {
693    if(SiS_Pr->ChipType == SIS_730) {
694       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
695    }
696    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
697    return false;
698 }
699 
700 bool
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)701 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
702 {
703 #ifdef CONFIG_FB_SIS_315
704    if(SiS_Pr->ChipType >= SIS_315H) {
705       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
706 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
707       }
708    }
709 #endif
710    return false;
711 }
712 
713 bool
SiS_IsVAMode(struct SiS_Private * SiS_Pr)714 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
715 {
716 #ifdef CONFIG_FB_SIS_315
717    unsigned short flag;
718 
719    if(SiS_Pr->ChipType >= SIS_315H) {
720       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
721       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
722    }
723 #endif
724    return false;
725 }
726 
727 #ifdef CONFIG_FB_SIS_315
728 static bool
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)729 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
730 {
731    if(SiS_IsVAMode(SiS_Pr))  return true;
732    if(SiS_CRT2IsLCD(SiS_Pr)) return true;
733    return false;
734 }
735 #endif
736 
737 static bool
SiS_IsDualLink(struct SiS_Private * SiS_Pr)738 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
739 {
740 #ifdef CONFIG_FB_SIS_315
741    if(SiS_Pr->ChipType >= SIS_315H) {
742       if((SiS_CRT2IsLCD(SiS_Pr)) ||
743          (SiS_IsVAMode(SiS_Pr))) {
744 	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
745       }
746    }
747 #endif
748    return false;
749 }
750 
751 #ifdef CONFIG_FB_SIS_315
752 static bool
SiS_TVEnabled(struct SiS_Private * SiS_Pr)753 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
754 {
755    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
756    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
757       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
758    }
759    return false;
760 }
761 #endif
762 
763 #ifdef CONFIG_FB_SIS_315
764 static bool
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)765 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
766 {
767    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
768    return false;
769 }
770 #endif
771 
772 #ifdef CONFIG_FB_SIS_315
773 static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)774 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
775 {
776    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
777       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
778    }
779    return false;
780 }
781 #endif
782 
783 #ifdef CONFIG_FB_SIS_315
784 static bool
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)785 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
786 {
787    unsigned short flag;
788 
789    if(SiS_Pr->ChipType == SIS_650) {
790       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
791       /* Check for revision != A0 only */
792       if((flag == 0xe0) || (flag == 0xc0) ||
793          (flag == 0xb0) || (flag == 0x90)) return false;
794    } else if(SiS_Pr->ChipType >= SIS_661) return false;
795    return true;
796 }
797 #endif
798 
799 #ifdef CONFIG_FB_SIS_315
800 static bool
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)801 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
802 {
803    if(SiS_Pr->ChipType >= SIS_315H) {
804       /* YPrPb = 0x08 */
805       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
806    }
807    return false;
808 }
809 #endif
810 
811 #ifdef CONFIG_FB_SIS_315
812 static bool
SiS_IsChScart(struct SiS_Private * SiS_Pr)813 SiS_IsChScart(struct SiS_Private *SiS_Pr)
814 {
815    if(SiS_Pr->ChipType >= SIS_315H) {
816       /* Scart = 0x04 */
817       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
818    }
819    return false;
820 }
821 #endif
822 
823 #ifdef CONFIG_FB_SIS_315
824 static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)825 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
826 {
827    unsigned short flag;
828 
829    if(SiS_Pr->ChipType >= SIS_315H) {
830       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
831       if(flag & SetCRT2ToTV)        return true;
832       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
833       if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
834       if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
835    } else {
836       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
837       if(flag & SetCRT2ToTV)        return true;
838    }
839    return false;
840 }
841 #endif
842 
843 #ifdef CONFIG_FB_SIS_315
844 static bool
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)845 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
846 {
847    unsigned short flag;
848 
849    if(SiS_Pr->ChipType >= SIS_315H) {
850       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
851       if(flag & SetCRT2ToLCD) return true;
852       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
853       if(flag & SetToLCDA)    return true;
854    } else {
855       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
856       if(flag & SetCRT2ToLCD) return true;
857    }
858    return false;
859 }
860 #endif
861 
862 static bool
SiS_HaveBridge(struct SiS_Private * SiS_Pr)863 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
864 {
865    unsigned short flag;
866 
867    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
868       return true;
869    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
870       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
871       if((flag == 1) || (flag == 2)) return true;
872    }
873    return false;
874 }
875 
876 static bool
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)877 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
878 {
879    unsigned short flag;
880 
881    if(SiS_HaveBridge(SiS_Pr)) {
882       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
883       if(SiS_Pr->ChipType < SIS_315H) {
884 	flag &= 0xa0;
885 	if((flag == 0x80) || (flag == 0x20)) return true;
886       } else {
887 	flag &= 0x50;
888 	if((flag == 0x40) || (flag == 0x10)) return true;
889       }
890    }
891    return false;
892 }
893 
894 static bool
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)895 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
896 {
897    unsigned short flag1;
898 
899    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
900    if(flag1 & (SetInSlaveMode >> 8)) return true;
901    return false;
902 }
903 
904 /*********************************************/
905 /*       GET VIDEO BRIDGE CONFIG INFO        */
906 /*********************************************/
907 
908 /* Setup general purpose IO for Chrontel communication */
909 #ifdef CONFIG_FB_SIS_300
910 void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)911 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
912 {
913    unsigned int   acpibase;
914    unsigned short temp;
915 
916    if(!(SiS_Pr->SiS_ChSW)) return;
917 
918    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
919    acpibase &= 0xFFFF;
920    if(!acpibase) return;
921    temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
922    temp &= 0xFEFF;
923    SiS_SetRegShort((acpibase + 0x3c), temp);
924    temp = SiS_GetRegShort((acpibase + 0x3c));
925    temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
926    temp &= 0xFEFF;
927    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
928    SiS_SetRegShort((acpibase + 0x3a), temp);
929    temp = SiS_GetRegShort((acpibase + 0x3a));
930 }
931 #endif
932 
933 void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)934 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
935 		unsigned short ModeIdIndex, int checkcrt2mode)
936 {
937    unsigned short tempax, tempbx, temp;
938    unsigned short modeflag, resinfo = 0;
939 
940    SiS_Pr->SiS_SetFlag = 0;
941 
942    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
943 
944    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
945 
946    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
947       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
948    }
949 
950    tempbx = 0;
951 
952    if(SiS_HaveBridge(SiS_Pr)) {
953 
954 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
955 	tempbx |= temp;
956 	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
957 	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
958 	tempbx |= tempax;
959 
960 #ifdef CONFIG_FB_SIS_315
961 	if(SiS_Pr->ChipType >= SIS_315H) {
962 	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
963 	      if(ModeNo == 0x03) {
964 		 /* Mode 0x03 is never in driver mode */
965 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
966 	      }
967 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
968 		 /* Reset LCDA setting if not driver mode */
969 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
970 	      }
971 	      if(IS_SIS650) {
972 		 if(SiS_Pr->SiS_UseLCDA) {
973 		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
974 		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
975 			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
976 		       }
977 		    }
978 		 }
979 	      }
980 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
981 	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
982 		 tempbx |= SetCRT2ToLCDA;
983 	      }
984 	   }
985 
986 	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
987 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
988 	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
989 		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
990 		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
991 		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
992 		    tempbx |= SetCRT2ToYPbPr525750;
993 		 }
994 	      }
995 	   }
996 
997 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
998 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
999 	      if(temp & SetToLCDA) {
1000 		 tempbx |= SetCRT2ToLCDA;
1001 	      }
1002 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1003 		 if(temp & EnableCHYPbPr) {
1004 		    tempbx |= SetCRT2ToCHYPbPr;
1005 		 }
1006 	      }
1007 	   }
1008 	}
1009 
1010 #endif  /* CONFIG_FB_SIS_315 */
1011 
1012         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1013 	   tempbx &= ~(SetCRT2ToRAMDAC);
1014 	}
1015 
1016 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1017 	   temp = SetCRT2ToSVIDEO   |
1018 		  SetCRT2ToAVIDEO   |
1019 		  SetCRT2ToSCART    |
1020 		  SetCRT2ToLCDA     |
1021 		  SetCRT2ToLCD      |
1022 		  SetCRT2ToRAMDAC   |
1023 		  SetCRT2ToHiVision |
1024 		  SetCRT2ToYPbPr525750;
1025 	} else {
1026 	   if(SiS_Pr->ChipType >= SIS_315H) {
1027 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1028 		 temp = SetCRT2ToAVIDEO |
1029 		        SetCRT2ToSVIDEO |
1030 		        SetCRT2ToSCART  |
1031 		        SetCRT2ToLCDA   |
1032 		        SetCRT2ToLCD    |
1033 		        SetCRT2ToCHYPbPr;
1034 	      } else {
1035 		 temp = SetCRT2ToLCDA   |
1036 		        SetCRT2ToLCD;
1037 	      }
1038 	   } else {
1039 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040 		 temp = SetCRT2ToTV | SetCRT2ToLCD;
1041 	      } else {
1042 		 temp = SetCRT2ToLCD;
1043 	      }
1044 	   }
1045 	}
1046 
1047 	if(!(tempbx & temp)) {
1048 	   tempax = DisableCRT2Display;
1049 	   tempbx = 0;
1050 	}
1051 
1052 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1053 
1054 	   unsigned short clearmask = ( DriverMode |
1055 				DisableCRT2Display |
1056 				LoadDACFlag 	   |
1057 				SetNotSimuMode 	   |
1058 				SetInSlaveMode 	   |
1059 				SetPALTV 	   |
1060 				SwitchCRT2	   |
1061 				SetSimuScanMode );
1062 
1063 	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1064 	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1065 	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1066 	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1067 	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1068 	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1069 
1070 	} else {
1071 
1072 	   if(SiS_Pr->ChipType >= SIS_315H) {
1073 	      if(tempbx & SetCRT2ToLCDA) {
1074 		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1075 	      }
1076 	   }
1077 	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1078 	      if(tempbx & SetCRT2ToTV) {
1079 		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1080 	      }
1081 	   }
1082 	   if(tempbx & SetCRT2ToLCD) {
1083 	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1084 	   }
1085 	   if(SiS_Pr->ChipType >= SIS_315H) {
1086 	      if(tempbx & SetCRT2ToLCDA) {
1087 	         tempbx |= SetCRT2ToLCD;
1088 	      }
1089 	   }
1090 
1091 	}
1092 
1093 	if(tempax & DisableCRT2Display) {
1094 	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1095 	      tempbx = SetSimuScanMode | DisableCRT2Display;
1096 	   }
1097 	}
1098 
1099 	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1100 
1101 	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1102 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1103 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1104 	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1105 	      modeflag &= (~CRT2Mode);
1106 	   }
1107 	}
1108 
1109 	if(!(tempbx & SetSimuScanMode)) {
1110 	   if(tempbx & SwitchCRT2) {
1111 	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1112 		 if(resinfo != SIS_RI_1600x1200) {
1113 		    tempbx |= SetSimuScanMode;
1114 		 }
1115               }
1116 	   } else {
1117 	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
1118 		 if(!(tempbx & DriverMode)) {
1119 		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1120 		       tempbx |= SetSimuScanMode;
1121 		    }
1122 		 }
1123 	      }
1124 	   }
1125 	}
1126 
1127 	if(!(tempbx & DisableCRT2Display)) {
1128 	   if(tempbx & DriverMode) {
1129 	      if(tempbx & SetSimuScanMode) {
1130 		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1131 		    if(resinfo != SIS_RI_1600x1200) {
1132 		       tempbx |= SetInSlaveMode;
1133 		    }
1134 		 }
1135 	      }
1136 	   } else {
1137 	      tempbx |= SetInSlaveMode;
1138 	   }
1139 	}
1140 
1141    }
1142 
1143    SiS_Pr->SiS_VBInfo = tempbx;
1144 
1145 #ifdef CONFIG_FB_SIS_300
1146    if(SiS_Pr->ChipType == SIS_630) {
1147       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1148    }
1149 #endif
1150 
1151 #if 0
1152    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1153       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1154 #endif
1155 }
1156 
1157 /*********************************************/
1158 /*           DETERMINE YPbPr MODE            */
1159 /*********************************************/
1160 
1161 void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1162 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1163 {
1164 
1165    unsigned char temp;
1166 
1167    /* Note: This variable is only used on 30xLV systems.
1168     * CR38 has a different meaning on LVDS/CH7019 systems.
1169     * On 661 and later, these bits moved to CR35.
1170     *
1171     * On 301, 301B, only HiVision 1080i is supported.
1172     * On 30xLV, 301C, only YPbPr 1080i is supported.
1173     */
1174 
1175    SiS_Pr->SiS_YPbPr = 0;
1176    if(SiS_Pr->ChipType >= SIS_661) return;
1177 
1178    if(SiS_Pr->SiS_VBType) {
1179       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1180 	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1181       }
1182    }
1183 
1184    if(SiS_Pr->ChipType >= SIS_315H) {
1185       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1186 	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1187 	 if(temp & 0x08) {
1188 	    switch((temp >> 4)) {
1189 	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1190 	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1191 	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1192 	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1193 	    }
1194 	 }
1195       }
1196    }
1197 
1198 }
1199 
1200 /*********************************************/
1201 /*           DETERMINE TVMode flag           */
1202 /*********************************************/
1203 
1204 void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1205 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1206 {
1207    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1208    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1209    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1210 
1211    SiS_Pr->SiS_TVMode = 0;
1212 
1213    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1214    if(SiS_Pr->UseCustomMode) return;
1215 
1216    if(ModeNo > 0x13) {
1217       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1218    }
1219 
1220    if(SiS_Pr->ChipType < SIS_661) {
1221 
1222       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1223 
1224       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1225 	 temp = 0;
1226 	 if((SiS_Pr->ChipType == SIS_630) ||
1227 	    (SiS_Pr->ChipType == SIS_730)) {
1228 	    temp = 0x35;
1229 	    romindex = 0xfe;
1230 	 } else if(SiS_Pr->ChipType >= SIS_315H) {
1231 	    temp = 0x38;
1232 	    if(SiS_Pr->ChipType < XGI_20) {
1233 	       romindex = 0xf3;
1234 	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1235 	    }
1236 	 }
1237 	 if(temp) {
1238 	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1239 	       OutputSelect = ROMAddr[romindex];
1240 	       if(!(OutputSelect & EnablePALMN)) {
1241 		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1242 	       }
1243 	    }
1244 	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1245 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1246 	       if(temp1 & EnablePALM) {		/* 0x40 */
1247 		  SiS_Pr->SiS_TVMode |= TVSetPALM;
1248 		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1249 	       } else if(temp1 & EnablePALN) {	/* 0x80 */
1250 		  SiS_Pr->SiS_TVMode |= TVSetPALN;
1251 	       }
1252 	    } else {
1253 	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
1254 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1255 	       }
1256 	    }
1257 	 }
1258 	 /* Translate HiVision/YPbPr to our new flags */
1259 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1260 	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1261 	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1262 	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1263 	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1264 	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1265 	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1266 	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1267 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1268 	       SiS_Pr->SiS_TVMode |= TVSetPAL;
1269 	    }
1270 	 }
1271       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1272 	 if(SiS_Pr->SiS_CHOverScan) {
1273 	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1274 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1275 	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1276 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1277 	       }
1278 	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1279 	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1280 	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1281 		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1282 	       }
1283 	    }
1284 	    if(SiS_Pr->SiS_CHSOverScan) {
1285 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1286 	    }
1287 	 }
1288 	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1289 	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1290 	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1291 	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1292 	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1293 	    } else {
1294 	       if(temp & EnableNTSCJ) {
1295 		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1296 	       }
1297 	    }
1298 	 }
1299       }
1300 
1301    } else {  /* 661 and later */
1302 
1303       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1304       if(temp1 & 0x01) {
1305 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1306 	 if(temp1 & 0x08) {
1307 	    SiS_Pr->SiS_TVMode |= TVSetPALN;
1308 	 } else if(temp1 & 0x04) {
1309 	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1310 	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1311 	    }
1312 	    SiS_Pr->SiS_TVMode |= TVSetPALM;
1313 	 }
1314       } else {
1315 	 if(temp1 & 0x02) {
1316 	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1317 	 }
1318       }
1319       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1320 	 if(SiS_Pr->SiS_CHOverScan) {
1321 	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1322 	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1323 	    }
1324 	 }
1325       }
1326       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1327 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1328 	    temp1 &= 0xe0;
1329 	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1330 	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1331 	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1332 	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1333 	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1334 	 }
1335 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1336 	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1337 	       SiS_Pr->SiS_TVMode |= TVAspect169;
1338 	    } else {
1339 	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1340 	       if(temp1 & 0x02) {
1341 		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1342 		     SiS_Pr->SiS_TVMode |= TVAspect169;
1343 		  } else {
1344 		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1345 		  }
1346 	       } else {
1347 		  SiS_Pr->SiS_TVMode |= TVAspect43;
1348 	       }
1349 	    }
1350 	 }
1351       }
1352    }
1353 
1354    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1355 
1356    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1357 
1358       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1359 	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1360 	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1361       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1362 	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1363 	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1364 	 }
1365       }
1366 
1367       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1368 	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1369 	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1370 	 }
1371       }
1372 
1373       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1374 	 if(resinfo == SIS_RI_1024x768) {
1375 	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1376 	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
1377 	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1378 	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1379 	    }
1380 	 }
1381       }
1382 
1383       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1384       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1385 	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1386 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1387       } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1388 	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1389       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1390 	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1391 	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1392 	 }
1393       }
1394 
1395    }
1396 
1397    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1398 }
1399 
1400 /*********************************************/
1401 /*               GET LCD INFO                */
1402 /*********************************************/
1403 
1404 static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1405 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1406 {
1407    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1408    /* Translate my LCDResInfo to BIOS value */
1409    switch(temp) {
1410    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1411    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1412    case Panel_1280x854:   temp = Panel661_1280x854; break;
1413    }
1414    return temp;
1415 }
1416 
1417 static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1418 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1419 {
1420 #ifdef CONFIG_FB_SIS_315
1421    unsigned char  *ROMAddr;
1422    unsigned short temp;
1423 
1424    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1425       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1426 	 SiS_Pr->SiS_NeedRomModeData = true;
1427 	 SiS_Pr->PanelHT  = temp;
1428       }
1429       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1430 	 SiS_Pr->SiS_NeedRomModeData = true;
1431 	 SiS_Pr->PanelVT  = temp;
1432       }
1433       SiS_Pr->PanelHRS = SISGETROMW(10);
1434       SiS_Pr->PanelHRE = SISGETROMW(12);
1435       SiS_Pr->PanelVRS = SISGETROMW(14);
1436       SiS_Pr->PanelVRE = SISGETROMW(16);
1437       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1438       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1439 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1440       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1441 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1442       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1443 	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1444 
1445    }
1446 #endif
1447 }
1448 
1449 static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1450 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1451 			const unsigned char *nonscalingmodes)
1452 {
1453    int i = 0;
1454    while(nonscalingmodes[i] != 0xff) {
1455       if(nonscalingmodes[i++] == resinfo) {
1456 	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1457 	    (SiS_Pr->UsePanelScaler == -1)) {
1458 	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1459 	 }
1460 	 break;
1461       }
1462    }
1463 }
1464 
1465 void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1466 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1467 {
1468   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1469   bool panelcanscale = false;
1470 #ifdef CONFIG_FB_SIS_300
1471   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1472   static const unsigned char SiS300SeriesLCDRes[] =
1473           { 0,  1,  2,  3,  7,  4,  5,  8,
1474 	    0,  0, 10,  0,  0,  0,  0, 15 };
1475 #endif
1476 #ifdef CONFIG_FB_SIS_315
1477   unsigned char   *myptr = NULL;
1478 #endif
1479 
1480   SiS_Pr->SiS_LCDResInfo  = 0;
1481   SiS_Pr->SiS_LCDTypeInfo = 0;
1482   SiS_Pr->SiS_LCDInfo     = 0;
1483   SiS_Pr->PanelHRS        = 999; /* HSync start */
1484   SiS_Pr->PanelHRE        = 999; /* HSync end */
1485   SiS_Pr->PanelVRS        = 999; /* VSync start */
1486   SiS_Pr->PanelVRE        = 999; /* VSync end */
1487   SiS_Pr->SiS_NeedRomModeData = false;
1488 
1489   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1490   SiS_Pr->Alternate1600x1200 = false;
1491 
1492   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1493 
1494   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1495 
1496   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1497      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1498      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1499      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1500   }
1501 
1502   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1503 
1504   /* For broken BIOSes: Assume 1024x768 */
1505   if(temp == 0) temp = 0x02;
1506 
1507   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1508      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1509   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1510      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1511   } else {
1512      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1513   }
1514   temp &= 0x0f;
1515 #ifdef CONFIG_FB_SIS_300
1516   if(SiS_Pr->ChipType < SIS_315H) {
1517      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1518      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1519         if(temp < 0x0f) temp &= 0x07;
1520      }
1521      /* Translate 300 series LCDRes to 315 series for unified usage */
1522      temp = SiS300SeriesLCDRes[temp];
1523   }
1524 #endif
1525 
1526   /* Translate to our internal types */
1527 #ifdef CONFIG_FB_SIS_315
1528   if(SiS_Pr->ChipType == SIS_550) {
1529      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1530      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1531      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1532   } else if(SiS_Pr->ChipType >= SIS_661) {
1533      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1534   }
1535 #endif
1536 
1537   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
1538      if(temp == Panel310_1280x768) {
1539         temp = Panel_1280x768_2;
1540      }
1541      if(SiS_Pr->SiS_ROMNew) {
1542 	if(temp == Panel661_1280x800) {
1543 	   temp = Panel_1280x800_2;
1544 	}
1545      }
1546   }
1547 
1548   SiS_Pr->SiS_LCDResInfo = temp;
1549 
1550 #ifdef CONFIG_FB_SIS_300
1551   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1552      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1553 	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1554      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1555 	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1556      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1557 	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1558      }
1559   }
1560 #endif
1561 
1562   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1563      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1564 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1565   } else {
1566      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1567 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1568   }
1569 
1570   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1571   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1572   /* Need temp below! */
1573 
1574   /* These must/can't scale no matter what */
1575   switch(SiS_Pr->SiS_LCDResInfo) {
1576   case Panel_320x240_1:
1577   case Panel_320x240_2:
1578   case Panel_320x240_3:
1579   case Panel_1280x960:
1580       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1581       break;
1582   case Panel_640x480:
1583       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1584   }
1585 
1586   panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1587 
1588   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1589   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1590 
1591   /* Dual link, Pass 1:1 BIOS default, etc. */
1592 #ifdef CONFIG_FB_SIS_315
1593   if(SiS_Pr->ChipType >= SIS_661) {
1594      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1595 	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1596      }
1597      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1598 	if(SiS_Pr->SiS_ROMNew) {
1599 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1600 	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1601 	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1602 	}
1603      }
1604   } else if(SiS_Pr->ChipType >= SIS_315H) {
1605      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1606 	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1607      }
1608      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1609 	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1610 	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1611 	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1612 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1613 	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1614 	}
1615      } else if(!(SiS_Pr->SiS_ROMNew)) {
1616 	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1617 	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1618 	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1619 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1620 	   }
1621 	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1622 	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1623 	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1624 	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1625 	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1626 	   }
1627 	}
1628      }
1629   }
1630 #endif
1631 
1632   /* Pass 1:1 */
1633   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1634      /* Always center screen on LVDS (if scaling is disabled) */
1635      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1636   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1637      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1638 	/* Always center screen on SiS LVDS (if scaling is disabled) */
1639 	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1640      } else {
1641 	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1642 	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1643 	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1644      }
1645   }
1646 
1647   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1648   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1649 
1650   switch(SiS_Pr->SiS_LCDResInfo) {
1651      case Panel_320x240_1:
1652      case Panel_320x240_2:
1653      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1654 			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1655 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1656 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1657 			    break;
1658      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1659 						      SiS_Pr->PanelVRE  =    3;
1660 			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1661 			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1662 			    break;
1663      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1664      			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1665 			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1666 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1667 			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1668 			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1669 			    break;
1670      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1671 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1672 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1673 			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1674 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1675 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1676 			    break;
1677      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1678 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1679 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1680 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1681 			    if(SiS_Pr->ChipType < SIS_315H) {
1682 			       SiS_Pr->PanelHRS = 23;
1683 						      SiS_Pr->PanelVRE  =    5;
1684 			    }
1685 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1686 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1687 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1688 			    break;
1689      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
1690 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1691 			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1692 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1693 			    if(SiS_Pr->ChipType < SIS_315H) {
1694 			       SiS_Pr->PanelHRS = 23;
1695 						      SiS_Pr->PanelVRE  =    5;
1696 			    }
1697 			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698 			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1699 			    break;
1700      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
1701 			    break;
1702      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
1703 			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
1704 			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
1705 			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
1706 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1707 			    /* Data above for TMDS (projector); get from BIOS for LVDS */
1708 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1709 			    break;
1710      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1711 			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1712 			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
1713 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1714 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1715 			    } else {
1716 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
1717 			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
1718 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1719 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1720 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1721 			    }
1722 			    break;
1723      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
1724 			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
1725 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1726 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1727 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1728 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1729 			    break;
1730      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1731 			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
1732 			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
1733 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1734 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1735 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1736 			    break;
1737      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
1738 			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
1739 			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
1740 			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
1741 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1742 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1743 			    break;
1744      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
1745 			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
1746 			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
1747 			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
1748 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1749 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1750 			    break;
1751      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
1752 			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
1753 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1754 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1755 			    if(resinfo == SIS_RI_1280x1024) {
1756 			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1757 			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1758 			    }
1759 			    break;
1760      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1761 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1762 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1763 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1764 			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1765 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1766 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1767 			    break;
1768      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1769 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1770 			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
1771 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1772 			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1773 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1774 			    break;
1775      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1776 			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
1777 			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
1778 			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
1779 			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1780 			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1781 			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1782 				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
1783 				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
1784 				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
1785 				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1786 				  SiS_Pr->Alternate1600x1200 = true;
1787 			       }
1788 			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1789 			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
1790 			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1791 			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1792 			    }
1793 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1794 			    break;
1795      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1796 			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
1797 			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
1798 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
1799 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1800 			    SiS_GetLCDInfoBIOS(SiS_Pr);
1801 			    break;
1802      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1803 			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
1804 			    break;
1805      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
1806 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1807 			    break;
1808      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
1809 			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
1810 			    break;
1811      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1812 			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1813 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
1814 			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
1815 			    if(SiS_Pr->CP_PreferredIndex != -1) {
1816 			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1817 			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1818 			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1819 			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1820 			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1821 			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1822 			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1823 			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1824 			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1825 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1826 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1827 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1828 			       if(SiS_Pr->CP_PrefClock) {
1829 				  int idx;
1830 				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1831 				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1832 				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1833 				  else				   idx = VCLK_CUSTOM_315;
1834 				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
1835 				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1836 				  SiS_Pr->SiS_VCLKData[idx].SR2B =
1837 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1838 				  SiS_Pr->SiS_VCLKData[idx].SR2C =
1839 				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1840 			       }
1841 			    }
1842 			    break;
1843      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
1844 			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
1845 			    break;
1846   }
1847 
1848   /* Special cases */
1849   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
1850       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
1851       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1852       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1853       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1854       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1855      SiS_Pr->PanelHRS = 999;
1856      SiS_Pr->PanelHRE = 999;
1857   }
1858 
1859   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1860       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1861       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
1862       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1863      SiS_Pr->PanelVRS = 999;
1864      SiS_Pr->PanelVRE = 999;
1865   }
1866 
1867   /* DontExpand overrule */
1868   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1869 
1870      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1871 	/* No scaling for this mode on any panel (LCD=CRT2)*/
1872 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1873      }
1874 
1875      switch(SiS_Pr->SiS_LCDResInfo) {
1876 
1877      case Panel_Custom:
1878      case Panel_1152x864:
1879      case Panel_1280x768:	/* TMDS only */
1880 	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1881 	break;
1882 
1883      case Panel_800x600: {
1884 	static const unsigned char nonscalingmodes[] = {
1885 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1886 	};
1887 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1888 	break;
1889      }
1890      case Panel_1024x768: {
1891 	static const unsigned char nonscalingmodes[] = {
1892 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1893 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1894 	   0xff
1895 	};
1896 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1897 	break;
1898      }
1899      case Panel_1280x720: {
1900 	static const unsigned char nonscalingmodes[] = {
1901 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1902 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1903 	   0xff
1904 	};
1905 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1906 	if(SiS_Pr->PanelHT == 1650) {
1907 	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1908 	}
1909 	break;
1910      }
1911      case Panel_1280x768_2: {  /* LVDS only */
1912 	static const unsigned char nonscalingmodes[] = {
1913 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1914 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1915 	   SIS_RI_1152x768,0xff
1916 	};
1917 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1918 	switch(resinfo) {
1919 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
1920 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1921 			       }
1922 			       break;
1923 	}
1924 	break;
1925      }
1926      case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
1927 	static const unsigned char nonscalingmodes[] = {
1928 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1929 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1930 	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1931 	};
1932 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1933 	break;
1934      }
1935      case Panel_1280x800_2:  { 	/* SiS LVDS */
1936 	static const unsigned char nonscalingmodes[] = {
1937 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1938 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1939 	   SIS_RI_1152x768,0xff
1940 	};
1941 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1942 	switch(resinfo) {
1943 	case SIS_RI_1280x720:
1944 	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
1945 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1946 			       }
1947 			       break;
1948 	}
1949 	break;
1950      }
1951      case Panel_1280x854: {  	/* SiS LVDS */
1952 	static const unsigned char nonscalingmodes[] = {
1953 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1954 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1955 	   SIS_RI_1152x768,0xff
1956 	};
1957 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1958 	switch(resinfo) {
1959 	case SIS_RI_1280x720:
1960 	case SIS_RI_1280x768:
1961 	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
1962 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1963 			       }
1964 			       break;
1965 	}
1966 	break;
1967      }
1968      case Panel_1280x960: {
1969 	static const unsigned char nonscalingmodes[] = {
1970 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1971 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1972 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1973 	   SIS_RI_1280x854,0xff
1974 	};
1975 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976 	break;
1977      }
1978      case Panel_1280x1024: {
1979 	static const unsigned char nonscalingmodes[] = {
1980 	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1981 	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1982 	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1983 	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
1984 	};
1985 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1986 	break;
1987      }
1988      case Panel_1400x1050: {
1989 	static const unsigned char nonscalingmodes[] = {
1990 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1991 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1992 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
1993 	     SIS_RI_1280x960,0xff
1994 	};
1995 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1996 	switch(resinfo) {
1997 	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
1998 				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1999 			       }
2000 			       break;
2001 	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2002 			       break;
2003 	}
2004 	break;
2005      }
2006      case Panel_1600x1200: {
2007 	static const unsigned char nonscalingmodes[] = {
2008 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2009 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2010 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2011 	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2012 	};
2013 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 	break;
2015      }
2016      case Panel_1680x1050: {
2017 	static const unsigned char nonscalingmodes[] = {
2018 	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2019 	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2020 	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2021 	     SIS_RI_1360x1024,0xff
2022 	};
2023 	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2024 	break;
2025      }
2026      }
2027   }
2028 
2029 #ifdef CONFIG_FB_SIS_300
2030   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2031      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2032 	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2033      }
2034   }
2035 
2036   if(SiS_Pr->ChipType < SIS_315H) {
2037      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2038 	if(SiS_Pr->SiS_UseROM) {
2039 	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2040 	      if(!(ROMAddr[0x235] & 0x02)) {
2041 		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2042 	      }
2043 	   }
2044 	}
2045      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2046 	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2047 	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2048 	}
2049      }
2050   }
2051 #endif
2052 
2053   /* Special cases */
2054 
2055   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2056      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2057   }
2058 
2059   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2060      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2061   }
2062 
2063   switch(SiS_Pr->SiS_LCDResInfo) {
2064   case Panel_640x480:
2065      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2066      break;
2067   case Panel_1280x800:
2068      /* Don't pass 1:1 by default (TMDS special) */
2069      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2070      break;
2071   case Panel_1280x960:
2072      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2073      break;
2074   case Panel_Custom:
2075      if((!SiS_Pr->CP_PrefClock) ||
2076         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2077         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2078      }
2079      break;
2080   }
2081 
2082   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2083      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2084   }
2085 
2086   /* (In)validate LCDPass11 flag */
2087   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2088      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2089   }
2090 
2091   /* LVDS DDA */
2092   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2093 
2094      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2095 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2096 	   if(ModeNo == 0x12) {
2097 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2098 		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2099 	      }
2100 	   } else if(ModeNo > 0x13) {
2101 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2102 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2103 		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2104 		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2105 		    }
2106 		 }
2107 	      }
2108 	   }
2109 	}
2110      }
2111 
2112      if(modeflag & HalfDCLK) {
2113 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2114 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2115 	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2116 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2118 	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2119 	} else if(ModeNo > 0x13) {
2120 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2121 	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2122 	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2123 	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2124 	   }
2125 	}
2126      }
2127 
2128   }
2129 
2130   /* VESA timing */
2131   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2132      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2133 	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2134      }
2135   } else {
2136      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2137   }
2138 
2139 #if 0
2140   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2141 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2142 #endif
2143 }
2144 
2145 /*********************************************/
2146 /*                 GET VCLK                  */
2147 /*********************************************/
2148 
2149 unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2150 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2151 		unsigned short RefreshRateTableIndex)
2152 {
2153   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2154   unsigned short modeflag, resinfo, tempbx;
2155   const unsigned char *CHTVVCLKPtr = NULL;
2156 
2157   if(ModeNo <= 0x13) {
2158      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2159      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2160      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2161      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2162      VCLKIndexGENCRT = VCLKIndexGEN;
2163   } else {
2164      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2165      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2166      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2167      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2168      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2169 		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2170   }
2171 
2172   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2173 
2174      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2175 
2176 	CRT2Index >>= 6;
2177 	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2178 
2179 	   if(SiS_Pr->ChipType < SIS_315H) {
2180 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2181 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2182 		 VCLKIndex = VCLKIndexGEN;
2183 	      }
2184 	   } else {
2185 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2186 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2187 		 switch(resinfo) {
2188 		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2189 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2190 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2191 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2192 		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2193 		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2194 		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2195 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2196 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2197 		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2198 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2199 		 default:              VCLKIndex = VCLKIndexGEN;
2200 		 }
2201 
2202 		 if(ModeNo <= 0x13) {
2203 		    if(SiS_Pr->ChipType <= SIS_315PRO) {
2204 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2205 		    } else {
2206 		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2207 		    }
2208 		 }
2209 		 if(SiS_Pr->ChipType <= SIS_315PRO) {
2210 		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2211 		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2212 		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2213 		 }
2214 	      }
2215 	   }
2216 
2217 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2218 
2219 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2220 	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
2221 	      else                                  	   VCLKIndex = HiTVVCLK;
2222 	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2223 	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2224 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2225 	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2226 	   else						   VCLKIndex = TVVCLK;
2227 
2228 	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2229 	   else				   VCLKIndex += TVCLKBASE_315;
2230 
2231 	} else {							/* VGA2 */
2232 
2233 	   VCLKIndex = VCLKIndexGENCRT;
2234 	   if(SiS_Pr->ChipType < SIS_315H) {
2235 	      if(ModeNo > 0x13) {
2236 		 if( (SiS_Pr->ChipType == SIS_630) &&
2237 		     (SiS_Pr->ChipRevision >= 0x30)) {
2238 		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2239 		 }
2240 		 /* Better VGA2 clock for 1280x1024@75 */
2241 		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2242 	      }
2243 	   }
2244 	}
2245 
2246      } else {   /* If not programming CRT2 */
2247 
2248 	VCLKIndex = VCLKIndexGENCRT;
2249 	if(SiS_Pr->ChipType < SIS_315H) {
2250 	   if(ModeNo > 0x13) {
2251 	      if( (SiS_Pr->ChipType != SIS_630) &&
2252 		  (SiS_Pr->ChipType != SIS_300) ) {
2253 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2254 	      }
2255 	   }
2256 	}
2257      }
2258 
2259   } else {       /*   LVDS  */
2260 
2261      VCLKIndex = CRT2Index;
2262 
2263      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2264 
2265 	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2266 
2267 	   VCLKIndex &= 0x1f;
2268 	   tempbx = 0;
2269 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2270 	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2271 	      tempbx += 2;
2272 	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2273 		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2274 	      }
2275 	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2276 		 tempbx = 4;
2277 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2278 	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2279 		 tempbx = 6;
2280 		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2281 	      }
2282 	   }
2283 	   switch(tempbx) {
2284 	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2285 	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2286 	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2287 	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2288 	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2289 	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2290 	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2291 	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2292 	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2293 	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2294 	   }
2295 	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2296 
2297 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2298 
2299 	   if(SiS_Pr->ChipType < SIS_315H) {
2300 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2301 	   } else {
2302 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2303 	   }
2304 
2305 #ifdef CONFIG_FB_SIS_300
2306 	   /* Special Timing: Barco iQ Pro R series */
2307 	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2308 
2309 	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2310 	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2311 	      if(SiS_Pr->ChipType < SIS_315H) {
2312 		 VCLKIndex = VCLK34_300;
2313 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2314 	      } else {
2315 		 VCLKIndex = VCLK34_315;
2316 		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2317 	      }
2318 	   }
2319 #endif
2320 
2321 	} else {
2322 
2323 	   VCLKIndex = VCLKIndexGENCRT;
2324 	   if(SiS_Pr->ChipType < SIS_315H) {
2325 	      if(ModeNo > 0x13) {
2326 		 if( (SiS_Pr->ChipType == SIS_630) &&
2327 		     (SiS_Pr->ChipRevision >= 0x30) ) {
2328 		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2329 		 }
2330 	      }
2331 	   }
2332 	}
2333 
2334      } else {  /* if not programming CRT2 */
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->ChipType != SIS_300) ) {
2341 		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2342 	      }
2343 #if 0
2344 	      if(SiS_Pr->ChipType == SIS_730) {
2345 		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2346 		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2347 	      }
2348 #endif
2349 	   }
2350         }
2351 
2352      }
2353 
2354   }
2355 
2356   return VCLKIndex;
2357 }
2358 
2359 /*********************************************/
2360 /*        SET CRT2 MODE TYPE REGISTERS       */
2361 /*********************************************/
2362 
2363 static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2364 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2365 {
2366   unsigned short i, j, modeflag, tempah=0;
2367   short tempcl;
2368 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2369   unsigned short tempbl;
2370 #endif
2371 #ifdef CONFIG_FB_SIS_315
2372   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2373   unsigned short tempah2, tempbl2;
2374 #endif
2375 
2376   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2377 
2378   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2379 
2380      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2381      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2382 
2383   } else {
2384 
2385      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2386      if(SiS_Pr->ChipType >= SIS_315H) {
2387         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2388      }
2389 
2390      tempcl = SiS_Pr->SiS_ModeType;
2391 
2392      if(SiS_Pr->ChipType < SIS_315H) {
2393 
2394 #ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
2395 
2396 	/* For 301BDH: (with LCD via LVDS) */
2397 	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2398 	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2399 	   tempbl &= 0xef;
2400 	   tempbl |= 0x02;
2401 	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2402 	      tempbl |= 0x10;
2403 	      tempbl &= 0xfd;
2404 	   }
2405 	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2406 	}
2407 
2408 	if(ModeNo > 0x13) {
2409 	   tempcl -= ModeVGA;
2410 	   if(tempcl >= 0) {
2411 	      tempah = ((0x10 >> tempcl) | 0x80);
2412 	   }
2413 	} else tempah = 0x80;
2414 
2415 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2416 
2417 #endif  /* CONFIG_FB_SIS_300 */
2418 
2419      } else {
2420 
2421 #ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
2422 
2423 	if(ModeNo > 0x13) {
2424 	   tempcl -= ModeVGA;
2425 	   if(tempcl >= 0) {
2426 	      tempah = (0x08 >> tempcl);
2427 	      if (tempah == 0) tempah = 1;
2428 	      tempah |= 0x40;
2429 	   }
2430 	} else tempah = 0x40;
2431 
2432 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2433 
2434 #endif  /* CONFIG_FB_SIS_315 */
2435 
2436      }
2437 
2438      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2439 
2440      if(SiS_Pr->ChipType < SIS_315H) {
2441 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2442      } else {
2443 #ifdef CONFIG_FB_SIS_315
2444 	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2445 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2446 	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2447 	   if(IS_SIS740) {
2448 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2449 	   } else {
2450 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2451 	   }
2452 	}
2453 #endif
2454      }
2455 
2456      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2457 
2458 	tempah = 0x01;
2459 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2460 	   tempah |= 0x02;
2461 	}
2462 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2463 	   tempah ^= 0x05;
2464 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2465 	      tempah ^= 0x01;
2466 	   }
2467 	}
2468 
2469 	if(SiS_Pr->ChipType < SIS_315H) {
2470 
2471 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2472 
2473 	   tempah = (tempah << 5) & 0xFF;
2474 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2475 	   tempah = (tempah >> 5) & 0xFF;
2476 
2477 	} else {
2478 
2479 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2480 	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2481 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2482 	   tempah &= ~0x08;
2483 
2484 	}
2485 
2486 	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2487 	   tempah |= 0x10;
2488 	}
2489 
2490 	tempah |= 0x80;
2491 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2492 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2493 	}
2494 
2495 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2496 	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2497 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2498 		 tempah |= 0x20;
2499 	      }
2500 	   }
2501 	}
2502 
2503 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2504 
2505 	tempah = 0x80;
2506 	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2507 	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2508 	}
2509 
2510 	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2511 
2512 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2513 	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2514 	      tempah |= 0x40;
2515 	   }
2516 	}
2517 
2518 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2519 
2520      } else {  /* LVDS */
2521 
2522 	if(SiS_Pr->ChipType >= SIS_315H) {
2523 
2524 #ifdef CONFIG_FB_SIS_315
2525 	   /* LVDS can only be slave in 8bpp modes */
2526 	   tempah = 0x80;
2527 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2528 	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2529 	         tempah |= 0x02;
2530 	      }
2531 	   }
2532 
2533 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2534 
2535 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2536 
2537 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2538 
2539 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2540 #endif
2541 
2542 	} else {
2543 
2544 #ifdef CONFIG_FB_SIS_300
2545 	   tempah = 0;
2546 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2547 	      tempah |= 0x02;
2548 	   }
2549 	   tempah <<= 5;
2550 
2551 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2552 
2553 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2554 #endif
2555 
2556 	}
2557 
2558      }
2559 
2560   }  /* LCDA */
2561 
2562   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2563 
2564      if(SiS_Pr->ChipType >= SIS_315H) {
2565 
2566 #ifdef CONFIG_FB_SIS_315
2567 	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2568 
2569 	/* The following is nearly unpreditable and varies from machine
2570 	 * to machine. Especially the 301DH seems to be a real trouble
2571 	 * maker. Some BIOSes simply set the registers (like in the
2572 	 * NoLCD-if-statements here), some set them according to the
2573 	 * LCDA stuff. It is very likely that some machines are not
2574 	 * treated correctly in the following, very case-orientated
2575 	 * code. What do I do then...?
2576 	 */
2577 
2578 	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2579 
2580 	if(!(IS_SIS740)) {
2581 	   tempah = 0x04;						   /* For all bridges */
2582 	   tempbl = 0xfb;
2583 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2584 	      tempah = 0x00;
2585 	      if(SiS_IsDualEdge(SiS_Pr)) {
2586 	         tempbl = 0xff;
2587 	      }
2588 	   }
2589 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2590 	}
2591 
2592 	/* The following two are responsible for eventually wrong colors
2593 	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2594 	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2595 	 * in a 650 box (Jake). What is the criteria?
2596 	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2597 	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2598 	 * chipset than the bridge revision.
2599 	 */
2600 
2601 	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2602 	   tempah = 0x30;
2603 	   tempbl = 0xc0;
2604 	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2605 	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2606 	      tempah = 0x00;
2607 	      tempbl = 0x00;
2608 	   }
2609 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2610 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2611 	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2612 	   /* Fixes "TV-blue-bug" on 315+301 */
2613 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
2614 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2615 	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2616 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
2617 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2618 	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
2619 	   tempah = 0x30; tempah2 = 0xc0;
2620 	   tempbl = 0xcf; tempbl2 = 0x3f;
2621 	   if(SiS_Pr->SiS_TVBlue == 0) {
2622 	         tempah = tempah2 = 0x00;
2623 	   } else if(SiS_Pr->SiS_TVBlue == -1) {
2624 	      /* Set on 651/M650, clear on 315/650 */
2625 	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2626 	         tempah = tempah2 = 0x00;
2627 	      }
2628 	   }
2629 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2630 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2631 	} else {
2632 	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
2633 	   tempbl = 0xcf; tempbl2 = 0x3f;
2634 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2635 	      tempah = tempah2 = 0x00;
2636 	      if(SiS_IsDualEdge(SiS_Pr)) {
2637 		 tempbl = tempbl2 = 0xff;
2638 	      }
2639 	   }
2640 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2641 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2642 	}
2643 
2644 	if(IS_SIS740) {
2645 	   tempah = 0x80;
2646 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2647 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2648 	} else {
2649 	   tempah = 0x00;
2650 	   tempbl = 0x7f;
2651 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2652 	      tempbl = 0xff;
2653 	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2654 	   }
2655 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2656 	}
2657 
2658 #endif /* CONFIG_FB_SIS_315 */
2659 
2660      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2661 
2662 #ifdef CONFIG_FB_SIS_300
2663 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2664 
2665 	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2666 	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2667 	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2668 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2669 	} else {
2670 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2671 	}
2672 #endif
2673 
2674      }
2675 
2676      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2677 	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2678 	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2679 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2680         }
2681      }
2682 
2683   } else {  /* LVDS */
2684 
2685 #ifdef CONFIG_FB_SIS_315
2686      if(SiS_Pr->ChipType >= SIS_315H) {
2687 
2688 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2689 
2690 	   tempah = 0x04;
2691 	   tempbl = 0xfb;
2692 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2693 	      tempah = 0x00;
2694 	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2695 	   }
2696 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2697 
2698 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2699 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2700 	   }
2701 
2702 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2703 
2704 	} else if(SiS_Pr->ChipType == SIS_550) {
2705 
2706 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2707 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2708 
2709 	}
2710 
2711      }
2712 #endif
2713 
2714   }
2715 
2716 }
2717 
2718 /*********************************************/
2719 /*            GET RESOLUTION DATA            */
2720 /*********************************************/
2721 
2722 unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2723 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2724 {
2725    if(ModeNo <= 0x13)
2726       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2727    else
2728       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2729 }
2730 
2731 static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2732 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2733 {
2734    unsigned short xres, yres, modeflag=0, resindex;
2735 
2736    if(SiS_Pr->UseCustomMode) {
2737       xres = SiS_Pr->CHDisplay;
2738       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2739       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2740       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2741       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2742       return;
2743    }
2744 
2745    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2746 
2747    if(ModeNo <= 0x13) {
2748       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2749       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2750    } else {
2751       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2752       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2753       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2754    }
2755 
2756    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2757 
2758       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2759 	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2760 	    if(yres == 350) yres = 400;
2761 	 }
2762 	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2763 	    if(ModeNo == 0x12) yres = 400;
2764 	 }
2765       }
2766 
2767       if(modeflag & HalfDCLK)       xres <<= 1;
2768       if(modeflag & DoubleScanMode) yres <<= 1;
2769 
2770    }
2771 
2772    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2773 
2774       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2775 	 switch(SiS_Pr->SiS_LCDResInfo) {
2776 	   case Panel_1024x768:
2777 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2778 		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2779 		    if(yres == 350) yres = 357;
2780 		    if(yres == 400) yres = 420;
2781 		    if(yres == 480) yres = 525;
2782 		 }
2783 	      }
2784 	      break;
2785 	   case Panel_1280x1024:
2786 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2787 		 /* BIOS bug - does this regardless of scaling */
2788 		 if(yres == 400) yres = 405;
2789 	      }
2790 	      if(yres == 350) yres = 360;
2791 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2792 		 if(yres == 360) yres = 375;
2793 	      }
2794 	      break;
2795 	   case Panel_1600x1200:
2796 	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2797 		 if(yres == 1024) yres = 1056;
2798 	      }
2799 	      break;
2800 	 }
2801       }
2802 
2803    } else {
2804 
2805       if(SiS_Pr->SiS_VBType & VB_SISVB) {
2806 	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2807 	    if(xres == 720) xres = 640;
2808 	 }
2809       } else if(xres == 720) xres = 640;
2810 
2811       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2812 	 yres = 400;
2813 	 if(SiS_Pr->ChipType >= SIS_315H) {
2814 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2815 	 } else {
2816 	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2817 	 }
2818 	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2819       }
2820 
2821    }
2822    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2823    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2824 }
2825 
2826 /*********************************************/
2827 /*           GET CRT2 TIMING DATA            */
2828 /*********************************************/
2829 
2830 static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)2831 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2832 	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2833 	       unsigned short *ResIndex)
2834 {
2835   unsigned short tempbx=0, tempal=0, resinfo=0;
2836 
2837   if(ModeNo <= 0x13) {
2838      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2839   } else {
2840      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2841      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2842   }
2843 
2844   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2845 
2846      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
2847 
2848 	tempbx = SiS_Pr->SiS_LCDResInfo;
2849 	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2850 
2851 	/* patch index */
2852 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2853 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
2854 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2855 	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2856 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2857 		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2858 	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
2859 	}
2860 
2861 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2862 	   /* Pass 1:1 only (center-screen handled outside) */
2863 	   /* This is never called for the panel's native resolution */
2864 	   /* since Pass1:1 will not be set in this case */
2865 	   tempbx = 100;
2866 	   if(ModeNo >= 0x13) {
2867 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2868 	   }
2869 	}
2870 
2871 #ifdef CONFIG_FB_SIS_315
2872 	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2873 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2874 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2875 		 tempbx = 200;
2876 		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2877 	      }
2878 	   }
2879 	}
2880 #endif
2881 
2882      } else {						  	/* TV */
2883 
2884 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2885 	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2886 	   tempbx = 2;
2887 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2888 	      tempbx = 13;
2889 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2890 	   }
2891 	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2892 	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
2893 	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
2894 	   else						tempbx = 5;
2895 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
2896 	} else {
2897 	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
2898 	   else						tempbx = 4;
2899 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
2900 	}
2901 
2902      }
2903 
2904      tempal &= 0x3F;
2905 
2906      if(ModeNo > 0x13) {
2907         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2908 	   switch(resinfo) {
2909 	   case SIS_RI_720x480:
2910 	      tempal = 6;
2911 	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
2912 	      break;
2913 	   case SIS_RI_720x576:
2914 	   case SIS_RI_768x576:
2915 	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2916 	      tempal = 6;
2917 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2918 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
2919 	      }
2920 	      break;
2921 	   case SIS_RI_800x480:
2922 	      tempal = 4;
2923 	      break;
2924 	   case SIS_RI_512x384:
2925 	   case SIS_RI_1024x768:
2926 	      tempal = 7;
2927 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2928 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
2929 	      }
2930 	      break;
2931 	   case SIS_RI_1280x720:
2932 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2933 		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
2934 	      }
2935 	      break;
2936 	   }
2937 	}
2938      }
2939 
2940      *CRT2Index = tempbx;
2941      *ResIndex = tempal;
2942 
2943   } else {   /* LVDS, 301B-DH (if running on LCD) */
2944 
2945      tempbx = 0;
2946      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2947 
2948 	tempbx = 90;
2949 	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2950 	   tempbx = 92;
2951 	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
2952 	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2953 	   }
2954 	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
2955 	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2956 	}
2957 	if(tempbx != 99) {
2958 	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2959 	}
2960 
2961      } else {
2962 
2963 	switch(SiS_Pr->SiS_LCDResInfo) {
2964 	case Panel_640x480:   tempbx = 12; break;
2965 	case Panel_320x240_1: tempbx = 10; break;
2966 	case Panel_320x240_2:
2967 	case Panel_320x240_3: tempbx = 14; break;
2968 	case Panel_800x600:   tempbx = 16; break;
2969 	case Panel_1024x600:  tempbx = 18; break;
2970 	case Panel_1152x768:
2971 	case Panel_1024x768:  tempbx = 20; break;
2972 	case Panel_1280x768:  tempbx = 22; break;
2973 	case Panel_1280x1024: tempbx = 24; break;
2974 	case Panel_1400x1050: tempbx = 26; break;
2975 	case Panel_1600x1200: tempbx = 28; break;
2976 #ifdef CONFIG_FB_SIS_300
2977 	case Panel_Barco1366: tempbx = 80; break;
2978 #endif
2979 	}
2980 
2981 	switch(SiS_Pr->SiS_LCDResInfo) {
2982 	case Panel_320x240_1:
2983 	case Panel_320x240_2:
2984 	case Panel_320x240_3:
2985 	case Panel_640x480:
2986 	   break;
2987 	default:
2988 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2989 	}
2990 
2991 	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
2992 
2993 #ifdef CONFIG_FB_SIS_300
2994 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2995 	   tempbx = 82;
2996 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2997 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2998 	   tempbx = 84;
2999 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3000 	}
3001 #endif
3002 
3003      }
3004 
3005      (*CRT2Index) = tempbx;
3006      (*ResIndex) = tempal & 0x1F;
3007   }
3008 }
3009 
3010 static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3011 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3012 		unsigned short RefreshRateTableIndex)
3013 {
3014   unsigned short tempax=0, tempbx=0, index, dotclock;
3015   unsigned short temp1=0, modeflag=0, tempcx=0;
3016 
3017   SiS_Pr->SiS_RVBHCMAX  = 1;
3018   SiS_Pr->SiS_RVBHCFACT = 1;
3019 
3020   if(ModeNo <= 0x13) {
3021 
3022      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3023      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3024 
3025      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3026      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3027      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3028 
3029      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3030 
3031   } else {
3032 
3033      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3034      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3035 
3036      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3037      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3038      tempax &= 0x03FF;
3039      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3040      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3041      tempcx &= 0x0100;
3042      tempcx <<= 2;
3043      tempbx |= tempcx;
3044      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3045 
3046      dotclock = 8;
3047 
3048   }
3049 
3050   if(temp1 & 0x01) tempbx |= 0x0100;
3051   if(temp1 & 0x20) tempbx |= 0x0200;
3052 
3053   tempax += 5;
3054   tempax *= dotclock;
3055   if(modeflag & HalfDCLK) tempax <<= 1;
3056 
3057   tempbx++;
3058 
3059   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3060   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3061 }
3062 
3063 static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3064 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3065 		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3066 {
3067    unsigned short ResIndex;
3068 
3069    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3070       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3071 	 if(SiS_Pr->UseCustomMode) {
3072 	    ResIndex = SiS_Pr->CHTotal;
3073 	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3074 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3075 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3076 	 } else {
3077 	    if(ModeNo < 0x13) {
3078 	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3079 	    } else {
3080 	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3081 	    }
3082 	    if(ResIndex == 0x09) {
3083 	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3084 	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3085 	    }
3086 	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3087 	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3088 	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3089 	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3090 	 }
3091       } else {
3092 	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3093 	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3094       }
3095    } else {
3096       /* This handles custom modes and custom panels */
3097       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3098       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3099       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3100       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3101       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3102       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3103    }
3104 }
3105 
3106 static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3107 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3108                     unsigned short RefreshRateTableIndex)
3109 {
3110    unsigned short CRT2Index, ResIndex, backup;
3111    const struct SiS_LVDSData *LVDSData = NULL;
3112 
3113    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3114 
3115    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3116       SiS_Pr->SiS_RVBHCMAX  = 1;
3117       SiS_Pr->SiS_RVBHCFACT = 1;
3118       SiS_Pr->SiS_NewFlickerMode = 0;
3119       SiS_Pr->SiS_RVBHRS = 50;
3120       SiS_Pr->SiS_RY1COE = 0;
3121       SiS_Pr->SiS_RY2COE = 0;
3122       SiS_Pr->SiS_RY3COE = 0;
3123       SiS_Pr->SiS_RY4COE = 0;
3124       SiS_Pr->SiS_RVBHRS2 = 0;
3125    }
3126 
3127    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3128 
3129 #ifdef CONFIG_FB_SIS_315
3130       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3131       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3132 #endif
3133 
3134    } else {
3135 
3136       /* 301BDH needs LVDS Data */
3137       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3138       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3139 	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3140       }
3141 
3142       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3143                      		            &CRT2Index, &ResIndex);
3144 
3145       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3146 
3147       switch(CRT2Index) {
3148 	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3149 	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3150 	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3151 	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3152 	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3153 	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3154 #ifdef CONFIG_FB_SIS_300
3155 	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3156 	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3157 	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3158 	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3159 	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3160 #endif
3161 	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3162 	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3163 	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3164 	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3165 	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3166 	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3167 	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3168 	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3169 	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
3170       }
3171 
3172       if(LVDSData) {
3173 	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3174 	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3175 	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3176 	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3177       } else {
3178 	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3179       }
3180 
3181       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3182 	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3183 	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3184 	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3185 	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3186 	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3187             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3188 #ifdef CONFIG_FB_SIS_300
3189 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3190 	       if(ResIndex < 0x08) {
3191 		  SiS_Pr->SiS_HDE = 1280;
3192 		  SiS_Pr->SiS_VDE = 1024;
3193 	       }
3194 	    }
3195 #endif
3196          }
3197       }
3198    }
3199 }
3200 
3201 static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3202 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3203 		unsigned short RefreshRateTableIndex)
3204 {
3205   unsigned char  *ROMAddr = NULL;
3206   unsigned short tempax, tempbx, modeflag, romptr=0;
3207   unsigned short resinfo, CRT2Index, ResIndex;
3208   const struct SiS_LCDData *LCDPtr = NULL;
3209   const struct SiS_TVData  *TVPtr  = NULL;
3210 #ifdef CONFIG_FB_SIS_315
3211   short resinfo661;
3212 #endif
3213 
3214   if(ModeNo <= 0x13) {
3215      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3216      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3217   } else if(SiS_Pr->UseCustomMode) {
3218      modeflag = SiS_Pr->CModeFlag;
3219      resinfo = 0;
3220   } else {
3221      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3222      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3223 #ifdef CONFIG_FB_SIS_315
3224      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3225      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3226 	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3227 	 (resinfo661 >= 0)                     &&
3228 	 (SiS_Pr->SiS_NeedRomModeData) ) {
3229 	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3230 	   if((romptr = (SISGETROMW(21)))) {
3231 	      romptr += (resinfo661 * 10);
3232 	      ROMAddr = SiS_Pr->VirtualRomBase;
3233 	   }
3234 	}
3235      }
3236 #endif
3237   }
3238 
3239   SiS_Pr->SiS_NewFlickerMode = 0;
3240   SiS_Pr->SiS_RVBHRS = 50;
3241   SiS_Pr->SiS_RY1COE = 0;
3242   SiS_Pr->SiS_RY2COE = 0;
3243   SiS_Pr->SiS_RY3COE = 0;
3244   SiS_Pr->SiS_RY4COE = 0;
3245   SiS_Pr->SiS_RVBHRS2 = 0;
3246 
3247   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3248 
3249   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3250 
3251      if(SiS_Pr->UseCustomMode) {
3252 
3253 	SiS_Pr->SiS_RVBHCMAX  = 1;
3254 	SiS_Pr->SiS_RVBHCFACT = 1;
3255 	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3256 	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3257 
3258 	tempax = SiS_Pr->CHTotal;
3259 	if(modeflag & HalfDCLK) tempax <<= 1;
3260 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3261 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3262 
3263      } else {
3264 
3265 	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3266 
3267      }
3268 
3269   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3270 
3271      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3272 		    &CRT2Index,&ResIndex);
3273 
3274      switch(CRT2Index) {
3275 	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3276 	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3277 	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3278 	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3279 	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3280 	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3281 	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3282 	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3283 	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3284 	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3285 	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3286 	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3287 	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3288 	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3289      }
3290 
3291      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3292      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3293      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3294      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3295      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3296      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3297      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3298      if(modeflag & HalfDCLK) {
3299 	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3300 	if(SiS_Pr->SiS_RVBHRS2) {
3301 	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3302 	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3303 	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3304 	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3305 	}
3306      } else {
3307 	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3308      }
3309      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3310 
3311      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3312 
3313 	if((resinfo == SIS_RI_960x600)   ||
3314 	   (resinfo == SIS_RI_1024x768)  ||
3315 	   (resinfo == SIS_RI_1280x1024) ||
3316 	   (resinfo == SIS_RI_1280x720)) {
3317 	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3318 	}
3319 
3320 	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3321 
3322 	SiS_Pr->SiS_HT = ExtHiTVHT;
3323 	SiS_Pr->SiS_VT = ExtHiTVVT;
3324 	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3325 	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3326 	      SiS_Pr->SiS_HT = StHiTVHT;
3327 	      SiS_Pr->SiS_VT = StHiTVVT;
3328 	   }
3329 	}
3330 
3331      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3332 
3333 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3334 	   SiS_Pr->SiS_HT = 1650;
3335 	   SiS_Pr->SiS_VT = 750;
3336 	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3337 	   SiS_Pr->SiS_HT = NTSCHT;
3338 	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3339 	   SiS_Pr->SiS_VT = NTSCVT;
3340 	} else {
3341 	   SiS_Pr->SiS_HT = NTSCHT;
3342 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3343 	   SiS_Pr->SiS_VT = NTSCVT;
3344 	}
3345 
3346      } else {
3347 
3348 	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3349 	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3350 	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3351 	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3352 
3353 	if(modeflag & HalfDCLK) {
3354 	   SiS_Pr->SiS_RY1COE = 0x00;
3355 	   SiS_Pr->SiS_RY2COE = 0xf4;
3356 	   SiS_Pr->SiS_RY3COE = 0x10;
3357 	   SiS_Pr->SiS_RY4COE = 0x38;
3358 	}
3359 
3360 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3361 	   SiS_Pr->SiS_HT = NTSCHT;
3362 	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3363 	   SiS_Pr->SiS_VT = NTSCVT;
3364 	} else {
3365 	   SiS_Pr->SiS_HT = PALHT;
3366 	   SiS_Pr->SiS_VT = PALVT;
3367 	}
3368 
3369      }
3370 
3371   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3372 
3373      SiS_Pr->SiS_RVBHCMAX  = 1;
3374      SiS_Pr->SiS_RVBHCFACT = 1;
3375 
3376      if(SiS_Pr->UseCustomMode) {
3377 
3378 	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3379 	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3380 
3381 	tempax = SiS_Pr->CHTotal;
3382 	if(modeflag & HalfDCLK) tempax <<= 1;
3383 	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3384 	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3385 
3386      } else {
3387 
3388 	bool gotit = false;
3389 
3390 	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3391 
3392 	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3393 	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3394 	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3395 	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3396 	   gotit = true;
3397 
3398 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3399 
3400 #ifdef CONFIG_FB_SIS_315
3401 	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3402 	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3403 	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3404 	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3405 	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3406 	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3407 	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3408 	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3409 	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3410 	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3411 	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3412 	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3413 	   }
3414 	   if(SiS_Pr->SiS_VGAHT) gotit = true;
3415 	   else {
3416 	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3417 	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3418 	      SiS_Pr->SiS_RVBHCMAX  = 1;
3419 	      SiS_Pr->SiS_RVBHCFACT = 1;
3420 	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3421 	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3422 	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3423 	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3424 	      SiS_Pr->SiS_RVBHRS2 = 0;
3425 	      gotit = true;
3426 	   }
3427 #endif
3428 
3429 	}
3430 
3431 	if(!gotit) {
3432 
3433 	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3434 			  &CRT2Index,&ResIndex);
3435 
3436 	   switch(CRT2Index) {
3437 	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3438 	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3439 	      case Panel_1280x720      :
3440 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3441 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3442 	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3443 	      case Panel_1280x800      :
3444 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3445 	      case Panel_1280x800_2    :
3446 	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3447 	      case Panel_1280x854      :
3448 	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3449 	      case Panel_1280x960      :
3450 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3451 	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3452 	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3453 	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3454 	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3455 	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3456 	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3457 	      case Panel_1680x1050     :
3458 	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3459 	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3460 #ifdef CONFIG_FB_SIS_315
3461 	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3462 	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3463 #endif
3464 	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3465 	   }
3466 
3467 	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3468 	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3469 	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3470 	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3471 	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3472 	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3473 
3474         }
3475 
3476 	tempax = SiS_Pr->PanelXRes;
3477 	tempbx = SiS_Pr->PanelYRes;
3478 
3479 	switch(SiS_Pr->SiS_LCDResInfo) {
3480 	case Panel_1024x768:
3481 	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3482 	      if(SiS_Pr->ChipType < SIS_315H) {
3483 		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3484 		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3485 	      }
3486 	   } else {
3487 	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3488 	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3489 	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3490 	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3491 	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3492 	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3493 	   }
3494 	   break;
3495 	case Panel_1280x960:
3496 	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3497 	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3498 	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3499 	   break;
3500 	case Panel_1280x1024:
3501 	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3502 	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3503 	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3504 	   break;
3505 	case Panel_1600x1200:
3506 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3507 	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3508 	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3509 	   }
3510 	   break;
3511 	}
3512 
3513 	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3514 	   tempax = SiS_Pr->SiS_VGAHDE;
3515 	   tempbx = SiS_Pr->SiS_VGAVDE;
3516 	}
3517 
3518 	SiS_Pr->SiS_HDE = tempax;
3519 	SiS_Pr->SiS_VDE = tempbx;
3520      }
3521   }
3522 }
3523 
3524 static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3525 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3526                 unsigned short RefreshRateTableIndex)
3527 {
3528 
3529    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3530 
3531       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3532          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3533       } else {
3534 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3535 	    /* Need LVDS Data for LCD on 301B-DH */
3536 	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3537 	 } else {
3538 	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3539 	 }
3540       }
3541 
3542    } else {
3543 
3544       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3545 
3546    }
3547 }
3548 
3549 /*********************************************/
3550 /*         GET LVDS DES (SKEW) DATA          */
3551 /*********************************************/
3552 
3553 static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3554 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3555 {
3556    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3557 
3558 #ifdef CONFIG_FB_SIS_300
3559    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3560 
3561       if(SiS_Pr->ChipType < SIS_315H) {
3562 	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3563 	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3564 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3565 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3566 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3567 	       }
3568             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3569 	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3570 	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3571 		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3572 	       }
3573 	    }
3574 	 }
3575       }
3576    }
3577 #endif
3578    return PanelDesPtr;
3579 }
3580 
3581 static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3582 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3583                    unsigned short RefreshRateTableIndex)
3584 {
3585   unsigned short modeflag, ResIndex;
3586   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3587 
3588   SiS_Pr->SiS_LCDHDES = 0;
3589   SiS_Pr->SiS_LCDVDES = 0;
3590 
3591   /* Some special cases */
3592   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3593 
3594      /* Trumpion */
3595      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3596 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3597 	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3598 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3599 	   }
3600 	}
3601 	return;
3602      }
3603 
3604      /* 640x480 on LVDS */
3605      if(SiS_Pr->ChipType < SIS_315H) {
3606 	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3607 	   SiS_Pr->SiS_LCDHDES = 8;
3608 	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3609 	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3610 	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3611 	   return;
3612 	}
3613      }
3614 
3615   } /* LCD */
3616 
3617   if( (SiS_Pr->UseCustomMode) 		         ||
3618       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3619       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3620       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3621       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3622      return;
3623   }
3624 
3625   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3626   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3627 
3628   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3629 
3630 #ifdef CONFIG_FB_SIS_315
3631      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3632 	/* non-pass 1:1 only, see above */
3633 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3634 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3635 	}
3636 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3637 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3638 	}
3639      }
3640      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3641 	switch(SiS_Pr->SiS_CustomT) {
3642 	case CUT_UNIWILL1024:
3643 	case CUT_UNIWILL10242:
3644 	case CUT_CLEVO1400:
3645 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3646 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3647 	   }
3648 	   break;
3649 	}
3650 	switch(SiS_Pr->SiS_LCDResInfo) {
3651 	case Panel_1280x1024:
3652 	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3653 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3654 	   }
3655 	   break;
3656 	case Panel_1280x800:	/* Verified for Averatec 6240 */
3657 	case Panel_1280x800_2:	/* Verified for Asus A4L */
3658 	case Panel_1280x854:    /* Not verified yet FIXME */
3659 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3660 	   break;
3661 	}
3662      }
3663 #endif
3664 
3665   } else {
3666 
3667      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3668 
3669 	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3670 	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3671 	}
3672 
3673      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3674 
3675 	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3676 	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3677 
3678      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3679 
3680 	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3681 	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3682 	}
3683 	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3684 	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3685 	} else {
3686 	   if(SiS_Pr->ChipType < SIS_315H) {
3687 	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3688 	   } else {
3689 	      switch(SiS_Pr->SiS_LCDResInfo) {
3690 	      case Panel_800x600:
3691 	      case Panel_1024x768:
3692 	      case Panel_1280x1024:
3693 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3694 		 break;
3695 	      case Panel_1400x1050:
3696 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3697 		 break;
3698 	      }
3699 	   }
3700 	}
3701 
3702      } else {
3703 
3704         if(SiS_Pr->ChipType < SIS_315H) {
3705 #ifdef CONFIG_FB_SIS_300
3706 	   switch(SiS_Pr->SiS_LCDResInfo) {
3707 	   case Panel_800x600:
3708 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3709 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3710 	      } else {
3711 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3712 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3713 		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3714 		 else                          SiS_Pr->SiS_LCDVDES -= 4;
3715 	      }
3716 	      break;
3717 	   case Panel_1024x768:
3718 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3719 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3720 	      } else {
3721 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3722 		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3723 		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3724 	      }
3725 	      break;
3726 	   case Panel_1024x600:
3727 	   default:
3728 	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3729 		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3730 		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3731 	      } else {
3732 		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3733 	      }
3734 	      break;
3735 	   }
3736 
3737 	   switch(SiS_Pr->SiS_LCDTypeInfo) {
3738 	   case 1:
3739 	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3740 	      break;
3741 	   case 3: /* 640x480 only? */
3742 	      SiS_Pr->SiS_LCDHDES = 8;
3743 	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3744 	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3745 	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3746 	      break;
3747 	   }
3748 #endif
3749         } else {
3750 #ifdef CONFIG_FB_SIS_315
3751 	   switch(SiS_Pr->SiS_LCDResInfo) {
3752 	   case Panel_1024x768:
3753 	   case Panel_1280x1024:
3754 	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3755 	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3756 	      }
3757 	      break;
3758 	   case Panel_320x240_1:
3759 	   case Panel_320x240_2:
3760 	   case Panel_320x240_3:
3761 	      SiS_Pr->SiS_LCDVDES = 524;
3762 	      break;
3763 	   }
3764 #endif
3765 	}
3766      }
3767 
3768      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3769 	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3770 	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3771 	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3772 	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3773 	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3774 	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3775 	         if(SiS_Pr->ChipType < SIS_315H) {
3776 	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3777 	         } else {
3778 #ifdef CONFIG_FB_SIS_315
3779 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
3780 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3781 		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3782 		    if(!(modeflag & HalfDCLK)) {
3783 		       SiS_Pr->SiS_LCDHDES = 320;
3784 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3785 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3786         	    }
3787 #endif
3788 		 }
3789 	      }
3790 	   }
3791 	}
3792      }
3793   }
3794 }
3795 
3796 /*********************************************/
3797 /*           DISABLE VIDEO BRIDGE            */
3798 /*********************************************/
3799 
3800 #ifdef CONFIG_FB_SIS_315
3801 static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)3802 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3803 {
3804    int ret = 0;
3805 #ifdef SET_PWD
3806    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3807    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3808    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3809    unsigned short temp;
3810 
3811    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3812        (romptr)				&&
3813        (SiS_Pr->SiS_PWDOffset) ) {
3814       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3815       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3816       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3817       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3818       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3819       temp = 0x00;
3820       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3821          temp = 0x80;
3822 	 ret = 1;
3823       }
3824       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3825    }
3826 #endif
3827    return ret;
3828 }
3829 #endif
3830 
3831 /* NEVER use any variables (VBInfo), this will be called
3832  * from outside the context of modeswitch!
3833  * MUST call getVBType before calling this
3834  */
3835 void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)3836 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3837 {
3838 #ifdef CONFIG_FB_SIS_315
3839   unsigned short tempah, pushax=0, modenum;
3840 #endif
3841   unsigned short temp=0;
3842 
3843   if(SiS_Pr->SiS_VBType & VB_SISVB) {
3844 
3845      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
3846 
3847 	if(SiS_Pr->ChipType < SIS_315H) {
3848 
3849 #ifdef CONFIG_FB_SIS_300	   /* 300 series */
3850 
3851 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3852 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3853 		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3854 	      } else {
3855 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3856 	      }
3857 	      SiS_PanelDelay(SiS_Pr, 3);
3858 	   }
3859 	   if(SiS_Is301B(SiS_Pr)) {
3860 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3861 	      SiS_ShortDelay(SiS_Pr,1);
3862 	   }
3863 	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3864 	   SiS_DisplayOff(SiS_Pr);
3865 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3866 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3867 	   SiS_UnLockCRT2(SiS_Pr);
3868 	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3869 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3870 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3871 	   }
3872 	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3873 	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3874 	      SiS_PanelDelay(SiS_Pr, 2);
3875 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3876 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3877 	      } else {
3878 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3879 	      }
3880 	   }
3881 
3882 #endif  /* CONFIG_FB_SIS_300 */
3883 
3884         } else {
3885 
3886 #ifdef CONFIG_FB_SIS_315	   /* 315 series */
3887 
3888 	   int didpwd = 0;
3889 	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3890 	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3891 
3892 	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3893 
3894 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3895 
3896 #ifdef SET_EMI
3897 	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3898 		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3899 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3900 		 }
3901 	      }
3902 #endif
3903 
3904 	      didpwd = SiS_HandlePWD(SiS_Pr);
3905 
3906 	      if( (modenum <= 0x13)           ||
3907 		  (SiS_IsVAMode(SiS_Pr))      ||
3908 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
3909 		 if(!didpwd) {
3910 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3911 		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3912 		 } else {
3913 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3914 		 }
3915 	      }
3916 
3917 	      if(!custom1) {
3918 		 SiS_DDC2Delay(SiS_Pr,0xff00);
3919 		 SiS_DDC2Delay(SiS_Pr,0xe000);
3920 		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3921 		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3922 		 if(IS_SIS740) {
3923 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3924 		 }
3925 	         SiS_PanelDelay(SiS_Pr, 3);
3926 	      }
3927 
3928 	   }
3929 
3930 	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3931 	      /* if(SiS_Pr->ChipType < SIS_340) {*/
3932 		 tempah = 0xef;
3933 		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3934 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3935 	      /*}*/
3936 	   }
3937 
3938 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3939 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3940 	   }
3941 
3942 	   tempah = 0x3f;
3943 	   if(SiS_IsDualEdge(SiS_Pr)) {
3944 	      tempah = 0x7f;
3945 	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3946 	   }
3947 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3948 
3949 	   if((SiS_IsVAMode(SiS_Pr)) ||
3950 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3951 
3952 	      SiS_DisplayOff(SiS_Pr);
3953 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3954 		 SiS_PanelDelay(SiS_Pr, 2);
3955 	      }
3956 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3957 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3958 
3959 	   }
3960 
3961 	   if((!(SiS_IsVAMode(SiS_Pr))) ||
3962 	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3963 
3964 	      if(!(SiS_IsDualEdge(SiS_Pr))) {
3965 		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3966 		 SiS_DisplayOff(SiS_Pr);
3967 	      }
3968 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3969 
3970 	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3971 		 SiS_PanelDelay(SiS_Pr, 2);
3972 	      }
3973 
3974 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3975 	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3976 	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3977 	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3978 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3979 
3980 	   }
3981 
3982 	   if(SiS_IsNotM650orLater(SiS_Pr)) {
3983 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3984 	   }
3985 
3986 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3987 
3988 	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
3989 		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
3990 		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
3991 
3992 		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3993 		 if(!didpwd) {
3994 		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3995 		 }
3996 		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
3997 	      }
3998 
3999 	      if(!custom1) {
4000 		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4001 		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4002 		    if(SiS_IsVAorLCD(SiS_Pr)) {
4003 		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4004 		    }
4005 		 }
4006 	      }
4007 
4008 	   }
4009 
4010 #endif /* CONFIG_FB_SIS_315 */
4011 
4012 	}
4013 
4014      } else {     /* ============ For 301 ================ */
4015 
4016         if(SiS_Pr->ChipType < SIS_315H) {
4017 #ifdef CONFIG_FB_SIS_300
4018 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4019 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4020 	      SiS_PanelDelay(SiS_Pr, 3);
4021 	   }
4022 #endif
4023 	}
4024 
4025 	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4026 	SiS_DisplayOff(SiS_Pr);
4027 
4028 	if(SiS_Pr->ChipType >= SIS_315H) {
4029 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4030 	}
4031 
4032 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4033 
4034 	if(SiS_Pr->ChipType >= SIS_315H) {
4035 	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4036 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4037 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4038 	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4039 	} else {
4040 #ifdef CONFIG_FB_SIS_300
4041 	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4042 	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4043 		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4044 		SiS_PanelDelay(SiS_Pr, 2);
4045 		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4046 	    }
4047 #endif
4048 	}
4049 
4050       }
4051 
4052   } else {     /* ============ For LVDS =============*/
4053 
4054     if(SiS_Pr->ChipType < SIS_315H) {
4055 
4056 #ifdef CONFIG_FB_SIS_300	/* 300 series */
4057 
4058 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4059 	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4060 	}
4061 
4062 	if(SiS_Pr->ChipType == SIS_730) {
4063 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4064 	      SiS_WaitVBRetrace(SiS_Pr);
4065 	   }
4066 	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4067 	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4068 	      SiS_PanelDelay(SiS_Pr, 3);
4069 	   }
4070 	} else {
4071 	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4072 	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4073 		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4074 		    SiS_WaitVBRetrace(SiS_Pr);
4075 		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4076 		       SiS_DisplayOff(SiS_Pr);
4077 		    }
4078 		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4079 		    SiS_PanelDelay(SiS_Pr, 3);
4080 		 }
4081 	      }
4082 	   }
4083 	}
4084 
4085 	SiS_DisplayOff(SiS_Pr);
4086 
4087 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4088 
4089 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4090 	SiS_UnLockCRT2(SiS_Pr);
4091 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4092 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4093 
4094 	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4095 	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4096 	   SiS_PanelDelay(SiS_Pr, 2);
4097 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4098 	}
4099 
4100 #endif  /* CONFIG_FB_SIS_300 */
4101 
4102     } else {
4103 
4104 #ifdef CONFIG_FB_SIS_315	/* 315 series */
4105 
4106 	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4107 	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4108 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4109 	   /* } */
4110 	}
4111 
4112 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4113 
4114 	   if(SiS_Pr->ChipType == SIS_740) {
4115 	      temp = SiS_GetCH701x(SiS_Pr,0x61);
4116 	      if(temp < 1) {
4117 		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4118 		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4119 	      }
4120 
4121 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4122 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4123 		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4124 	      }
4125 	   }
4126 
4127 	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4128 	       (SiS_IsVAMode(SiS_Pr)) ) {
4129 	      SiS_Chrontel701xBLOff(SiS_Pr);
4130 	      SiS_Chrontel701xOff(SiS_Pr);
4131 	   }
4132 
4133 	   if(SiS_Pr->ChipType != SIS_740) {
4134 	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4135 		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4136 		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4137 	      }
4138 	   }
4139 
4140 	}
4141 
4142 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4143 	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4144 	   SiS_PanelDelay(SiS_Pr, 3);
4145 	}
4146 
4147 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4148 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4149 	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4150 	   SiS_DisplayOff(SiS_Pr);
4151 	}
4152 
4153 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4154 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4155 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4156 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4157 	}
4158 
4159 	if(SiS_Pr->ChipType == SIS_740) {
4160 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4161 	}
4162 
4163 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4164 
4165 	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4166 	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4167 	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4168 	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4169 	}
4170 
4171 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4172 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4173 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4174 	      if(SiS_Pr->ChipType == SIS_550) {
4175 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4176 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4177 	      }
4178 	   }
4179 	} else {
4180 	   if(SiS_Pr->ChipType == SIS_740) {
4181 	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4182 		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4183 	      }
4184 	   } else if(SiS_IsVAMode(SiS_Pr)) {
4185 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4186 	   }
4187 	}
4188 
4189 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4190 	   if(SiS_IsDualEdge(SiS_Pr)) {
4191 	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4192 	   } else {
4193 	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4194 	   }
4195 	}
4196 
4197 	SiS_UnLockCRT2(SiS_Pr);
4198 
4199 	if(SiS_Pr->ChipType == SIS_550) {
4200 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4201 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4202 	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4203 		   (!(SiS_IsDualEdge(SiS_Pr))) ||
4204 		   (!(SiS_IsVAMode(SiS_Pr))) ) {
4205 	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4206 	}
4207 
4208         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4209 	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4210 	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4211 		 SiS_PanelDelay(SiS_Pr, 2);
4212 		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4213 	      }
4214 	   }
4215         }
4216 
4217 #endif  /* CONFIG_FB_SIS_315 */
4218 
4219     }  /* 315 series */
4220 
4221   }  /* LVDS */
4222 
4223 }
4224 
4225 /*********************************************/
4226 /*            ENABLE VIDEO BRIDGE            */
4227 /*********************************************/
4228 
4229 /* NEVER use any variables (VBInfo), this will be called
4230  * from outside the context of a mode switch!
4231  * MUST call getVBType before calling this
4232  */
4233 static
4234 void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4235 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4236 {
4237   unsigned short temp=0, tempah;
4238 #ifdef CONFIG_FB_SIS_315
4239   unsigned short temp1, pushax=0;
4240   bool delaylong = false;
4241 #endif
4242 
4243   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4244 
4245     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
4246 
4247       if(SiS_Pr->ChipType < SIS_315H) {
4248 
4249 #ifdef CONFIG_FB_SIS_300     /* 300 series */
4250 
4251 	 if(SiS_CRT2IsLCD(SiS_Pr)) {
4252 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4253 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4254 	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4255 	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4256 	    }
4257 	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4258 	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4259 		  SiS_PanelDelay(SiS_Pr, 0);
4260 	       }
4261 	    }
4262 	 }
4263 
4264 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4265 	    (SiS_CRT2IsLCD(SiS_Pr))) {
4266 
4267 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4268 	    SiS_DisplayOn(SiS_Pr);
4269 	    SiS_UnLockCRT2(SiS_Pr);
4270 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4271 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4272 	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4273 	    } else {
4274 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4275 	    }
4276 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4277 	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4278 		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4279 		     SiS_PanelDelay(SiS_Pr, 1);
4280 		  }
4281 		  SiS_WaitVBRetrace(SiS_Pr);
4282 		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4283 	       }
4284 	    }
4285 
4286 	 } else {
4287 
4288 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4289 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4290 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4291 	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4292 	    }
4293 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4294 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4295 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4296 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4297 	    SiS_DisplayOn(SiS_Pr);
4298 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4299 	       if(SiS_CRT2IsLCD(SiS_Pr)) {
4300 		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4301 		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4302 		        SiS_PanelDelay(SiS_Pr, 1);
4303 		     }
4304 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4305 		  }
4306 	       }
4307 	    }
4308 
4309 	 }
4310 
4311 
4312 #endif /* CONFIG_FB_SIS_300 */
4313 
4314       } else {
4315 
4316 #ifdef CONFIG_FB_SIS_315    /* 315 series */
4317 
4318 #ifdef SET_EMI
4319 	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4320 	 int didpwd = 0;
4321 	 /* unsigned short  emidelay=0; */
4322 #endif
4323 
4324 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4325 	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4326 #ifdef SET_EMI
4327 	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4328 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4329 	    }
4330 #endif
4331 	 }
4332 
4333 	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4334 	    /*if(SiS_Pr->ChipType < SIS_340) { */
4335 	       tempah = 0x10;
4336 	       if(SiS_LCDAEnabled(SiS_Pr)) {
4337 		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4338 		  else			    tempah = 0x08;
4339 	       }
4340 	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4341 	    /*}*/
4342 	 }
4343 
4344 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4345 
4346 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4347 	    SiS_DisplayOff(SiS_Pr);
4348 	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4349 	    if(IS_SIS740) {
4350 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4351 	    }
4352 
4353 	    didpwd = SiS_HandlePWD(SiS_Pr);
4354 
4355 	    if(SiS_IsVAorLCD(SiS_Pr)) {
4356 	       if(!didpwd) {
4357 		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4358 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4359 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4360 		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4361 		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4362 		        SiS_GenericDelay(SiS_Pr, 17664);
4363 		     }
4364 		  }
4365 	       } else {
4366 		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4367 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4368 		     SiS_GenericDelay(SiS_Pr, 17664);
4369 		  }
4370 	       }
4371 	    }
4372 
4373 	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4374 	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4375 	       delaylong = true;
4376 	    }
4377 
4378 	 }
4379 
4380 	 if(!(SiS_IsVAMode(SiS_Pr))) {
4381 
4382 	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4383 	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4384 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4385 	       if(!(tempah & SetCRT2ToRAMDAC)) {
4386 		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4387 	       }
4388 	    }
4389 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4390 
4391 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4392 
4393 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4394 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4395 
4396 	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4397 	       SiS_PanelDelay(SiS_Pr, 2);
4398 	    }
4399 
4400 	 } else {
4401 
4402 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4403 
4404 	 }
4405 
4406 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4407 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4408 
4409 	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4410 	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
4411 	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
4412 	       /* Enable "LVDS PLL power on" (even on 301C) */
4413 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4414 	       /* Enable "LVDS Driver Power on" (even on 301C) */
4415 	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4416 	    }
4417 	 }
4418 
4419 	 tempah = 0xc0;
4420 	 if(SiS_IsDualEdge(SiS_Pr)) {
4421 	    tempah = 0x80;
4422 	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4423 	 }
4424 	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4425 
4426 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4427 
4428 	    SiS_PanelDelay(SiS_Pr, 2);
4429 
4430 	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4431 	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4432 
4433 	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4434 #ifdef SET_EMI
4435 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4436 		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4437 		  SiS_GenericDelay(SiS_Pr, 2048);
4438 	       }
4439 #endif
4440 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4441 
4442 	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4443 #ifdef SET_EMI
4444 		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4445 
4446 		  if(SiS_Pr->SiS_ROMNew) {
4447 		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4448 		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4449 		     if(romptr) {
4450 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4451 			SiS_Pr->EMI_30 = 0;
4452 			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4453 			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4454 			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4455 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4456 			/* emidelay = SISGETROMW((romptr + 0x22)); */
4457 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4458 		     }
4459 		  }
4460 
4461 		  /*                                              (P4_30|0x40)  */
4462 		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4463 		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4464 		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4465 		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4466 		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4467 		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4468 		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4469 		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4470 		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4471 
4472 		  if(SiS_Pr->HaveEMI) {
4473 		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4474 		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4475 		  } else {
4476 		     r30 = 0;
4477 		  }
4478 
4479 		  /* EMI_30 is read at driver start; however, the BIOS sets this
4480 		   * (if it is used) only if the LCD is in use. In case we caught
4481 		   * the machine while on TV output, this bit is not set and we
4482 		   * don't know if it should be set - hence our detection is wrong.
4483 		   * Work-around this here:
4484 		   */
4485 
4486 		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4487 		     switch((cr36 & 0x0f)) {
4488 		     case 2:
4489 			r30 |= 0x40;
4490 			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4491 			if(!SiS_Pr->HaveEMI) {
4492 			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4493 			   if((cr36 & 0xf0) == 0x30) {
4494 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4495 			   }
4496 			}
4497 			break;
4498 		     case 3:  /* 1280x1024 */
4499 			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4500 			if(!SiS_Pr->HaveEMI) {
4501 			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4502 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4503 			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4504 			   }
4505 			}
4506 			break;
4507 		     case 9:  /* 1400x1050 */
4508 			r30 |= 0x40;
4509 			if(!SiS_Pr->HaveEMI) {
4510 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4511 			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4512 			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4513 			   }
4514 			}
4515 			break;
4516 		     case 11: /* 1600x1200 - unknown */
4517 			r30 |= 0x40;
4518 			if(!SiS_Pr->HaveEMI) {
4519 			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4520 			}
4521 		     }
4522                   }
4523 
4524 		  /* BIOS values don't work so well sometimes */
4525 		  if(!SiS_Pr->OverruleEMI) {
4526 #ifdef COMPAL_HACK
4527 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4528 			if((cr36 & 0x0f) == 0x09) {
4529 			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4530 			}
4531  		     }
4532 #endif
4533 #ifdef COMPAQ_HACK
4534 		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4535 			if((cr36 & 0x0f) == 0x03) {
4536 			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4537 			}
4538 		     }
4539 #endif
4540 #ifdef ASUS_HACK
4541 		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4542 			if((cr36 & 0x0f) == 0x02) {
4543 			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4544 			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4545 			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4546 			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4547 			}
4548 		     }
4549 #endif
4550 		  }
4551 
4552 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4553 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4554 		     SiS_GenericDelay(SiS_Pr, 2048);
4555 		  }
4556 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4557 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4558 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4559 #endif	/* SET_EMI */
4560 
4561 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4562 
4563 #ifdef SET_EMI
4564 		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4565 		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
4566 		     if(r30 & 0x40) {
4567 			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4568 			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4569 			if(delaylong) {
4570 			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4571 			   delaylong = false;
4572 			}
4573 			SiS_WaitVBRetrace(SiS_Pr);
4574 			SiS_WaitVBRetrace(SiS_Pr);
4575 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4576 			   SiS_GenericDelay(SiS_Pr, 1280);
4577 			}
4578 			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4579 			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4580 		     }
4581 		  }
4582 #endif
4583 	       }
4584 	    }
4585 
4586 	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4587 	       if(SiS_IsVAorLCD(SiS_Pr)) {
4588 		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4589 		  if(delaylong) {
4590 		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4591 		  }
4592 		  SiS_WaitVBRetrace(SiS_Pr);
4593 		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4594 		     SiS_GenericDelay(SiS_Pr, 2048);
4595 		     SiS_WaitVBRetrace(SiS_Pr);
4596 		  }
4597 		  if(!didpwd) {
4598 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4599 		  } else {
4600 		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4601 		  }
4602 	       }
4603 	    }
4604 
4605 	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4606 	    SiS_DisplayOn(SiS_Pr);
4607 	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4608 
4609 	 }
4610 
4611 	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4612 	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4613 	 }
4614 
4615 #endif /* CONFIG_FB_SIS_315 */
4616 
4617       }
4618 
4619     } else {	/* ============  For 301 ================ */
4620 
4621        if(SiS_Pr->ChipType < SIS_315H) {
4622 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4623 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4624 	     SiS_PanelDelay(SiS_Pr, 0);
4625 	  }
4626        }
4627 
4628        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4629        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4630 	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4631 	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4632        }
4633        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4634 
4635        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4636 
4637        if(SiS_Pr->ChipType >= SIS_315H) {
4638 	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4639 	  if(!(temp & 0x80)) {
4640 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4641 	  }
4642        }
4643 
4644        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4645 
4646        SiS_VBLongWait(SiS_Pr);
4647        SiS_DisplayOn(SiS_Pr);
4648        if(SiS_Pr->ChipType >= SIS_315H) {
4649 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4650        }
4651        SiS_VBLongWait(SiS_Pr);
4652 
4653        if(SiS_Pr->ChipType < SIS_315H) {
4654 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4655 	     SiS_PanelDelay(SiS_Pr, 1);
4656 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4657 	  }
4658        }
4659 
4660     }
4661 
4662   } else {   /* =================== For LVDS ================== */
4663 
4664     if(SiS_Pr->ChipType < SIS_315H) {
4665 
4666 #ifdef CONFIG_FB_SIS_300    /* 300 series */
4667 
4668        if(SiS_CRT2IsLCD(SiS_Pr)) {
4669 	  if(SiS_Pr->ChipType == SIS_730) {
4670 	     SiS_PanelDelay(SiS_Pr, 1);
4671 	     SiS_PanelDelay(SiS_Pr, 1);
4672 	     SiS_PanelDelay(SiS_Pr, 1);
4673 	  }
4674 	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4675 	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4676 	     SiS_PanelDelay(SiS_Pr, 0);
4677 	  }
4678        }
4679 
4680        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4681        SiS_DisplayOn(SiS_Pr);
4682        SiS_UnLockCRT2(SiS_Pr);
4683        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4684        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4685 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4686        } else {
4687 	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4688        }
4689 
4690        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4691 	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4692 	     SiS_WaitVBRetrace(SiS_Pr);
4693 	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4694 	  }
4695        }
4696 
4697        if(SiS_CRT2IsLCD(SiS_Pr)) {
4698 	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4699 	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4700 		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4701 		   SiS_PanelDelay(SiS_Pr, 1);
4702 		   SiS_PanelDelay(SiS_Pr, 1);
4703 		}
4704 		SiS_WaitVBRetrace(SiS_Pr);
4705 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4706 	     }
4707 	  }
4708        }
4709 
4710 #endif  /* CONFIG_FB_SIS_300 */
4711 
4712     } else {
4713 
4714 #ifdef CONFIG_FB_SIS_315    /* 315 series */
4715 
4716        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4717 	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
4718 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4719 	  /*}*/
4720        }
4721 
4722        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4723 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4724 	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4725 	     SiS_PanelDelay(SiS_Pr, 0);
4726 	  }
4727        }
4728 
4729        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4730        SiS_UnLockCRT2(SiS_Pr);
4731 
4732        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4733 
4734        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4735 	  temp = SiS_GetCH701x(SiS_Pr,0x66);
4736 	  temp &= 0x20;
4737 	  SiS_Chrontel701xBLOff(SiS_Pr);
4738        }
4739 
4740        if(SiS_Pr->ChipType != SIS_550) {
4741 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4742        }
4743 
4744        if(SiS_Pr->ChipType == SIS_740) {
4745 	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4746 	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4747 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4748 	     }
4749 	  }
4750        }
4751 
4752        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4753        if(!(temp1 & 0x80)) {
4754 	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4755        }
4756 
4757        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4758 	  if(temp) {
4759 	     SiS_Chrontel701xBLOn(SiS_Pr);
4760 	  }
4761        }
4762 
4763        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4764 	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4765 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4766 	     if(SiS_Pr->ChipType == SIS_550) {
4767 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4768 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4769 	     }
4770 	  }
4771        } else if(SiS_IsVAMode(SiS_Pr)) {
4772 	  if(SiS_Pr->ChipType != SIS_740) {
4773 	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4774 	  }
4775        }
4776 
4777        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4778 	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4779        }
4780 
4781        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4782 	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4783 	     SiS_Chrontel701xOn(SiS_Pr);
4784 	  }
4785 	  if( (SiS_IsVAMode(SiS_Pr)) ||
4786 	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4787 	     SiS_ChrontelDoSomething1(SiS_Pr);
4788 	  }
4789        }
4790 
4791        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4792 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4793 	     if( (SiS_IsVAMode(SiS_Pr)) ||
4794 		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4795 		SiS_Chrontel701xBLOn(SiS_Pr);
4796 		SiS_ChrontelInitTVVSync(SiS_Pr);
4797 	     }
4798 	  }
4799        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4800 	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4801 	     if(SiS_CRT2IsLCD(SiS_Pr)) {
4802 		SiS_PanelDelay(SiS_Pr, 1);
4803 		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4804 	     }
4805 	  }
4806        }
4807 
4808 #endif  /* CONFIG_FB_SIS_315 */
4809 
4810     } /* 310 series */
4811 
4812   }  /* LVDS */
4813 
4814 }
4815 
4816 /*********************************************/
4817 /*         SET PART 1 REGISTER GROUP         */
4818 /*********************************************/
4819 
4820 /* Set CRT2 OFFSET / PITCH */
4821 static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)4822 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4823 		unsigned short RRTI)
4824 {
4825    unsigned short offset;
4826    unsigned char  temp;
4827 
4828    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4829 
4830    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4831 
4832    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4833    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4834 
4835    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4836    if(offset & 0x07) temp++;
4837    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4838 }
4839 
4840 /* Set CRT2 sync and PanelLink mode */
4841 static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)4842 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4843 {
4844    unsigned short tempah=0, tempbl, infoflag;
4845 
4846    tempbl = 0xC0;
4847 
4848    if(SiS_Pr->UseCustomMode) {
4849       infoflag = SiS_Pr->CInfoFlag;
4850    } else {
4851       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4852    }
4853 
4854    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
4855 
4856       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4857 	 tempah = 0;
4858       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4859 	 tempah = SiS_Pr->SiS_LCDInfo;
4860       } else tempah = infoflag >> 8;
4861       tempah &= 0xC0;
4862       tempah |= 0x20;
4863       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4864       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4865 	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4866 	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4867 	    tempah |= 0xf0;
4868 	 }
4869 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4870 	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
4871 	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4872 	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4873 	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4874 	    tempah |= 0x30;
4875 	 }
4876 	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4877 	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4878 	    tempah &= ~0xc0;
4879 	 }
4880       }
4881       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4882 	 if(SiS_Pr->ChipType >= SIS_315H) {
4883 	    tempah >>= 3;
4884 	    tempah &= 0x18;
4885 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4886 	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4887 	 } else {
4888 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4889 	 }
4890       } else {
4891 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4892       }
4893 
4894    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4895 
4896       if(SiS_Pr->ChipType < SIS_315H) {
4897 
4898 #ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
4899 
4900 	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
4901 
4902 	    tempah = infoflag >> 8;
4903 	    tempbl = 0;
4904 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4905 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4906 		  tempah = SiS_Pr->SiS_LCDInfo;
4907 		  tempbl = (tempah >> 6) & 0x03;
4908 	       }
4909 	    }
4910 	    tempah &= 0xC0;
4911 	    tempah |= 0x20;
4912 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4913 	    tempah |= 0xc0;
4914 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4915 	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4916 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4917 	    }
4918 
4919 	 } else {							/* 630 - 301 */
4920 
4921 	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4922 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4923 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4924 
4925 	 }
4926 
4927 #endif /* CONFIG_FB_SIS_300 */
4928 
4929       } else {
4930 
4931 #ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
4932 
4933 	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
4934 
4935 	    tempbl = 0;
4936 	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4937 	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4938 	       tempah = infoflag >> 8;
4939 	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4940 		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4941 	       }
4942 	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
4943 		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4944 	       tempah = infoflag >> 8;
4945 	       tempbl = 0x03;
4946 	    } else {
4947 	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4948 	       tempbl = (tempah >> 6) & 0x03;
4949 	       tempbl |= 0x08;
4950 	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4951 	    }
4952 	    tempah &= 0xC0;
4953 	    tempah |= 0x20;
4954 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4955 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
4956 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4957 	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4958 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4959 		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4960 	       }
4961 	    }
4962 
4963 	 } else {							/* 315 - TMDS */
4964 
4965 	    tempah = tempbl = infoflag >> 8;
4966 	    if(!SiS_Pr->UseCustomMode) {
4967 	       tempbl = 0;
4968 	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4969 		  if(ModeNo <= 0x13) {
4970 		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4971 		  }
4972 	       }
4973 	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4974 		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4975 		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4976 		       tempah = SiS_Pr->SiS_LCDInfo;
4977 		       tempbl = (tempah >> 6) & 0x03;
4978 		    }
4979 		  }
4980 	       }
4981 	    }
4982 	    tempah &= 0xC0;
4983 	    tempah |= 0x20;
4984 	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4985 	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4986 	       /* Imitate BIOS bug */
4987 	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
4988 	    }
4989 	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4990 	       tempah >>= 3;
4991 	       tempah &= 0x18;
4992 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4993 	    } else {
4994 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4995 	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4996 		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4997 		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4998 		  }
4999 	       }
5000 	    }
5001 
5002          }
5003 #endif  /* CONFIG_FB_SIS_315 */
5004       }
5005    }
5006 }
5007 
5008 /* Set CRT2 FIFO on 300/540/630/730 */
5009 #ifdef CONFIG_FB_SIS_300
5010 static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5011 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5012 {
5013   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5014   unsigned short temp, index, modeidindex, refreshratetableindex;
5015   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5016   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5017   unsigned int   data, pci50, pciA0;
5018   static const unsigned char colortharray[] = {
5019   	1, 1, 2, 2, 3, 4
5020   };
5021 
5022   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5023 
5024   if(!SiS_Pr->CRT1UsesCustomMode) {
5025 
5026      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5027      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5028      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5029      SiS_Pr->SiS_SelectCRT2Rate = 0;
5030      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5031 
5032      if(CRT1ModeNo >= 0x13) {
5033         /* Get VCLK */
5034 	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5035 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5036 
5037 	/* Get colordepth */
5038 	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5039 	if(!colorth) colorth++;
5040      }
5041 
5042   } else {
5043 
5044      CRT1ModeNo = 0xfe;
5045 
5046      /* Get VCLK */
5047      VCLK = SiS_Pr->CSRClock_CRT1;
5048 
5049      /* Get color depth */
5050      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5051 
5052   }
5053 
5054   if(CRT1ModeNo >= 0x13) {
5055      /* Get MCLK */
5056      if(SiS_Pr->ChipType == SIS_300) {
5057         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5058      } else {
5059         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5060      }
5061      index &= 0x07;
5062      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5063 
5064      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5065      if(!temp) temp++;
5066      temp <<= 2;
5067 
5068      data2 = temp - ((colorth * VCLK) / MCLK);
5069 
5070      temp = (28 * 16) % data2;
5071      data2 = (28 * 16) / data2;
5072      if(temp) data2++;
5073 
5074      if(SiS_Pr->ChipType == SIS_300) {
5075 
5076 	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5077 	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5078 
5079      } else {
5080 
5081 	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5082 	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5083 
5084         if(SiS_Pr->ChipType == SIS_730) {
5085 
5086 	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5087 	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
5088 
5089 	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5090 	   index = 0;  /* -- do it like the BIOS anyway... */
5091 
5092 	} else {
5093 
5094 	   pci50 >>= 24;
5095 	   pciA0 >>= 24;
5096 
5097 	   index = (pci50 >> 1) & 0x07;
5098 
5099 	   if(pci50 & 0x01)    index += 6;
5100 	   if(!(pciA0 & 0x01)) index += 24;
5101 
5102 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5103 
5104 	}
5105 
5106 	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5107 	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5108 
5109      }
5110 
5111      data += data2;						/* CRT1 Request Period */
5112 
5113      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5114      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5115 
5116      if(!SiS_Pr->UseCustomMode) {
5117 
5118 	CRT2ModeNo = ModeNo;
5119 	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5120 
5121 	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5122 
5123 	/* Get VCLK  */
5124 	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5125 	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5126 
5127 	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5128 	   if(SiS_Pr->SiS_UseROM) {
5129 	      if(ROMAddr[0x220] & 0x01) {
5130 		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5131 	      }
5132            }
5133         }
5134 
5135      } else {
5136 
5137 	/* Get VCLK */
5138 	CRT2ModeNo = 0xfe;
5139 	VCLK = SiS_Pr->CSRClock;
5140 
5141      }
5142 
5143      /* Get colordepth */
5144      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5145      if(!colorth) colorth++;
5146 
5147      data = data * VCLK * colorth;
5148      temp = data % (MCLK << 4);
5149      data = data / (MCLK << 4);
5150      if(temp) data++;
5151 
5152      if(data < 6) data = 6;
5153      else if(data > 0x14) data = 0x14;
5154 
5155      if(SiS_Pr->ChipType == SIS_300) {
5156         temp = 0x16;
5157 	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5158 	   temp = 0x13;
5159      } else {
5160         temp = 0x16;
5161 	if(( (SiS_Pr->ChipType == SIS_630) ||
5162 	     (SiS_Pr->ChipType == SIS_730) )  &&
5163 	   (SiS_Pr->ChipRevision >= 0x30))
5164 	   temp = 0x1b;
5165      }
5166      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5167 
5168      if((SiS_Pr->ChipType == SIS_630) &&
5169 	(SiS_Pr->ChipRevision >= 0x30)) {
5170 	if(data > 0x13) data = 0x13;
5171      }
5172      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5173 
5174   } else {  /* If mode <= 0x13, we just restore everything */
5175 
5176      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5177      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5178 
5179   }
5180 }
5181 #endif
5182 
5183 /* Set CRT2 FIFO on 315/330 series */
5184 #ifdef CONFIG_FB_SIS_315
5185 static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5186 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5187 {
5188   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5189   if( (SiS_Pr->ChipType == SIS_760)      &&
5190       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5191       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5192       (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5193       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5194      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5195      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5196      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5197      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5198      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5199      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5200   } else {
5201      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5202   }
5203 
5204 }
5205 #endif
5206 
5207 static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5208 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5209 {
5210   unsigned int tempax,tempbx;
5211 
5212   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5213   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5214   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5215   return (unsigned short)tempax;
5216 }
5217 
5218 /* Set Part 1 / SiS bridge slave mode */
5219 static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5220 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5221                   unsigned short RefreshRateTableIndex)
5222 {
5223   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5224   static const unsigned short CRTranslation[] = {
5225        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5226 	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5227        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5228 	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5229        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5230 	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5231   };
5232 
5233   if(ModeNo <= 0x13) {
5234      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5235   } else if(SiS_Pr->UseCustomMode) {
5236      modeflag = SiS_Pr->CModeFlag;
5237      xres = SiS_Pr->CHDisplay;
5238   } else {
5239      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5240      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5241   }
5242 
5243   /* The following is only done if bridge is in slave mode: */
5244 
5245   if(SiS_Pr->ChipType >= SIS_315H) {
5246      if(xres >= 1600) {  /* BIOS: == 1600 */
5247         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5248      }
5249   }
5250 
5251   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5252 
5253   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5254   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5255 
5256   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5257   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5258      SiS_Pr->CHBlankStart += 16;
5259   }
5260 
5261   SiS_Pr->CHBlankEnd = 32;
5262   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5263      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5264   }
5265 
5266   temp = SiS_Pr->SiS_VGAHT - 96;
5267   if(!(modeflag & HalfDCLK)) temp -= 32;
5268   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5269      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5270      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5271      temp -= 3;
5272      temp <<= 3;
5273   } else {
5274      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5275   }
5276   SiS_Pr->CHSyncStart = temp;
5277 
5278   SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
5279 
5280   SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
5281 
5282   VGAVDE = SiS_Pr->SiS_VGAVDE;
5283   if     (VGAVDE ==  357) VGAVDE =  350;
5284   else if(VGAVDE ==  360) VGAVDE =  350;
5285   else if(VGAVDE ==  375) VGAVDE =  350;
5286   else if(VGAVDE ==  405) VGAVDE =  400;
5287   else if(VGAVDE ==  420) VGAVDE =  400;
5288   else if(VGAVDE ==  525) VGAVDE =  480;
5289   else if(VGAVDE == 1056) VGAVDE = 1024;
5290   SiS_Pr->CVDisplay = VGAVDE;
5291 
5292   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5293 
5294   SiS_Pr->CVBlankEnd = 1;
5295   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5296 
5297   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5298   SiS_Pr->CVSyncStart = VGAVDE + temp;
5299 
5300   temp >>= 3;
5301   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5302 
5303   SiS_CalcCRRegisters(SiS_Pr, 0);
5304   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5305 
5306   for(i = 0; i <= 7; i++) {
5307      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5308   }
5309   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5310      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5311   }
5312   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5313      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5314   }
5315   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5316      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5317   }
5318 
5319   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5320   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5321 
5322   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5323   if(modeflag & DoubleScanMode) temp |= 0x80;
5324   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5325 
5326   temp = 0;
5327   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5328   if(modeflag & HalfDCLK) temp |= 0x08;
5329   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5330 
5331   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
5332   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
5333 
5334   temp = 0;
5335   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5336      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5337   }
5338   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
5339 
5340   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5341   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
5342 }
5343 
5344 /* Setup panel link
5345  * This is used for LVDS, LCDA and Chrontel TV output
5346  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5347  */
5348 static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5349 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5350 		unsigned short RefreshRateTableIndex)
5351 {
5352   unsigned short modeflag, resinfo = 0;
5353   unsigned short push2, tempax, tempbx, tempcx, temp;
5354   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5355   bool islvds = false, issis  = false, chkdclkfirst = false;
5356 #ifdef CONFIG_FB_SIS_300
5357   unsigned short crt2crtc = 0;
5358 #endif
5359 #ifdef CONFIG_FB_SIS_315
5360   unsigned short pushcx;
5361 #endif
5362 
5363   if(ModeNo <= 0x13) {
5364      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5365      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5366 #ifdef CONFIG_FB_SIS_300
5367      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5368 #endif
5369   } else if(SiS_Pr->UseCustomMode) {
5370      modeflag = SiS_Pr->CModeFlag;
5371   } else {
5372      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5373      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5374 #ifdef CONFIG_FB_SIS_300
5375      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5376 #endif
5377   }
5378 
5379   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5380   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5381      islvds = true;
5382   }
5383 
5384   /* is really sis if sis bridge, but not 301B-DH */
5385   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5386      issis = true;
5387   }
5388 
5389   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5390      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5391         chkdclkfirst = true;
5392      }
5393   }
5394 
5395 #ifdef CONFIG_FB_SIS_315
5396   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5397      if(IS_SIS330) {
5398         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5399      } else if(IS_SIS740) {
5400         if(islvds) {
5401            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5402 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5403         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5404            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5405         }
5406      } else {
5407         if(islvds) {
5408            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5409 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5410         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5411            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5412 	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5413 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5414 	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5415 	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5416 	      }
5417 	   }
5418         }
5419      }
5420   }
5421 #endif
5422 
5423   /* Horizontal */
5424 
5425   tempax = SiS_Pr->SiS_LCDHDES;
5426   if(islvds) {
5427      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5428 	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5429 	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5430 	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5431 	      tempax -= 8;
5432 	   }
5433 	}
5434      }
5435   }
5436 
5437   temp = (tempax & 0x0007);
5438   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5439   temp = (tempax >> 3) & 0x00FF;
5440   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5441 
5442   tempbx = SiS_Pr->SiS_HDE;
5443   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5444      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5445         tempbx = SiS_Pr->PanelXRes;
5446      }
5447      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5448         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5449         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5450         tempbx >>= 1;
5451      }
5452   }
5453 
5454   tempax += tempbx;
5455   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5456 
5457   temp = tempax;
5458   if(temp & 0x07) temp += 8;
5459   temp >>= 3;
5460   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5461 
5462   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5463 
5464   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5465      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5466         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5467      }
5468   }
5469 
5470   tempcx += tempax;
5471   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5472 
5473   temp = (tempcx >> 3) & 0x00FF;
5474   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5475      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5476 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5477 	   switch(ModeNo) {
5478 	   case 0x04:
5479 	   case 0x05:
5480 	   case 0x0d: temp = 0x56; break;
5481 	   case 0x10: temp = 0x60; break;
5482 	   case 0x13: temp = 0x5f; break;
5483 	   case 0x40:
5484 	   case 0x41:
5485 	   case 0x4f:
5486 	   case 0x43:
5487 	   case 0x44:
5488 	   case 0x62:
5489 	   case 0x56:
5490 	   case 0x53:
5491 	   case 0x5d:
5492 	   case 0x5e: temp = 0x54; break;
5493 	   }
5494 	}
5495      }
5496   }
5497   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5498 
5499   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5500      temp += 2;
5501      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5502 	temp += 8;
5503 	if(SiS_Pr->PanelHRE != 999) {
5504 	   temp = tempcx + SiS_Pr->PanelHRE;
5505 	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5506 	   temp >>= 3;
5507 	}
5508      }
5509   } else {
5510      temp += 10;
5511   }
5512 
5513   temp &= 0x1F;
5514   temp |= ((tempcx & 0x07) << 5);
5515   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5516 
5517   /* Vertical */
5518 
5519   tempax = SiS_Pr->SiS_VGAVDE;
5520   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5521      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5522 	tempax = SiS_Pr->PanelYRes;
5523      }
5524   }
5525 
5526   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5527   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5528 
5529   push2 = tempbx;
5530 
5531   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5532   if(SiS_Pr->ChipType < SIS_315H) {
5533      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5534 	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5535 	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5536 	}
5537      }
5538   }
5539   if(islvds) tempcx >>= 1;
5540   else       tempcx >>= 2;
5541 
5542   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5543       (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5544       (SiS_Pr->PanelVRS != 999) ) {
5545      tempcx = SiS_Pr->PanelVRS;
5546      tempbx += tempcx;
5547      if(issis) tempbx++;
5548   } else {
5549      tempbx += tempcx;
5550      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5551      else if(issis)                   tempbx++;
5552   }
5553 
5554   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5555 
5556   temp = tempbx & 0x00FF;
5557   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5558      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5559 	if(ModeNo == 0x10) temp = 0xa9;
5560      }
5561   }
5562   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
5563 
5564   tempcx >>= 3;
5565   tempcx++;
5566 
5567   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5568      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5569         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5570      }
5571   }
5572 
5573   tempcx += tempbx;
5574   temp = tempcx & 0x000F;
5575   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5576 
5577   temp = ((tempbx >> 8) & 0x07) << 3;
5578   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5579      if(SiS_Pr->SiS_HDE != 640) {
5580         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5581      }
5582   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5583   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5584   tempbx = 0x87;
5585   if((SiS_Pr->ChipType >= SIS_315H) ||
5586      (SiS_Pr->ChipRevision >= 0x30)) {
5587      tempbx = 0x07;
5588      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5589 	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5590      }
5591      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5592      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5593 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5594 	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5595 	} else {
5596 	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5597 	}
5598      }
5599   }
5600   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5601 
5602   tempbx = push2;						/* BPLVDEE */
5603 
5604   tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
5605 
5606   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5607      switch(SiS_Pr->SiS_LCDResInfo) {
5608      case Panel_640x480:
5609 	tempbx = SiS_Pr->SiS_VGAVDE - 1;
5610 	tempcx = SiS_Pr->SiS_VGAVDE;
5611 	break;
5612      case Panel_800x600:
5613 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5614 	   if(resinfo == SIS_RI_800x600) tempcx++;
5615 	}
5616 	break;
5617      case Panel_1024x600:
5618 	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5619 	   if(resinfo == SIS_RI_1024x600) tempcx++;
5620 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5621 	      if(resinfo == SIS_RI_800x600) tempcx++;
5622 	   }
5623 	}
5624 	break;
5625      case Panel_1024x768:
5626 	if(SiS_Pr->ChipType < SIS_315H) {
5627 	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5628 	      if(resinfo == SIS_RI_1024x768) tempcx++;
5629 	   }
5630 	}
5631 	break;
5632      }
5633   }
5634 
5635   temp = ((tempbx >> 8) & 0x07) << 3;
5636   temp |= ((tempcx >> 8) & 0x07);
5637   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5638   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5639   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5640 
5641   /* Vertical scaling */
5642 
5643   if(SiS_Pr->ChipType < SIS_315H) {
5644 
5645 #ifdef CONFIG_FB_SIS_300      /* 300 series */
5646      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5647      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5648      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5649      if(temp) tempeax++;
5650 
5651      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5652 
5653      temp = (unsigned short)(tempeax & 0x00FF);
5654      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5655      tempvcfact = temp;
5656 #endif /* CONFIG_FB_SIS_300 */
5657 
5658   } else {
5659 
5660 #ifdef CONFIG_FB_SIS_315  /* 315 series */
5661      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5662      tempebx = SiS_Pr->SiS_VDE;
5663      temp = (tempeax % tempebx);
5664      tempeax = tempeax / tempebx;
5665      if(temp) tempeax++;
5666      tempvcfact = tempeax;
5667 
5668      temp = (unsigned short)(tempeax & 0x00FF);
5669      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5670      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5671      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5672      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5673      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5674      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5675 
5676      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5677         temp = (unsigned short)(tempeax & 0x00FF);
5678         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5679         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5680         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5681         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5682         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5683         temp = 0;
5684         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5685         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5686      }
5687 #endif
5688 
5689   }
5690 
5691   /* Horizontal scaling */
5692 
5693   tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5694   if(chkdclkfirst) {
5695      if(modeflag & HalfDCLK) tempeax >>= 1;
5696   }
5697   tempebx = tempeax << 16;
5698   if(SiS_Pr->SiS_HDE == tempeax) {
5699      tempecx = 0xFFFF;
5700   } else {
5701      tempecx = tempebx / SiS_Pr->SiS_HDE;
5702      if(SiS_Pr->ChipType >= SIS_315H) {
5703         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5704      }
5705   }
5706 
5707   if(SiS_Pr->ChipType >= SIS_315H) {
5708      tempeax = (tempebx / tempecx) - 1;
5709   } else {
5710      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5711   }
5712   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5713   temp = (unsigned short)(tempecx & 0x00FF);
5714   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5715 
5716   if(SiS_Pr->ChipType >= SIS_315H) {
5717      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5718      tempbx = (unsigned short)(tempeax & 0xFFFF);
5719   } else {
5720      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5721      tempbx = tempvcfact & 0x3f;
5722      if(tempbx == 0) tempbx = 64;
5723      tempeax /= tempbx;
5724      tempbx = (unsigned short)(tempeax & 0xFFFF);
5725   }
5726   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5727   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5728      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5729      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
5730   }
5731 
5732   temp = ((tempbx >> 8) & 0x07) << 3;
5733   temp = temp | ((tempecx >> 8) & 0x07);
5734   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5735   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5736 
5737   tempecx >>= 16;						/* BPLHCFACT  */
5738   if(!chkdclkfirst) {
5739      if(modeflag & HalfDCLK) tempecx >>= 1;
5740   }
5741   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5742   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5743   temp = (unsigned short)(tempecx & 0x00FF);
5744   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5745 
5746 #ifdef CONFIG_FB_SIS_315
5747   if(SiS_Pr->ChipType >= SIS_315H) {
5748      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5749         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5750            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5751 	}
5752      } else {
5753         if(islvds) {
5754            if(SiS_Pr->ChipType == SIS_740) {
5755               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5756            } else {
5757 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5758            }
5759         }
5760      }
5761   }
5762 #endif
5763 
5764 #ifdef CONFIG_FB_SIS_300
5765   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5766      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5767      unsigned char *trumpdata;
5768      int   i, j = crt2crtc;
5769      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
5770      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5771      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5772 
5773      if(SiS_Pr->SiS_UseROM) {
5774 	trumpdata = &ROMAddr[0x8001 + (j * 80)];
5775      } else {
5776 	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5777 	trumpdata = &SiS300_TrumpionData[j][0];
5778      }
5779 
5780      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5781      for(i=0; i<5; i++) {
5782 	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5783      }
5784      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5785 	if(ModeNo == 0x13) {
5786 	   for(i=0; i<4; i++) {
5787 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5788 	   }
5789 	} else if(ModeNo == 0x10) {
5790 	   for(i=0; i<4; i++) {
5791 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5792 	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5793 	   }
5794 	}
5795      }
5796      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5797   }
5798 #endif
5799 
5800 #ifdef CONFIG_FB_SIS_315
5801   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5802      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5803      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5804      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5805      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5806      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5807      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5808      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5809      tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5810      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5811         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5812         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5813      tempax += 64;
5814      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5815      temp = (tempax >> 8) << 3;
5816      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5817      tempax += 32;						/* Blpe = lBlps+32 */
5818      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5819      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
5820      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5821 
5822      tempax = SiS_Pr->SiS_VDE;
5823      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5824         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5825         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5826      tempax >>= 1;
5827      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5828      temp = (tempax >> 8) << 3;
5829      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5830 
5831      tempeax = SiS_Pr->SiS_HDE;
5832      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5833         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5834         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5835      tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
5836      temp = tempeax & 0x7f;
5837      tempeax >>= 7;
5838      if(temp) tempeax++;
5839      temp = tempeax & 0x3f;
5840      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5841      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
5842      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5843      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5844      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5845 
5846      tempax = SiS_Pr->SiS_HDE;
5847      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5848         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5849         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5850      tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
5851      pushcx = tempax;
5852      temp = tempax & 0x00FF;
5853      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5854      temp = ((tempax & 0xFF00) >> 8) << 3;
5855      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
5856 
5857      tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5858      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5859         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5860         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5861      tempeax = tempax * pushcx;
5862      temp = tempeax & 0xFF;
5863      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5864      temp = (tempeax & 0xFF00) >> 8;
5865      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5866      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5867      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5868      temp = ((tempeax & 0x01000000) >> 24) << 7;
5869      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
5870 
5871      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5872      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5873      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5874      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5875      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5876 
5877      if(SiS_Pr->SiS_IF_DEF_FSTN) {
5878         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5879         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5880         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5881         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5882         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5883         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5884         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5885         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5886         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5887         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5888         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5889         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5890         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5891         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5892         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5893         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5894         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5895         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5896         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5897         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
5898      }
5899   }
5900 #endif  /* CONFIG_FB_SIS_315 */
5901 }
5902 
5903 /* Set Part 1 */
5904 static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5905 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5906 		unsigned short RefreshRateTableIndex)
5907 {
5908 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
5909   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
5910 #endif
5911   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
5912   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
5913 #ifdef CONFIG_FB_SIS_315
5914   unsigned short  tempbl=0;
5915 #endif
5916 
5917   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5918      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5919      return;
5920   }
5921 
5922   if(ModeNo <= 0x13) {
5923      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5924   } else if(SiS_Pr->UseCustomMode) {
5925      modeflag = SiS_Pr->CModeFlag;
5926   } else {
5927      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
5928      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5929      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5930   }
5931 
5932   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
5933 
5934   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
5935          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
5936          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
5937 
5938      if(SiS_Pr->ChipType < SIS_315H ) {
5939 #ifdef CONFIG_FB_SIS_300
5940 	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
5941 #endif
5942      } else {
5943 #ifdef CONFIG_FB_SIS_315
5944 	SiS_SetCRT2FIFO_310(SiS_Pr);
5945 #endif
5946      }
5947 
5948      /* 1. Horizontal setup */
5949 
5950      if(SiS_Pr->ChipType < SIS_315H ) {
5951 
5952 #ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
5953 
5954 	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
5955 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
5956 
5957 	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
5958 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
5959 
5960 	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
5961 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
5962 
5963 	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
5964 	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
5965 	tempbx = pushbx + tempcx;
5966 	tempcx <<= 1;
5967 	tempcx += tempbx;
5968 
5969 	bridgeadd = 12;
5970 
5971 #endif /* CONFIG_FB_SIS_300 */
5972 
5973      } else {
5974 
5975 #ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
5976 
5977 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
5978 	if(modeflag & HalfDCLK) {
5979 	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
5980 	      tempcx >>= 1;
5981 	   } else {
5982 	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
5983 	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
5984 	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5985 	         tempcx = SiS_Pr->SiS_HT - tempax;
5986 	      }
5987 	   }
5988 	}
5989 	tempcx--;
5990 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
5991 	temp = (tempcx >> 4) & 0xF0;
5992 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
5993 
5994 	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
5995 	tempbx = SiS_Pr->SiS_VGAHDE;
5996 	tempcx -= tempbx;
5997 	tempcx >>= 2;
5998 	if(modeflag & HalfDCLK) {
5999 	   tempbx >>= 1;
6000 	   tempcx >>= 1;
6001 	}
6002 	tempbx += 16;
6003 
6004 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6005 
6006 	pushbx = tempbx;
6007 	tempcx >>= 1;
6008 	tempbx += tempcx;
6009 	tempcx += tempbx;
6010 
6011 	bridgeadd = 16;
6012 
6013 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6014 	   if(SiS_Pr->ChipType >= SIS_661) {
6015 	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6016 		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6017 		 if(resinfo == SIS_RI_1280x1024) {
6018 		    tempcx = (tempcx & 0xff00) | 0x30;
6019 		 } else if(resinfo == SIS_RI_1600x1200) {
6020 		    tempcx = (tempcx & 0xff00) | 0xff;
6021 		 }
6022 	      }
6023 	   }
6024         }
6025 
6026 #endif  /* CONFIG_FB_SIS_315 */
6027 
6028      }  /* 315/330 series */
6029 
6030      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6031 
6032 	if(SiS_Pr->UseCustomMode) {
6033 	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6034 	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6035 	   tempax = SiS_Pr->SiS_VGAHT;
6036 	   if(modeflag & HalfDCLK) tempax >>= 1;
6037 	   tempax--;
6038 	   if(tempcx > tempax) tempcx = tempax;
6039 	}
6040 
6041 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6042 	   unsigned char cr4, cr14, cr5, cr15;
6043 	   if(SiS_Pr->UseCustomMode) {
6044 	      cr4  = SiS_Pr->CCRT1CRTC[4];
6045 	      cr14 = SiS_Pr->CCRT1CRTC[14];
6046 	      cr5  = SiS_Pr->CCRT1CRTC[5];
6047 	      cr15 = SiS_Pr->CCRT1CRTC[15];
6048 	   } else {
6049 	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6050 	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6051 	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6052 	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6053 	   }
6054 	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6055 	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6056 	   tempcx &= 0x00FF;
6057 	   tempcx |= (tempbx & 0xFF00);
6058 	   tempbx += bridgeadd;
6059 	   tempcx += bridgeadd;
6060 	   tempax = SiS_Pr->SiS_VGAHT;
6061 	   if(modeflag & HalfDCLK) tempax >>= 1;
6062 	   tempax--;
6063 	   if(tempcx > tempax) tempcx = tempax;
6064 	}
6065 
6066 	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6067 	   tempbx = 1040;
6068 	   tempcx = 1044;   /* HWCursor bug! */
6069 	}
6070 
6071      }
6072 
6073      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6074 
6075      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6076 
6077      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6078      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6079 
6080      /* 2. Vertical setup */
6081 
6082      tempcx = SiS_Pr->SiS_VGAVT - 1;
6083      temp = tempcx & 0x00FF;
6084 
6085      if(SiS_Pr->ChipType < SIS_661) {
6086         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6087 	   if(SiS_Pr->ChipType < SIS_315H) {
6088 	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6089 	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6090 	            temp--;
6091 	         }
6092 	      }
6093 	   } else {
6094 	      temp--;
6095 	   }
6096 	} else if(SiS_Pr->ChipType >= SIS_315H) {
6097 	   temp--;
6098 	}
6099      }
6100      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6101 
6102      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6103      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6104 
6105      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6106      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6107 
6108      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6109 	tempbx++;
6110 	tempax = tempbx;
6111 	tempcx++;
6112 	tempcx -= tempax;
6113 	tempcx >>= 2;
6114 	tempbx += tempcx;
6115 	if(tempcx < 4) tempcx = 4;
6116 	tempcx >>= 2;
6117 	tempcx += tempbx;
6118 	tempcx++;
6119      } else {
6120 	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6121 	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6122      }
6123 
6124      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6125 	if(SiS_Pr->UseCustomMode) {
6126 	   tempbx = SiS_Pr->CVSyncStart;
6127 	   tempcx = SiS_Pr->CVSyncEnd;
6128 	}
6129 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6130 	   unsigned char cr8, cr7, cr13;
6131 	   if(SiS_Pr->UseCustomMode) {
6132 	      cr8    = SiS_Pr->CCRT1CRTC[8];
6133 	      cr7    = SiS_Pr->CCRT1CRTC[7];
6134 	      cr13   = SiS_Pr->CCRT1CRTC[13];
6135 	      tempcx = SiS_Pr->CCRT1CRTC[9];
6136 	   } else {
6137 	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6138 	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6139 	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6140 	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6141 	   }
6142 	   tempbx = cr8;
6143 	   if(cr7  & 0x04) tempbx |= 0x0100;
6144 	   if(cr7  & 0x80) tempbx |= 0x0200;
6145 	   if(cr13 & 0x08) tempbx |= 0x0400;
6146 	}
6147      }
6148      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6149 
6150      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6151      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6152 
6153      /* 3. Panel delay compensation */
6154 
6155      if(SiS_Pr->ChipType < SIS_315H) {
6156 
6157 #ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
6158 
6159 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6160 	   temp = 0x20;
6161 	   if(SiS_Pr->ChipType == SIS_300) {
6162 	      temp = 0x10;
6163 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6164 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6165 	   }
6166 	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6167 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6168 	   }
6169 	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6170 	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6171 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6172 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6173 	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6174 	      else 					    temp = 0x20;
6175 	   }
6176 	   if(SiS_Pr->SiS_UseROM) {
6177 	      if(ROMAddr[0x220] & 0x80) {
6178 		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6179 		    temp = ROMAddr[0x221];
6180 		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6181 		    temp = ROMAddr[0x222];
6182 		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6183 		    temp = ROMAddr[0x223];
6184 		 else
6185 		    temp = ROMAddr[0x224];
6186 	      }
6187 	   }
6188 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6189 	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6190 	   }
6191 
6192 	} else {
6193 	   temp = 0x20;
6194 	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6195 	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6196 	   }
6197 	   if(SiS_Pr->SiS_UseROM) {
6198 	      if(ROMAddr[0x220] & 0x80) {
6199 	         temp = ROMAddr[0x220];
6200 	      }
6201 	   }
6202 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6203 	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6204 	   }
6205 	}
6206 
6207 	temp &= 0x3c;
6208 
6209 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6210 
6211 #endif  /* CONFIG_FB_SIS_300 */
6212 
6213      } else {
6214 
6215 #ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
6216 
6217 	if(SiS_Pr->ChipType < SIS_661) {
6218 
6219 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6220 
6221 	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6222 	      else 		              temp = 0x00;
6223 
6224 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6225 	      tempbl = 0xF0;
6226 	      if(SiS_Pr->ChipType == SIS_650) {
6227 		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6228 		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6229 		 }
6230 	      }
6231 
6232 	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6233 		 temp = 0x08;
6234 		 tempbl = 0;
6235 		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6236 		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6237 		 }
6238 	      }
6239 
6240 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6241 	   }
6242 
6243 	} /* < 661 */
6244 
6245 	tempax = 0;
6246 	if(modeflag & DoubleScanMode) tempax |= 0x80;
6247 	if(modeflag & HalfDCLK)       tempax |= 0x40;
6248 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6249 
6250 #endif  /* CONFIG_FB_SIS_315 */
6251 
6252      }
6253 
6254   }  /* Slavemode */
6255 
6256   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6257      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6258 	/* For 301BDH with LCD, we set up the Panel Link */
6259 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6260      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6261 	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6262      }
6263   } else {
6264      if(SiS_Pr->ChipType < SIS_315H) {
6265 	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6266      } else {
6267 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6268 	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6269 	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6270 	   }
6271 	} else {
6272 	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6273 	}
6274      }
6275   }
6276 }
6277 
6278 /*********************************************/
6279 /*         SET PART 2 REGISTER GROUP         */
6280 /*********************************************/
6281 
6282 #ifdef CONFIG_FB_SIS_315
6283 static unsigned char *
SiS_GetGroup2CLVXPtr(struct SiS_Private * SiS_Pr,int tabletype)6284 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6285 {
6286    const unsigned char *tableptr = NULL;
6287    unsigned short      a, b, p = 0;
6288 
6289    a = SiS_Pr->SiS_VGAHDE;
6290    b = SiS_Pr->SiS_HDE;
6291    if(tabletype) {
6292       a = SiS_Pr->SiS_VGAVDE;
6293       b = SiS_Pr->SiS_VDE;
6294    }
6295 
6296    if(a < b) {
6297       tableptr = SiS_Part2CLVX_1;
6298    } else if(a == b) {
6299       tableptr = SiS_Part2CLVX_2;
6300    } else {
6301       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6302 	 tableptr = SiS_Part2CLVX_4;
6303       } else {
6304 	 tableptr = SiS_Part2CLVX_3;
6305       }
6306       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6307 	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
6308 	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
6309 	 else 				         	tableptr = SiS_Part2CLVX_5;
6310       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6311 	 tableptr = SiS_Part2CLVX_6;
6312       }
6313       do {
6314 	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6315 	 p += 0x42;
6316       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6317       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6318    }
6319    p += 2;
6320    return ((unsigned char *)&tableptr[p]);
6321 }
6322 
6323 static void
SiS_SetGroup2_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6324 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6325 	      	    unsigned short RefreshRateTableIndex)
6326 {
6327    unsigned char *tableptr;
6328    unsigned char temp;
6329    int i, j;
6330 
6331    if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6332 
6333    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6334    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6335       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6336    }
6337    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6338       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6339       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6340          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6341       }
6342    }
6343    temp = 0x10;
6344    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6345    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6346 }
6347 
6348 static bool
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6349 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6350 		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6351 		    unsigned short *ResIndex)
6352 {
6353 
6354   if(SiS_Pr->ChipType < SIS_315H) return false;
6355 
6356   if(ModeNo <= 0x13)
6357      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6358   else
6359      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6360 
6361   (*ResIndex) &= 0x3f;
6362   (*CRT2Index) = 0;
6363 
6364   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6365      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6366         (*CRT2Index) = 200;
6367      }
6368   }
6369 
6370   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6371      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6372         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6373      }
6374   }
6375   return (((*CRT2Index) != 0));
6376 }
6377 #endif
6378 
6379 #ifdef CONFIG_FB_SIS_300
6380 static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6381 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6382 {
6383    unsigned short tempcx;
6384    static const unsigned char atable[] = {
6385        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6386        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6387    };
6388 
6389    if(!SiS_Pr->UseCustomMode) {
6390       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6391 	      (SiS_Pr->ChipType == SIS_730) ) &&
6392 	    (SiS_Pr->ChipRevision > 2) )  &&
6393 	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6394 	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6395 	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6396 	 if(ModeNo == 0x13) {
6397 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6398 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6399 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6400 	 } else if((crt2crtc & 0x3F) == 4) {
6401 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6402 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6403 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6404 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6405 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6406 	 }
6407       }
6408 
6409       if(SiS_Pr->ChipType < SIS_315H) {
6410 	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6411 	    crt2crtc &= 0x1f;
6412 	    tempcx = 0;
6413 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6414 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6415 		  tempcx += 7;
6416 	       }
6417 	    }
6418 	    tempcx += crt2crtc;
6419 	    if(crt2crtc >= 4) {
6420 	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6421 	    }
6422 
6423 	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6424 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6425 		  if(crt2crtc == 4) {
6426 		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6427 		  }
6428 	       }
6429 	    }
6430 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6431 	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6432 	 }
6433       }
6434    }
6435 }
6436 
6437 /* For ECS A907. Highly preliminary. */
6438 static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6439 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6440 		    unsigned short ModeNo)
6441 {
6442   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6443   unsigned short crt2crtc, resindex;
6444   int i, j;
6445 
6446   if(SiS_Pr->ChipType != SIS_300) return;
6447   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6448   if(SiS_Pr->UseCustomMode) return;
6449 
6450   if(ModeNo <= 0x13) {
6451      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6452   } else {
6453      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6454   }
6455 
6456   resindex = crt2crtc & 0x3F;
6457   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6458   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6459 
6460   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6461   if(ModeNo > 0x13) {
6462      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6463      resindex = 4;
6464   }
6465 
6466   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6467   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6468   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6469      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6470   }
6471   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6472      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6473   }
6474   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6475      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6476   }
6477   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6478   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6479 }
6480 #endif
6481 
6482 static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6483 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6484 {
6485   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6486   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6487   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6488 
6489   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6490      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6491         const unsigned char specialtv[] = {
6492 		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6493 		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6494 		0x58,0xe4,0x73,0xda,0x13
6495 	};
6496 	int i, j;
6497 	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6498 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6499 	}
6500 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6501 	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6502 	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6503 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6504 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6505 	   } else {
6506 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6507 	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6508 	   }
6509 	}
6510      }
6511   } else {
6512      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6513         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6514         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6515         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6516      } else {
6517         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6518         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6519      }
6520   }
6521 }
6522 
6523 static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6524 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6525 {
6526   unsigned short temp;
6527 
6528   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6529      if(SiS_Pr->SiS_VGAVDE == 525) {
6530 	temp = 0xc3;
6531 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6532 	   temp++;
6533 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6534 	}
6535 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6536 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6537      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6538 	temp = 0x4d;
6539 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6540 	   temp++;
6541 	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6542 	}
6543 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6544      }
6545   }
6546 
6547   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6548      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6549 	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6550 	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6551 	   /* Not always for LV, see SetGrp2 */
6552 	}
6553 	temp = 1;
6554 	if(ModeNo <= 0x13) temp = 3;
6555 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6556      }
6557 #if 0
6558      /* 651+301C, for 1280x768 - do I really need that? */
6559      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6560         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6561 	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6562 	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6563 	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6564 	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
6565 	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6566 	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
6567 	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6568 	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6569 	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6570 	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6571 	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
6572 	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6573 	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6574 	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
6575 	   }
6576 	}
6577      }
6578 #endif
6579   }
6580 }
6581 
6582 static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6583 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6584 		unsigned short RefreshRateTableIndex)
6585 {
6586   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6587   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6588   unsigned int   longtemp, PhaseIndex;
6589   bool           newtvphase;
6590   const unsigned char *TimingPoint;
6591 #ifdef CONFIG_FB_SIS_315
6592   unsigned short resindex, CRT2Index;
6593   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6594 
6595   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6596 #endif
6597 
6598   if(ModeNo <= 0x13) {
6599      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6600      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6601   } else if(SiS_Pr->UseCustomMode) {
6602      modeflag = SiS_Pr->CModeFlag;
6603      crt2crtc = 0;
6604   } else {
6605      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6606      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6607   }
6608 
6609   temp = 0;
6610   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6611   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6612   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6613   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6614 
6615   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
6616 
6617   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6618 
6619   PhaseIndex  = 0x01; /* SiS_PALPhase */
6620   TimingPoint = SiS_Pr->SiS_PALTiming;
6621 
6622   newtvphase = false;
6623   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6624       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6625 	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6626      newtvphase = true;
6627   }
6628 
6629   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6630 
6631      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6632      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6633         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6634         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6635 	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6636         }
6637      }
6638 
6639   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6640 
6641      i = 0;
6642      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6643      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6644 
6645      TimingPoint = &SiS_YPbPrTable[i][0];
6646 
6647      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6648 
6649   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6650 
6651      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6652 
6653   } else {
6654 
6655      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6656      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
6657      if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
6658 
6659   }
6660 
6661   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6662      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
6663      if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
6664   }
6665 
6666   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6667      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6668         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6669      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6670         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6671      } else {
6672         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6673      }
6674   }
6675 
6676   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6677      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6678   }
6679 
6680   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6681      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6682   }
6683   for(i = 0x39; i <= 0x45; i++, j++) {
6684      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6685   }
6686 
6687   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6688      if(SiS_Pr->SiS_ModeType != ModeText) {
6689         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6690      }
6691   }
6692 
6693   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6694 
6695   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6696   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6697   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6698   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6699 
6700   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
6701   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
6702   else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;
6703   else						tempax = 440; /* NTSC, YPbPr 525 */
6704 
6705   if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6706       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6707         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6708 
6709      tempax -= SiS_Pr->SiS_VDE;
6710      tempax >>= 1;
6711      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6712         tempax >>= 1;
6713      }
6714      tempax &= 0x00ff;
6715 
6716      temp = tempax + (unsigned short)TimingPoint[0];
6717      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6718 
6719      temp = tempax + (unsigned short)TimingPoint[1];
6720      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6721 
6722      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6723         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6724            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6725            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6726         } else {
6727            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6728            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6729         }
6730      }
6731 
6732   }
6733 
6734   tempcx = SiS_Pr->SiS_HT;
6735   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6736   tempcx--;
6737   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6738   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6739   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6740 
6741   tempcx = SiS_Pr->SiS_HT >> 1;
6742   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6743   tempcx += 7;
6744   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6745   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6746 
6747   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6748   tempbx += tempcx;
6749   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6750   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6751 
6752   tempbx += 8;
6753   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6754      tempbx -= 4;
6755      tempcx = tempbx;
6756   }
6757   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6758 
6759   j += 2;
6760   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6761   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6762   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6763 
6764   tempcx += 8;
6765   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6766   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6767 
6768   tempcx = SiS_Pr->SiS_HT >> 1;
6769   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6770   j += 2;
6771   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6772   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6773 
6774   tempcx -= 11;
6775   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6776      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6777   }
6778   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6779 
6780   tempbx = SiS_Pr->SiS_VDE;
6781   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6782      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6783      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6784      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6785   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6786              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6787      tempbx >>= 1;
6788      if(SiS_Pr->ChipType >= SIS_315H) {
6789         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6790 	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6791 	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6792 	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6793 	      if(crt2crtc == 4) tempbx++;
6794 	   }
6795 	}
6796      }
6797      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6798         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6799 	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6800 	}
6801 	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6802 	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6803         }
6804      }
6805   }
6806   tempbx -= 2;
6807   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6808 
6809   temp = (tempcx >> 8) & 0x0F;
6810   temp |= ((tempbx >> 2) & 0xC0);
6811   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6812      temp |= 0x10;
6813      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6814   }
6815   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6816 
6817   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6818      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6819   }
6820 
6821   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6822      tempbx = SiS_Pr->SiS_VDE;
6823      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6824          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6825         tempbx >>= 1;
6826      }
6827      tempbx -= 3;
6828      temp = ((tempbx >> 3) & 0x60) | 0x18;
6829      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6830      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6831 
6832      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6833 	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6834      }
6835   }
6836 
6837   tempbx = 0;
6838   if(!(modeflag & HalfDCLK)) {
6839      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6840         tempax = 0;
6841         tempbx |= 0x20;
6842      }
6843   }
6844 
6845   tempch = tempcl = 0x01;
6846   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6847      if(SiS_Pr->SiS_VGAHDE >= 960) {
6848         if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6849 	   tempcl = 0x20;
6850 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
6851               tempch = 20;
6852               tempbx &= ~0x20;
6853            } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6854               tempch = 25;
6855            } else {
6856 	      tempch = 25; /* OK */
6857 	   }
6858         }
6859      }
6860   }
6861 
6862   if(!(tempbx & 0x20)) {
6863      if(modeflag & HalfDCLK) tempcl <<= 1;
6864      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6865      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6866      tempax = longtemp / SiS_Pr->SiS_HDE;
6867      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6868      tempbx |= ((tempax >> 8) & 0x1F);
6869      tempcx = tempax >> 13;
6870   }
6871 
6872   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6873   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6874 
6875   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6876 
6877      tempcx &= 0x07;
6878      if(tempbx & 0x20) tempcx = 0;
6879      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6880 
6881      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6882         tempbx = 0x0382;
6883         tempcx = 0x007e;
6884      } else {
6885         tempbx = 0x0369;
6886         tempcx = 0x0061;
6887      }
6888      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6889      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6890      temp = (tempcx & 0x0300) >> 6;
6891      temp |= ((tempbx >> 8) & 0x03);
6892      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6893         temp |= 0x10;
6894 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
6895 	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6896      }
6897      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
6898 
6899      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
6900      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
6901 
6902      SiS_SetTVSpecial(SiS_Pr, ModeNo);
6903 
6904      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
6905         temp = 0;
6906         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
6907         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
6908      }
6909 
6910   }
6911 
6912   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6913      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
6914         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
6915         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
6916      }
6917      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
6918   }
6919 
6920   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6921      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6922         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
6923      }
6924   }
6925 
6926   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
6927 
6928   /* From here: Part2 LCD setup */
6929 
6930   tempbx = SiS_Pr->SiS_HDE;
6931   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
6932   tempbx--;			         	/* RHACTE = HDE - 1 */
6933   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
6934   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
6935 
6936   temp = 0x01;
6937   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
6938      if(SiS_Pr->SiS_ModeType == ModeEGA) {
6939         if(SiS_Pr->SiS_VGAHDE >= 1024) {
6940            temp = 0x02;
6941            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
6942               temp = 0x01;
6943 	   }
6944         }
6945      }
6946   }
6947   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
6948 
6949   tempbx = SiS_Pr->SiS_VDE - 1;
6950   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
6951   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
6952 
6953   tempcx = SiS_Pr->SiS_VT - 1;
6954   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
6955   temp = (tempcx >> 3) & 0xE0;
6956   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
6957      /* Enable dithering; only do this for 32bpp mode */
6958      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
6959         temp |= 0x10;
6960      }
6961   }
6962   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
6963 
6964   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
6965   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
6966 
6967   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
6968   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
6969 
6970 #ifdef CONFIG_FB_SIS_315
6971   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
6972                           			&CRT2Index, &resindex)) {
6973       switch(CRT2Index) {
6974         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
6975 	default:
6976         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
6977       }
6978 
6979       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6980       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6981       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6982         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6983       }
6984       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6985         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6986       }
6987       for(j = 0x1f; j <= 0x21; i++, j++ ) {
6988         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6989       }
6990       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6991       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6992 
6993       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
6994 
6995   } else {
6996 #endif
6997 
6998     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
6999     /*             Clevo dual-link 1024x768 */
7000     /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7001     /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7002 
7003     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7004        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7005           tempbx = SiS_Pr->SiS_VDE - 1;
7006           tempcx = SiS_Pr->SiS_VT - 1;
7007        } else {
7008           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7009 	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7010        }
7011     } else {
7012        tempbx = SiS_Pr->PanelYRes;
7013        tempcx = SiS_Pr->SiS_VT;
7014        tempax = 1;
7015        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7016           tempax = SiS_Pr->PanelYRes;
7017 	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7018           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7019              tempax = tempcx = 0;
7020           } else {
7021              tempax -= SiS_Pr->SiS_VDE;
7022           }
7023           tempax >>= 1;
7024        }
7025        tempcx -= tempax; /* lcdvdes */
7026        tempbx -= tempax; /* lcdvdee */
7027     }
7028 
7029     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7030 
7031     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7032     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7033 
7034     temp = (tempbx >> 5) & 0x38;
7035     temp |= ((tempcx >> 8) & 0x07);
7036     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7037 
7038     tempax = SiS_Pr->SiS_VDE;
7039     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7040        tempax = SiS_Pr->PanelYRes;
7041     }
7042     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7043     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7044        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7045 	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7046        }
7047     }
7048 
7049     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7050     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7051        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7052           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7053              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7054 	     if(tempax % 4) { tempax >>= 2; tempax++; }
7055 	     else           { tempax >>= 2;           }
7056              tempbx -= (tempax - 1);
7057 	  } else {
7058 	     tempbx -= 10;
7059 	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7060 	  }
7061        }
7062     }
7063     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7064        tempbx++;
7065        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7066           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7067 	     tempbx = 770;
7068 	     tempcx = 3;
7069 	  }
7070        }
7071     }
7072 
7073     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7074 
7075     if(SiS_Pr->UseCustomMode) {
7076        tempbx = SiS_Pr->CVSyncStart;
7077     }
7078 
7079     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7080 
7081     temp = (tempbx >> 4) & 0xF0;
7082     tempbx += (tempcx + 1);
7083     temp |= (tempbx & 0x0F);
7084 
7085     if(SiS_Pr->UseCustomMode) {
7086        temp &= 0xf0;
7087        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7088     }
7089 
7090     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7091 
7092 #ifdef CONFIG_FB_SIS_300
7093     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7094 #endif
7095 
7096     bridgeoffset = 7;
7097     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7098     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7099     if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7100     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7101     /* Higher bridgeoffset shifts to the LEFT */
7102 
7103     temp = 0;
7104     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7105        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7106 	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7107 	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7108        }
7109     }
7110     temp += bridgeoffset;
7111     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7112     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7113 
7114     tempcx = SiS_Pr->SiS_HT;
7115     tempax = tempbx = SiS_Pr->SiS_HDE;
7116     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7117        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7118           tempax = SiS_Pr->PanelXRes;
7119           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7120        }
7121     }
7122     if(SiS_IsDualLink(SiS_Pr)) {
7123        tempcx >>= 1;
7124        tempbx >>= 1;
7125        tempax >>= 1;
7126     }
7127 
7128     tempbx += bridgeoffset;
7129 
7130     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7131     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7132 
7133     tempcx = (tempcx - tempax) >> 2;
7134 
7135     tempbx += tempcx;
7136     push2 = tempbx;
7137 
7138     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7139        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7140           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7141              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7142 	  }
7143        }
7144     }
7145 
7146     if(SiS_Pr->UseCustomMode) {
7147        tempbx = SiS_Pr->CHSyncStart;
7148        if(modeflag & HalfDCLK) tempbx <<= 1;
7149        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7150        tempbx += bridgeoffset;
7151     }
7152 
7153     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7154     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7155 
7156     tempbx = push2;
7157 
7158     tempcx <<= 1;
7159     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7160        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7161     }
7162     tempbx += tempcx;
7163 
7164     if(SiS_Pr->UseCustomMode) {
7165        tempbx = SiS_Pr->CHSyncEnd;
7166        if(modeflag & HalfDCLK) tempbx <<= 1;
7167        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7168        tempbx += bridgeoffset;
7169     }
7170 
7171     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7172 
7173     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7174 
7175 #ifdef CONFIG_FB_SIS_300
7176     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7177 #endif
7178 #ifdef CONFIG_FB_SIS_315
7179   } /* CRT2-LCD from table */
7180 #endif
7181 }
7182 
7183 /*********************************************/
7184 /*         SET PART 3 REGISTER GROUP         */
7185 /*********************************************/
7186 
7187 static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7188 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7189 {
7190   unsigned short i;
7191   const unsigned char *tempdi;
7192 
7193   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7194 
7195 #ifndef SIS_CP
7196   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7197 #else
7198   SIS_CP_INIT301_CP
7199 #endif
7200 
7201   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7202      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7203      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7204   } else {
7205      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7206      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7207   }
7208 
7209   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7210      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7211      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7212      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7213   }
7214 
7215   tempdi = NULL;
7216   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7217      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7218      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7219         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7220      }
7221   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7222      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7223         tempdi = SiS_HiTVGroup3_1;
7224         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7225      }
7226   }
7227   if(tempdi) {
7228      for(i=0; i<=0x3E; i++) {
7229         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7230      }
7231      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7232 	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7233 	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7234 	}
7235      }
7236   }
7237 
7238 #ifdef SIS_CP
7239   SIS_CP_INIT301_CP2
7240 #endif
7241 }
7242 
7243 /*********************************************/
7244 /*         SET PART 4 REGISTER GROUP         */
7245 /*********************************************/
7246 
7247 #ifdef CONFIG_FB_SIS_315
7248 #if 0
7249 static void
7250 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7251 {
7252    unsigned short temp, temp1, temp2;
7253 
7254    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7255    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7256    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7257    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7258    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7259    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7260    temp = (unsigned short)((int)(temp) + shift);
7261    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7262    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7263    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7264    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7265    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7266    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7267 }
7268 #endif
7269 
7270 static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7271 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7272 {
7273    unsigned short temp, temp1, resinfo = 0;
7274    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7275 
7276    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7277    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7278 
7279    if(SiS_Pr->ChipType >= XGI_20) return;
7280 
7281    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7282       if(!(ROMAddr[0x61] & 0x04)) return;
7283    }
7284 
7285    if(ModeNo > 0x13) {
7286       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7287    }
7288 
7289    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7290    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7291    if(!(temp & 0x01)) {
7292       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7293       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7294       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7295          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7296       }
7297       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7298       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7299       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7300       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7301       else					   temp = 0x0402;
7302       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7303          temp1 = 0;
7304 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7305 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7306 	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7307 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7308 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7309 	 if(ModeNo > 0x13) {
7310             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7311          }
7312       } else {
7313          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7314 	 if(temp1 == 0x01) temp |= 0x01;
7315 	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7316 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7317 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7318 	 if(ModeNo > 0x13) {
7319             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7320          }
7321       }
7322 
7323 #if 0
7324       if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7325          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7326             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7327 	       if(resinfo == SIS_RI_1024x768) {
7328 	          SiS_ShiftXPos(SiS_Pr, 97);
7329 	       } else {
7330 	          SiS_ShiftXPos(SiS_Pr, 111);
7331 	       }
7332 	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7333 	       SiS_ShiftXPos(SiS_Pr, 136);
7334 	    }
7335          }
7336       }
7337 #endif
7338 
7339    }
7340 
7341 }
7342 #endif
7343 
7344 static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7345 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7346                  unsigned short RefreshRateTableIndex)
7347 {
7348   unsigned short vclkindex, temp, reg1, reg2;
7349 
7350   if(SiS_Pr->UseCustomMode) {
7351      reg1 = SiS_Pr->CSR2B;
7352      reg2 = SiS_Pr->CSR2C;
7353   } else {
7354      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7355      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7356      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7357   }
7358 
7359   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7360      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7361         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7362  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7363 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7364      } else {
7365         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7366         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7367      }
7368   } else {
7369      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7370      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7371      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7372   }
7373   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7374   temp = 0x08;
7375   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7376   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7377 }
7378 
7379 static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7380 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7381 {
7382   if(SiS_Pr->ChipType >= SIS_315H) {
7383      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7384 	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7385 	   (SiS_IsVAMode(SiS_Pr))) {
7386 	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7387 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7388 	   } else {
7389 	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7390 	   }
7391 	}
7392      }
7393   }
7394   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7395      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7396 #ifdef SET_EMI
7397      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7398 #endif
7399      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7400   }
7401 }
7402 
7403 static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7404 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7405 		unsigned short RefreshRateTableIndex)
7406 {
7407   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7408   unsigned int   tempebx, tempeax, templong;
7409 
7410   if(ModeNo <= 0x13) {
7411      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7412      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7413   } else if(SiS_Pr->UseCustomMode) {
7414      modeflag = SiS_Pr->CModeFlag;
7415      resinfo = 0;
7416   } else {
7417      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7418      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7419   }
7420 
7421   if(SiS_Pr->ChipType >= SIS_315H) {
7422      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7423 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7424 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7425 	}
7426      }
7427   }
7428 
7429   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7430      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7431 	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7432      }
7433   }
7434 
7435   if(SiS_Pr->ChipType >= SIS_315H) {
7436      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7437 	SiS_SetDualLinkEtc(SiS_Pr);
7438 	return;
7439      }
7440   }
7441 
7442   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7443 
7444   tempbx = SiS_Pr->SiS_RVBHCMAX;
7445   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7446 
7447   temp = (tempbx >> 1) & 0x80;
7448 
7449   tempcx = SiS_Pr->SiS_VGAHT - 1;
7450   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7451 
7452   temp |= ((tempcx >> 5) & 0x78);
7453 
7454   tempcx = SiS_Pr->SiS_VGAVT - 1;
7455   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7456   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7457 
7458   temp |= ((tempcx >> 8) & 0x07);
7459   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7460 
7461   tempbx = SiS_Pr->SiS_VGAHDE;
7462   if(modeflag & HalfDCLK)    tempbx >>= 1;
7463   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7464 
7465   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7466      temp = 0;
7467      if(tempbx > 800)        temp = 0x60;
7468   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7469      temp = 0;
7470      if(tempbx > 1024)       temp = 0xC0;
7471      else if(tempbx >= 960)  temp = 0xA0;
7472   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7473      temp = 0;
7474      if(tempbx >= 1280)      temp = 0x40;
7475      else if(tempbx >= 1024) temp = 0x20;
7476   } else {
7477      temp = 0x80;
7478      if(tempbx >= 1024)      temp = 0xA0;
7479   }
7480 
7481   temp |= SiS_Pr->Init_P4_0E;
7482 
7483   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7484      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7485         temp &= 0xf0;
7486         temp |= 0x0A;
7487      }
7488   }
7489 
7490   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7491 
7492   tempeax = SiS_Pr->SiS_VGAVDE;
7493   tempebx = SiS_Pr->SiS_VDE;
7494   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7495      if(!(temp & 0xE0)) tempebx >>=1;
7496   }
7497 
7498   tempcx = SiS_Pr->SiS_RVBHRS;
7499   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7500   tempcx >>= 8;
7501   tempcx |= 0x40;
7502 
7503   if(tempeax <= tempebx) {
7504      tempcx ^= 0x40;
7505   } else {
7506      tempeax -= tempebx;
7507   }
7508 
7509   tempeax *= (256 * 1024);
7510   templong = tempeax % tempebx;
7511   tempeax /= tempebx;
7512   if(templong) tempeax++;
7513 
7514   temp = (unsigned short)(tempeax & 0x000000FF);
7515   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7516   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7517   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7518   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7519   temp |= (tempcx & 0x4F);
7520   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7521 
7522   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7523 
7524      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7525 
7526      /* Calc Linebuffer max address and set/clear decimode */
7527      tempbx = 0;
7528      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7529      tempax = SiS_Pr->SiS_VGAHDE;
7530      if(modeflag & HalfDCLK)    tempax >>= 1;
7531      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7532      if(tempax > 800) {
7533         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7534 	   tempax -= 800;
7535 	} else {
7536 	   tempbx = 0x08;
7537 	   if(tempax == 960)	   tempax *= 25; /* Correct */
7538            else if(tempax == 1024) tempax *= 25;
7539            else			   tempax *= 20;
7540 	   temp = tempax % 32;
7541 	   tempax /= 32;
7542 	   if(temp) tempax++;
7543 	   tempax++;
7544 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7545 	      if(resinfo == SIS_RI_1024x768 ||
7546 	         resinfo == SIS_RI_1024x576 ||
7547 		 resinfo == SIS_RI_1280x1024 ||
7548 		 resinfo == SIS_RI_1280x720) {
7549 	         /* Otherwise white line or garbage at right edge */
7550 	         tempax = (tempax & 0xff00) | 0x20;
7551 	      }
7552 	   }
7553 	}
7554      }
7555      tempax--;
7556      temp = ((tempax >> 4) & 0x30) | tempbx;
7557      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7558      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7559 
7560      temp = 0x0036; tempbx = 0xD0;
7561      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7562 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7563      }
7564      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7565         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7566 	   temp |= 0x01;
7567 	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7568 	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7569   	         temp &= ~0x01;
7570 	      }
7571 	   }
7572 	}
7573      }
7574      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7575 
7576      tempbx = SiS_Pr->SiS_HT >> 1;
7577      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7578      tempbx -= 2;
7579      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7580      temp = (tempbx >> 5) & 0x38;
7581      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7582 
7583      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7584 	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7585            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7586 	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7587 	}
7588      }
7589 
7590      SiS_SetDualLinkEtc(SiS_Pr);
7591 
7592   }  /* 301B */
7593 
7594   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7595 }
7596 
7597 /*********************************************/
7598 /*         SET PART 5 REGISTER GROUP         */
7599 /*********************************************/
7600 
7601 static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7602 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7603 {
7604 
7605   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7606 
7607   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7608      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7609         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7610         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7611      }
7612   }
7613 }
7614 
7615 /*********************************************/
7616 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7617 /*********************************************/
7618 
7619 static bool
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7620 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7621 		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7622 		   unsigned short *DisplayType)
7623  {
7624   unsigned short modeflag = 0;
7625   bool checkhd = true;
7626 
7627   /* Pass 1:1 not supported here */
7628 
7629   if(ModeNo <= 0x13) {
7630      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7631      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7632   } else {
7633      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7634      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7635   }
7636 
7637   (*ResIndex) &= 0x3F;
7638 
7639   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7640 
7641      (*DisplayType) = 80;
7642      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7643       	(*DisplayType) = 82;
7644 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7645 	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7646 	}
7647      }
7648      if((*DisplayType) != 84) {
7649         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7650      }
7651 
7652   } else {
7653 
7654      (*DisplayType = 0);
7655      switch(SiS_Pr->SiS_LCDResInfo) {
7656      case Panel_320x240_1: (*DisplayType) = 50;
7657 			   checkhd = false;
7658 			   break;
7659      case Panel_320x240_2: (*DisplayType) = 14;
7660 			   break;
7661      case Panel_320x240_3: (*DisplayType) = 18;
7662 			   break;
7663      case Panel_640x480:   (*DisplayType) = 10;
7664 			   break;
7665      case Panel_1024x600:  (*DisplayType) = 26;
7666 			   break;
7667      default: return true;
7668      }
7669 
7670      if(checkhd) {
7671         if(modeflag & HalfDCLK) (*DisplayType)++;
7672      }
7673 
7674      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7675         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7676      }
7677 
7678   }
7679 
7680   return true;
7681 }
7682 
7683 static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7684 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7685                 unsigned short RefreshRateTableIndex)
7686 {
7687   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7688   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7689   static const unsigned short CRIdx[] = {
7690 	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7691 	0x07, 0x10, 0x11, 0x15, 0x16
7692   };
7693 
7694   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7695      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7696      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
7697      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7698      return;
7699 
7700   if(SiS_Pr->SiS_IF_DEF_LVDS) {
7701      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7702         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7703      }
7704   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7705      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7706   } else return;
7707 
7708   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7709 
7710   if(SiS_Pr->ChipType < SIS_315H) {
7711      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7712   }
7713 
7714   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7715                           &ResIndex, &DisplayType))) {
7716      return;
7717   }
7718 
7719   switch(DisplayType) {
7720     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
7721     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
7722     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
7723     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
7724     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
7725     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
7726     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
7727 #if 0 /* Works better with calculated numbers */
7728     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
7729     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
7730     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
7731     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
7732 #endif
7733     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
7734     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
7735     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
7736     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
7737     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
7738   }
7739 
7740   if(LVDSCRT1Ptr) {
7741 
7742      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7743 
7744      for(i = 0; i <= 10; i++) {
7745         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7746         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7747      }
7748 
7749      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7750         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7751         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7752      }
7753 
7754      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7755      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7756 
7757      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7758      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7759 
7760      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7761      if(modeflag & DoubleScanMode) tempah |= 0x80;
7762      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7763 
7764   } else {
7765 
7766      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7767 
7768   }
7769 }
7770 
7771 /*********************************************/
7772 /*              SET CRT2 ECLK                */
7773 /*********************************************/
7774 
7775 static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7776 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7777            unsigned short RefreshRateTableIndex)
7778 {
7779   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7780   unsigned short clkbase, vclkindex = 0;
7781   unsigned char  sr2b, sr2c;
7782 
7783   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7784      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7785      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7786 	RefreshRateTableIndex--;
7787      }
7788      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7789                                     RefreshRateTableIndex);
7790      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7791   } else {
7792      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7793                                     RefreshRateTableIndex);
7794   }
7795 
7796   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7797   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7798 
7799   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7800      if(SiS_Pr->SiS_UseROM) {
7801 	if(ROMAddr[0x220] & 0x01) {
7802 	   sr2b = ROMAddr[0x227];
7803 	   sr2c = ROMAddr[0x228];
7804 	}
7805      }
7806   }
7807 
7808   clkbase = 0x02B;
7809   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7810      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7811 	clkbase += 3;
7812      }
7813   }
7814 
7815   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7816   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7817   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7818   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7819   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7820   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7821   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7822   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7823   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7824 }
7825 
7826 /*********************************************/
7827 /*           SET UP CHRONTEL CHIPS           */
7828 /*********************************************/
7829 
7830 static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7831 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7832                unsigned short RefreshRateTableIndex)
7833 {
7834    unsigned short TVType, resindex;
7835    const struct SiS_CHTVRegData *CHTVRegData = NULL;
7836 
7837    if(ModeNo <= 0x13)
7838       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7839    else
7840       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7841 
7842    resindex &= 0x3F;
7843 
7844    TVType = 0;
7845    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7846    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7847       TVType += 2;
7848       if(SiS_Pr->SiS_ModeType > ModeVGA) {
7849 	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7850       }
7851       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7852 	 TVType = 4;
7853 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7854       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7855 	 TVType = 6;
7856 	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7857       }
7858    }
7859 
7860    switch(TVType) {
7861       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7862       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7863       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
7864       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7865       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7866       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7867       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7868       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7869       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7870       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
7871    }
7872 
7873 
7874    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7875 
7876 #ifdef CONFIG_FB_SIS_300
7877 
7878       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7879 
7880       /* We don't support modes >800x600 */
7881       if (resindex > 5) return;
7882 
7883       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7884 	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7885 	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
7886       } else {
7887 	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7888 	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
7889       }
7890 
7891       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
7892       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
7893       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
7894       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
7895       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
7896 
7897       /* Set minimum flicker filter for Luma channel (SR1-0=00),
7898                 minimum text enhancement (S3-2=10),
7899    	        maximum flicker filter for Chroma channel (S5-4=10)
7900 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
7901        */
7902       SiS_SetCH700x(SiS_Pr,0x01,0x28);
7903 
7904       /* Set video bandwidth
7905             High bandwidth Luma composite video filter(S0=1)
7906             low bandwidth Luma S-video filter (S2-1=00)
7907 	    disable peak filter in S-video channel (S3=0)
7908 	    high bandwidth Chroma Filter (S5-4=11)
7909 	    =00110001=0x31
7910       */
7911       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
7912 
7913       /* Register 0x3D does not exist in non-macrovision register map
7914             (Maybe this is a macrovision register?)
7915        */
7916 #ifndef SIS_CP
7917       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
7918 #endif
7919 
7920       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
7921              all other bits a read-only. Macrovision?
7922        */
7923       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
7924 
7925       /* Register 0x11 only contains 3 writable bits (S0-S2) for
7926              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
7927        */
7928       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
7929 
7930       /* Clear DSEN
7931        */
7932       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
7933 
7934       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
7935          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
7936             if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
7937       	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7938                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
7939             } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
7940                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
7941                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
7942                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
7943                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
7944                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
7945                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
7946                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
7947                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
7948                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
7949                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
7950             }
7951          } else {
7952             if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
7953                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7954                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7955             } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
7956 #if 0
7957                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
7958                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
7959                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
7960                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
7961                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
7962                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
7963                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
7964                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
7965                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
7966                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
7967 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
7968 	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
7969                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
7970             }
7971          }
7972       } else {						/* ---- PAL ---- */
7973          /* We don't play around with FSCI in PAL mode */
7974          if(resindex == 0x04) {
7975             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7976             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
7977          } else {
7978             SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
7979             SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
7980          }
7981       }
7982 
7983 #endif  /* 300 */
7984 
7985    } else {
7986 
7987       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
7988 
7989 #ifdef CONFIG_FB_SIS_315
7990 
7991       unsigned short temp;
7992 
7993       /* We don't support modes >1024x768 */
7994       if (resindex > 6) return;
7995 
7996       temp = CHTVRegData[resindex].Reg[0];
7997       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
7998       SiS_SetCH701x(SiS_Pr,0x00,temp);
7999 
8000       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8001       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8002       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8003       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8004       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8005       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8006 
8007       temp = CHTVRegData[resindex].Reg[7];
8008       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8009       SiS_SetCH701x(SiS_Pr,0x07,temp);
8010 
8011       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8012       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8013       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8014       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8015       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8016       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8017       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8018       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8019 
8020       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8021       /* D1 should be set for PAL, PAL-N and NTSC-J,
8022          but I won't do that for PAL unless somebody
8023 	 tells me to do so. Since the BIOS uses
8024 	 non-default CIV values and blacklevels,
8025 	 this might be compensated anyway.
8026        */
8027       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8028       SiS_SetCH701x(SiS_Pr,0x21,temp);
8029 
8030 #endif	/* 315 */
8031 
8032    }
8033 
8034 #ifdef SIS_CP
8035    SIS_CP_INIT301_CP3
8036 #endif
8037 
8038 }
8039 
8040 #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8041 
8042 void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8043 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8044 {
8045    unsigned short temp;
8046 
8047    /* Enable Chrontel 7019 LCD panel backlight */
8048    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8049       if(SiS_Pr->ChipType == SIS_740) {
8050 	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8051       } else {
8052 	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8053 	 temp |= 0x20;
8054 	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8055       }
8056    }
8057 }
8058 
8059 void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8060 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8061 {
8062    unsigned short temp;
8063 
8064    /* Disable Chrontel 7019 LCD panel backlight */
8065    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8066       temp = SiS_GetCH701x(SiS_Pr,0x66);
8067       temp &= 0xDF;
8068       SiS_SetCH701x(SiS_Pr,0x66,temp);
8069    }
8070 }
8071 
8072 static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8073 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8074 {
8075   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8076   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8077   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8078   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8079   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8080   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8081   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8082   const unsigned char *tableptr = NULL;
8083   int i;
8084 
8085   /* Set up Power up/down timing */
8086 
8087   if(SiS_Pr->ChipType == SIS_740) {
8088      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8089 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8090 	else    			          tableptr = table1024_740;
8091      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8092 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8093 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8094 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8095         else					  tableptr = table1400_740;
8096      } else return;
8097   } else {
8098      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8099 	tableptr = table1024_650;
8100      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8101 	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8102 	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8103 	tableptr = table1400_650;
8104      } else return;
8105   }
8106 
8107   for(i=0; i<5; i++) {
8108      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8109   }
8110 }
8111 
8112 static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8113 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8114 {
8115   const unsigned char *tableptr = NULL;
8116   unsigned short tempbh;
8117   int i;
8118   static const unsigned char regtable[] = {
8119 		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8120 		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8121   };
8122   static const unsigned char table1024_740[] = {
8123 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8124 		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8125   };
8126   static const unsigned char table1280_740[] = {
8127 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8128 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8129   };
8130   static const unsigned char table1400_740[] = {
8131 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8132 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8133   };
8134   static const unsigned char table1600_740[] = {
8135 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8136 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8137   };
8138   static const unsigned char table1024_650[] = {
8139 		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8140 		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8141   };
8142   static const unsigned char table1280_650[] = {
8143 		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8144 		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8145   };
8146   static const unsigned char table1400_650[] = {
8147 		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8148 		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8149   };
8150   static const unsigned char table1600_650[] = {
8151 		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8152 		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8153   };
8154 
8155   if(SiS_Pr->ChipType == SIS_740) {
8156      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8157      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8158      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8159      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8160      else return;
8161   } else {
8162      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8163      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8164      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8165      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8166      else return;
8167   }
8168 
8169   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8170   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8171      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8172      if(tempbh == 0xc8) {
8173         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8174      } else if(tempbh == 0xdb) {
8175         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8176 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8177      } else if(tempbh == 0xde) {
8178         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8179      }
8180   }
8181 
8182   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8183   else     			  tempbh = 0x0c;
8184 
8185   for(i = 0; i < tempbh; i++) {
8186      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8187   }
8188   SiS_ChrontelPowerSequencing(SiS_Pr);
8189   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8190   tempbh |= 0xc0;
8191   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8192 
8193   if(SiS_Pr->ChipType == SIS_740) {
8194      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8195      tempbh &= 0xfb;
8196      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8197      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8198      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8199      tempbh |= 0x40;
8200      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8201      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8202      tempbh &= 0x3f;
8203      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8204   }
8205 }
8206 
8207 static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8208 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8209 {
8210   unsigned char temp, temp1;
8211 
8212   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8213   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8214   temp = SiS_GetCH701x(SiS_Pr,0x47);
8215   temp &= 0x7f;	/* Use external VSYNC */
8216   SiS_SetCH701x(SiS_Pr,0x47,temp);
8217   SiS_LongDelay(SiS_Pr, 3);
8218   temp = SiS_GetCH701x(SiS_Pr,0x47);
8219   temp |= 0x80;	/* Use internal VSYNC */
8220   SiS_SetCH701x(SiS_Pr,0x47,temp);
8221   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8222 }
8223 
8224 static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8225 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8226 {
8227   unsigned short temp;
8228 
8229   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8230      if(SiS_Pr->ChipType == SIS_740) {
8231         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8232         temp |= 0x04;	/* Invert XCLK phase */
8233         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8234      }
8235      if(SiS_IsYPbPr(SiS_Pr)) {
8236         temp = SiS_GetCH701x(SiS_Pr,0x01);
8237 	temp &= 0x3f;
8238 	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8239 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8240      }
8241      if(SiS_IsChScart(SiS_Pr)) {
8242         temp = SiS_GetCH701x(SiS_Pr,0x01);
8243 	temp &= 0x3f;
8244 	temp |= 0xc0;	/* Enable SCART + CVBS */
8245 	SiS_SetCH701x(SiS_Pr,0x01,temp);
8246      }
8247      if(SiS_Pr->ChipType == SIS_740) {
8248         SiS_ChrontelResetVSync(SiS_Pr);
8249         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8250      } else {
8251         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8252         temp = SiS_GetCH701x(SiS_Pr,0x49);
8253         if(SiS_IsYPbPr(SiS_Pr)) {
8254            temp = SiS_GetCH701x(SiS_Pr,0x73);
8255 	   temp |= 0x60;
8256 	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8257         }
8258         temp = SiS_GetCH701x(SiS_Pr,0x47);
8259         temp &= 0x7f;
8260         SiS_SetCH701x(SiS_Pr,0x47,temp);
8261         SiS_LongDelay(SiS_Pr, 2);
8262         temp = SiS_GetCH701x(SiS_Pr,0x47);
8263         temp |= 0x80;
8264         SiS_SetCH701x(SiS_Pr,0x47,temp);
8265      }
8266   }
8267 }
8268 
8269 static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8270 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8271 {
8272   unsigned short temp;
8273 
8274   /* Complete power down of LVDS */
8275   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8276      if(SiS_Pr->ChipType == SIS_740) {
8277         SiS_LongDelay(SiS_Pr, 1);
8278 	SiS_GenericDelay(SiS_Pr, 5887);
8279 	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8280 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8281      } else {
8282         SiS_LongDelay(SiS_Pr, 2);
8283 	temp = SiS_GetCH701x(SiS_Pr,0x76);
8284 	temp &= 0xfc;
8285 	SiS_SetCH701x(SiS_Pr,0x76,temp);
8286 	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8287      }
8288   }
8289 }
8290 
8291 static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8292 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8293 {
8294      unsigned short temp;
8295 
8296      if(SiS_Pr->ChipType == SIS_740) {
8297 
8298         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8299         temp &= 0x01;
8300         if(!temp) {
8301 
8302            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8303 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8304 	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8305 	   }
8306 
8307 	   /* Reset Chrontel 7019 datapath */
8308            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8309            SiS_LongDelay(SiS_Pr, 1);
8310            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8311 
8312 	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8313 	      SiS_ChrontelResetVSync(SiS_Pr);
8314 	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8315 	   }
8316 
8317         } else {
8318 
8319 	   /* Clear/set/clear GPIO */
8320            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8321 	   temp &= 0xef;
8322 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8323 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8324 	   temp |= 0x10;
8325 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8326 	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8327 	   temp &= 0xef;
8328 	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8329 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8330 	   if(!temp) {
8331 	      SiS_SetCH701xForLCD(SiS_Pr);
8332 	   }
8333         }
8334 
8335      } else { /* 650 */
8336         /* Reset Chrontel 7019 datapath */
8337         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8338         SiS_LongDelay(SiS_Pr, 1);
8339         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8340      }
8341 }
8342 
8343 static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8344 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8345 {
8346      unsigned short temp;
8347 
8348      if(SiS_Pr->ChipType == SIS_740) {
8349 
8350         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8351            SiS_ChrontelResetVSync(SiS_Pr);
8352         }
8353 
8354      } else {
8355 
8356         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8357         temp = SiS_GetCH701x(SiS_Pr,0x49);
8358         temp &= 1;
8359         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8360 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8361 	   temp &= 0x70;
8362 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8363 	   SiS_LongDelay(SiS_Pr, 3);
8364 	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8365 	   temp |= 0x80;
8366 	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8367         }
8368 
8369      }
8370 }
8371 
8372 static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8373 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8374 {
8375      unsigned short temp,temp1;
8376 
8377      if(SiS_Pr->ChipType == SIS_740) {
8378 
8379         temp = SiS_GetCH701x(SiS_Pr,0x61);
8380         if(temp < 1) {
8381            temp++;
8382 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8383         }
8384         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8385         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8386         SiS_LongDelay(SiS_Pr, 1);
8387         SiS_GenericDelay(SiS_Pr, 5887);
8388 
8389      } else {  /* 650 */
8390 
8391         temp1 = 0;
8392         temp = SiS_GetCH701x(SiS_Pr,0x61);
8393         if(temp < 2) {
8394            temp++;
8395 	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8396 	   temp1 = 1;
8397         }
8398         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8399         temp = SiS_GetCH701x(SiS_Pr,0x66);
8400         temp |= 0x5f;
8401         SiS_SetCH701x(SiS_Pr,0x66,temp);
8402         if(ModeNo > 0x13) {
8403            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8404 	      SiS_GenericDelay(SiS_Pr, 1023);
8405 	   } else {
8406 	      SiS_GenericDelay(SiS_Pr, 767);
8407 	   }
8408         } else {
8409            if(!temp1)
8410 	      SiS_GenericDelay(SiS_Pr, 767);
8411         }
8412         temp = SiS_GetCH701x(SiS_Pr,0x76);
8413         temp |= 0x03;
8414         SiS_SetCH701x(SiS_Pr,0x76,temp);
8415         temp = SiS_GetCH701x(SiS_Pr,0x66);
8416         temp &= 0x7f;
8417         SiS_SetCH701x(SiS_Pr,0x66,temp);
8418         SiS_LongDelay(SiS_Pr, 1);
8419 
8420      }
8421 }
8422 
8423 static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8424 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8425 {
8426      unsigned short temp;
8427 
8428      SiS_LongDelay(SiS_Pr, 1);
8429 
8430      do {
8431        temp = SiS_GetCH701x(SiS_Pr,0x66);
8432        temp &= 0x04;  /* PLL stable? -> bail out */
8433        if(temp == 0x04) break;
8434 
8435        if(SiS_Pr->ChipType == SIS_740) {
8436           /* Power down LVDS output, PLL normal operation */
8437           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8438        }
8439 
8440        SiS_SetCH701xForLCD(SiS_Pr);
8441 
8442        temp = SiS_GetCH701x(SiS_Pr,0x76);
8443        temp &= 0xfb;  /* Reset PLL */
8444        SiS_SetCH701x(SiS_Pr,0x76,temp);
8445        SiS_LongDelay(SiS_Pr, 2);
8446        temp = SiS_GetCH701x(SiS_Pr,0x76);
8447        temp |= 0x04;  /* PLL normal operation */
8448        SiS_SetCH701x(SiS_Pr,0x76,temp);
8449        if(SiS_Pr->ChipType == SIS_740) {
8450           SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8451        } else {
8452           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8453        }
8454        SiS_LongDelay(SiS_Pr, 2);
8455     } while(0);
8456 
8457     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8458 }
8459 
8460 static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8461 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8462 {
8463      unsigned short temp;
8464 
8465      temp = SiS_GetCH701x(SiS_Pr,0x03);
8466      temp |= 0x80;	/* Set datapath 1 to TV   */
8467      temp &= 0xbf;	/* Set datapath 2 to LVDS */
8468      SiS_SetCH701x(SiS_Pr,0x03,temp);
8469 
8470      if(SiS_Pr->ChipType == SIS_740) {
8471 
8472         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8473         temp &= 0xfb;	/* Normal XCLK phase */
8474         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8475 
8476         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8477 
8478         temp = SiS_GetCH701x(SiS_Pr,0x64);
8479         temp |= 0x40;	/* ? Bit not defined */
8480         SiS_SetCH701x(SiS_Pr,0x64,temp);
8481 
8482         temp = SiS_GetCH701x(SiS_Pr,0x03);
8483         temp &= 0x3f;	/* D1 input to both LVDS and TV */
8484         SiS_SetCH701x(SiS_Pr,0x03,temp);
8485 
8486 	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8487 	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8488 	   SiS_LongDelay(SiS_Pr, 1);
8489 	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8490 	   SiS_ChrontelResetDB(SiS_Pr);
8491 	   SiS_ChrontelDoSomething2(SiS_Pr);
8492 	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8493 	} else {
8494            temp = SiS_GetCH701x(SiS_Pr,0x66);
8495            if(temp != 0x45) {
8496               SiS_ChrontelResetDB(SiS_Pr);
8497               SiS_ChrontelDoSomething2(SiS_Pr);
8498               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8499            }
8500 	}
8501 
8502      } else { /* 650 */
8503 
8504         SiS_ChrontelResetDB(SiS_Pr);
8505         SiS_ChrontelDoSomething2(SiS_Pr);
8506         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8507         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8508         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8509 
8510      }
8511 
8512 }
8513 #endif  /* 315 series  */
8514 
8515 /*********************************************/
8516 /*      MAIN: SET CRT2 REGISTER GROUP        */
8517 /*********************************************/
8518 
8519 bool
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8520 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8521 {
8522 #ifdef CONFIG_FB_SIS_300
8523    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8524 #endif
8525    unsigned short ModeIdIndex, RefreshRateTableIndex;
8526 
8527    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8528 
8529    if(!SiS_Pr->UseCustomMode) {
8530       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8531    } else {
8532       ModeIdIndex = 0;
8533    }
8534 
8535    /* Used for shifting CR33 */
8536    SiS_Pr->SiS_SelectCRT2Rate = 4;
8537 
8538    SiS_UnLockCRT2(SiS_Pr);
8539 
8540    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8541 
8542    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8543 
8544    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8545       SiS_DisableBridge(SiS_Pr);
8546       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8547          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8548       }
8549       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8550    }
8551 
8552    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8553       SiS_LockCRT2(SiS_Pr);
8554       SiS_DisplayOn(SiS_Pr);
8555       return true;
8556    }
8557 
8558    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8559 
8560    /* Set up Panel Link for LVDS and LCDA */
8561    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8562    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8563        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8564        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8565       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8566    }
8567 
8568    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8569       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8570    }
8571 
8572    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8573 
8574       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8575 
8576 	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8577 #ifdef CONFIG_FB_SIS_315
8578 	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8579 #endif
8580 	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8581 	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8582 #ifdef CONFIG_FB_SIS_315
8583 	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8584 #endif
8585 	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8586 
8587 	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8588 
8589 	 /* For 301BDH (Panel link initialization): */
8590 	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8591 
8592 	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8593 	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8594 		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8595 	       }
8596             }
8597 	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8598 	 }
8599       }
8600 
8601    } else {
8602 
8603       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8604 
8605       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8606 
8607       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8608 
8609       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8610 	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8611 	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8612 	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8613 #ifdef CONFIG_FB_SIS_315
8614 		  SiS_SetCH701xForLCD(SiS_Pr);
8615 #endif
8616 	       }
8617 	    }
8618 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8619 	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8620 	    }
8621 	 }
8622       }
8623 
8624    }
8625 
8626 #ifdef CONFIG_FB_SIS_300
8627    if(SiS_Pr->ChipType < SIS_315H) {
8628       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8629 	 if(SiS_Pr->SiS_UseOEM) {
8630 	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8631 	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8632 		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8633 	       }
8634 	    } else {
8635 	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8636 	    }
8637 	 }
8638 	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8639 	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8640 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8641 	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8642 	    }
8643 	    SiS_DisplayOn(SiS_Pr);
8644          }
8645       }
8646    }
8647 #endif
8648 
8649 #ifdef CONFIG_FB_SIS_315
8650    if(SiS_Pr->ChipType >= SIS_315H) {
8651       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8652 	 if(SiS_Pr->ChipType < SIS_661) {
8653 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8654 	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8655 	 } else {
8656 	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8657 	 }
8658 	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8659       }
8660    }
8661 #endif
8662 
8663    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8664       SiS_EnableBridge(SiS_Pr);
8665    }
8666 
8667    SiS_DisplayOn(SiS_Pr);
8668 
8669    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8670       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8671 	 /* Disable LCD panel when using TV */
8672 	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8673       } else {
8674 	 /* Disable TV when using LCD */
8675 	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8676       }
8677    }
8678 
8679    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8680       SiS_LockCRT2(SiS_Pr);
8681    }
8682 
8683    return true;
8684 }
8685 
8686 
8687 /*********************************************/
8688 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8689 /*********************************************/
8690 
8691 void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)8692 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8693 {
8694   /* Switch on LCD backlight on SiS30xLV */
8695   SiS_DDC2Delay(SiS_Pr,0xff00);
8696   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8697      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8698      SiS_WaitVBRetrace(SiS_Pr);
8699   }
8700   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8701      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8702   }
8703 }
8704 
8705 void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)8706 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8707 {
8708   /* Switch off LCD backlight on SiS30xLV */
8709   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8710   SiS_DDC2Delay(SiS_Pr,0xff00);
8711 }
8712 
8713 /*********************************************/
8714 /*          DDC RELATED FUNCTIONS            */
8715 /*********************************************/
8716 
8717 static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)8718 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8719 {
8720   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8721   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
8722   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8723      SiS_Pr->SiS_DDC_NData &= 0x0f;
8724      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
8725   }
8726 }
8727 
8728 #ifdef CONFIG_FB_SIS_300
8729 static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8730 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8731 {
8732   int i, j, num;
8733   unsigned short tempah,temp;
8734   unsigned char *mydataptr;
8735 
8736   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8737      mydataptr = dataptr;
8738      num = *mydataptr++;
8739      if(!num) return mydataptr;
8740      if(i) {
8741         SiS_SetStop(SiS_Pr);
8742 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8743      }
8744      if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
8745      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8746      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
8747      if(temp) continue;				/*    (ERROR: no ack) */
8748      tempah = *mydataptr++;
8749      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
8750      if(temp) continue;				/*    (ERROR: no ack) */
8751      for(j=0; j<num; j++) {
8752         tempah = *mydataptr++;
8753         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8754 	if(temp) break;
8755      }
8756      if(temp) continue;
8757      if(SiS_SetStop(SiS_Pr)) continue;
8758      return mydataptr;
8759   }
8760   return NULL;
8761 }
8762 
8763 static bool
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8764 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8765 {
8766   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
8767   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8768   SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
8769   SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
8770   SiS_SetupDDCN(SiS_Pr);
8771 
8772   SiS_SetSwitchDDC2(SiS_Pr);
8773 
8774   while(*dataptr) {
8775      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8776      if(!dataptr) return false;
8777   }
8778   return true;
8779 }
8780 #endif
8781 
8782 /* The Chrontel 700x is connected to the 630/730 via
8783  * the 630/730's DDC/I2C port.
8784  *
8785  * On 630(S)T chipset, the index changed from 0x11 to
8786  * 0x0a, possibly for working around the DDC problems
8787  */
8788 
8789 static bool
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)8790 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8791 {
8792   unsigned short temp, i;
8793 
8794   for(i=0; i<20; i++) {				/* Do 20 attempts to write */
8795      if(i) {
8796 	SiS_SetStop(SiS_Pr);
8797 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8798      }
8799      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
8800      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
8801      if(temp) continue;							/*    (ERROR: no ack) */
8802      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
8803      if(temp) continue;							/*    (ERROR: no ack) */
8804      temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
8805      if(temp) continue;							/*    (ERROR: no ack) */
8806      if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
8807      SiS_Pr->SiS_ChrontelInit = 1;
8808      return true;
8809   }
8810   return false;
8811 }
8812 
8813 /* Write to Chrontel 700x */
8814 void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)8815 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8816 {
8817   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
8818 
8819   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8820 
8821   if(!(SiS_Pr->SiS_ChrontelInit)) {
8822      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
8823      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
8824      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
8825      SiS_SetupDDCN(SiS_Pr);
8826   }
8827 
8828   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
8829       (!(SiS_Pr->SiS_ChrontelInit)) ) {
8830      SiS_Pr->SiS_DDC_Index = 0x0a;
8831      SiS_Pr->SiS_DDC_Data  = 0x80;
8832      SiS_Pr->SiS_DDC_Clk   = 0x40;
8833      SiS_SetupDDCN(SiS_Pr);
8834 
8835      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
8836   }
8837 }
8838 
8839 /* Write to Chrontel 701x */
8840 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
8841 void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)8842 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8843 {
8844   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8845   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
8846   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
8847   SiS_SetupDDCN(SiS_Pr);
8848   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
8849   SiS_SetChReg(SiS_Pr, reg, val, 0);
8850 }
8851 
8852 static
8853 void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)8854 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
8855 {
8856   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8857      SiS_SetCH700x(SiS_Pr, reg, val);
8858   else
8859      SiS_SetCH701x(SiS_Pr, reg, val);
8860 }
8861 
8862 static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)8863 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
8864 {
8865   unsigned short tempah, temp, i;
8866 
8867   for(i=0; i<20; i++) {				/* Do 20 attempts to read */
8868      if(i) {
8869 	SiS_SetStop(SiS_Pr);
8870 	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8871      }
8872      if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
8873      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
8874      if(temp) continue;							/*        (ERROR: no ack) */
8875      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
8876      if(temp) continue;							/*        (ERROR: no ack) */
8877      if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
8878      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
8879      if(temp) continue;							/*        (ERROR: no ack) */
8880      tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
8881      if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
8882      SiS_Pr->SiS_ChrontelInit = 1;
8883      return tempah;
8884   }
8885   return 0xFFFF;
8886 }
8887 
8888 /* Read from Chrontel 700x */
8889 /* Parameter is [Register no (S7-S0)] */
8890 unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)8891 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8892 {
8893   unsigned short result;
8894 
8895   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
8896 
8897   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8898 
8899   if(!(SiS_Pr->SiS_ChrontelInit)) {
8900      SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
8901      SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
8902      SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
8903      SiS_SetupDDCN(SiS_Pr);
8904   }
8905 
8906   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8907 
8908   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
8909       (!SiS_Pr->SiS_ChrontelInit) ) {
8910 
8911      SiS_Pr->SiS_DDC_Index = 0x0a;
8912      SiS_Pr->SiS_DDC_Data  = 0x80;
8913      SiS_Pr->SiS_DDC_Clk   = 0x40;
8914      SiS_SetupDDCN(SiS_Pr);
8915 
8916      result = SiS_GetChReg(SiS_Pr,0x80);
8917   }
8918   return result;
8919 }
8920 
8921 /* Read from Chrontel 701x */
8922 /* Parameter is [Register no (S7-S0)] */
8923 unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)8924 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8925 {
8926   SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
8927   SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
8928   SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
8929   SiS_SetupDDCN(SiS_Pr);
8930   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
8931 
8932   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
8933 
8934   return SiS_GetChReg(SiS_Pr,0);
8935 }
8936 
8937 /* Read from Chrontel 70xx */
8938 /* Parameter is [Register no (S7-S0)] */
8939 static
8940 unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)8941 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
8942 {
8943   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
8944      return SiS_GetCH700x(SiS_Pr, tempbx);
8945   else
8946      return SiS_GetCH701x(SiS_Pr, tempbx);
8947 }
8948 
8949 void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)8950 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
8951 		unsigned char myor, unsigned short myand)
8952 {
8953   unsigned short tempbl;
8954 
8955   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
8956   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
8957 }
8958 
8959 /* Our own DDC functions */
8960 static
8961 unsigned short
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,bool checkcr32,unsigned int VBFlags2)8962 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
8963                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
8964 		unsigned int VBFlags2)
8965 {
8966      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
8967      unsigned char flag, cr32;
8968      unsigned short        temp = 0, myadaptnum = adaptnum;
8969 
8970      if(adaptnum != 0) {
8971 	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
8972 	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
8973      }
8974 
8975      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
8976 
8977      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
8978 
8979      SiS_Pr->SiS_DDC_SecAddr = 0;
8980      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
8981      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
8982      SiS_Pr->SiS_DDC_Index = 0x11;
8983      flag = 0xff;
8984 
8985      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
8986 
8987 #if 0
8988      if(VBFlags2 & VB2_SISBRIDGE) {
8989 	if(myadaptnum == 0) {
8990 	   if(!(cr32 & 0x20)) {
8991 	      myadaptnum = 2;
8992 	      if(!(cr32 & 0x10)) {
8993 	         myadaptnum = 1;
8994 		 if(!(cr32 & 0x08)) {
8995 		    myadaptnum = 0;
8996 		 }
8997 	      }
8998 	   }
8999         }
9000      }
9001 #endif
9002 
9003      if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9004 
9005         if(myadaptnum != 0) {
9006 	   flag = 0;
9007 	   if(VBFlags2 & VB2_SISBRIDGE) {
9008 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9009               SiS_Pr->SiS_DDC_Index = 0x0f;
9010 	   }
9011         }
9012 
9013 	if(!(VBFlags2 & VB2_301)) {
9014 	   if((cr32 & 0x80) && (checkcr32)) {
9015               if(myadaptnum >= 1) {
9016 	         if(!(cr32 & 0x08)) {
9017 		     myadaptnum = 1;
9018 		     if(!(cr32 & 0x10)) return 0xFFFF;
9019                  }
9020 	      }
9021 	   }
9022 	}
9023 
9024 	temp = 4 - (myadaptnum * 2);
9025 	if(flag) temp = 0;
9026 
9027      } else {						/* 315/330 series */
9028 
9029 	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9030 
9031 	if(VBFlags2 & VB2_SISBRIDGE) {
9032 	   if(myadaptnum == 2) {
9033 	      myadaptnum = 1;
9034 	   }
9035 	}
9036 
9037         if(myadaptnum == 1) {
9038 	   flag = 0;
9039 	   if(VBFlags2 & VB2_SISBRIDGE) {
9040 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9041               SiS_Pr->SiS_DDC_Index = 0x0f;
9042 	   }
9043         }
9044 
9045         if((cr32 & 0x80) && (checkcr32)) {
9046            if(myadaptnum >= 1) {
9047 	      if(!(cr32 & 0x08)) {
9048 	         myadaptnum = 1;
9049 		 if(!(cr32 & 0x10)) return 0xFFFF;
9050 	      }
9051 	   }
9052         }
9053 
9054         temp = myadaptnum;
9055         if(myadaptnum == 1) {
9056            temp = 0;
9057 	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9058         }
9059 
9060 	if(flag) temp = 0;
9061     }
9062 
9063     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9064     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9065 
9066     SiS_SetupDDCN(SiS_Pr);
9067 
9068     return 0;
9069 }
9070 
9071 static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9072 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9073 {
9074    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9075    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9076       return 0xFFFF;
9077    }
9078    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9079       return 0xFFFF;
9080    }
9081    return 0;
9082 }
9083 
9084 static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9085 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9086 {
9087    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9088    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9089       return 0xFFFF;
9090    }
9091    return 0;
9092 }
9093 
9094 static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9095 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9096 {
9097    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9098    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9099    return 0;
9100 }
9101 
9102 static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9103 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9104 {
9105    SiS_SetSCLKLow(SiS_Pr);
9106    if(yesno) {
9107       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9108 		      SiS_Pr->SiS_DDC_Index,
9109 		      SiS_Pr->SiS_DDC_NData,
9110 		      SiS_Pr->SiS_DDC_Data);
9111    } else {
9112       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9113 		      SiS_Pr->SiS_DDC_Index,
9114 		      SiS_Pr->SiS_DDC_NData,
9115 		      0);
9116    }
9117    SiS_SetSCLKHigh(SiS_Pr);
9118 }
9119 
9120 static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9121 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9122 {
9123     unsigned char mask, value;
9124     unsigned short  temp, ret=0;
9125     bool failed = false;
9126 
9127     SiS_SetSwitchDDC2(SiS_Pr);
9128     if(SiS_PrepareDDC(SiS_Pr)) {
9129          SiS_SetStop(SiS_Pr);
9130          return 0xFFFF;
9131     }
9132     mask = 0xf0;
9133     value = 0x20;
9134     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9135        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9136        SiS_SendACK(SiS_Pr, 0);
9137        if(temp == 0) {
9138            mask = 0xff;
9139 	   value = 0xff;
9140        } else {
9141            failed = true;
9142 	   ret = 0xFFFF;
9143        }
9144     }
9145     if(!failed) {
9146        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9147        SiS_SendACK(SiS_Pr, 1);
9148        temp &= mask;
9149        if(temp == value) ret = 0;
9150        else {
9151           ret = 0xFFFF;
9152           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9153              if(temp == 0x30) ret = 0;
9154           }
9155        }
9156     }
9157     SiS_SetStop(SiS_Pr);
9158     return ret;
9159 }
9160 
9161 static
9162 unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9163 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9164 {
9165    unsigned short flag;
9166 
9167    flag = 0x180;
9168    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9169    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9170    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9171    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9172    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9173    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9174    if(!(flag & 0x1a)) flag = 0;
9175    return flag;
9176 }
9177 
9178 static
9179 unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9180 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9181 {
9182    unsigned short flag, length, i;
9183    unsigned char chksum,gotcha;
9184 
9185    if(DDCdatatype > 4) return 0xFFFF;
9186 
9187    flag = 0;
9188    SiS_SetSwitchDDC2(SiS_Pr);
9189    if(!(SiS_PrepareDDC(SiS_Pr))) {
9190       length = 127;
9191       if(DDCdatatype != 1) length = 255;
9192       chksum = 0;
9193       gotcha = 0;
9194       for(i=0; i<length; i++) {
9195 	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9196 	 chksum += buffer[i];
9197 	 gotcha |= buffer[i];
9198 	 SiS_SendACK(SiS_Pr, 0);
9199       }
9200       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9201       chksum += buffer[i];
9202       SiS_SendACK(SiS_Pr, 1);
9203       if(gotcha) flag = (unsigned short)chksum;
9204       else flag = 0xFFFF;
9205    } else {
9206       flag = 0xFFFF;
9207    }
9208    SiS_SetStop(SiS_Pr);
9209    return flag;
9210 }
9211 
9212 /* Our private DDC functions
9213 
9214    It complies somewhat with the corresponding VESA function
9215    in arguments and return values.
9216 
9217    Since this is probably called before the mode is changed,
9218    we use our pre-detected pSiS-values instead of SiS_Pr as
9219    regards chipset and video bridge type.
9220 
9221    Arguments:
9222        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9223                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9224 		 LCDA is CRT1, but DDC is read from CRT2 port.
9225        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9226        buffer: ptr to 256 data bytes which will be filled with read data.
9227 
9228    Returns 0xFFFF if error, otherwise
9229        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9230        if DDCdatatype = 0:  Returns supported DDC modes
9231 
9232  */
9233 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)9234 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9235               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9236 	      unsigned int VBFlags2)
9237 {
9238    unsigned char  sr1f, cr17=1;
9239    unsigned short result;
9240 
9241    if(adaptnum > 2)
9242       return 0xFFFF;
9243 
9244    if(DDCdatatype > 4)
9245       return 0xFFFF;
9246 
9247    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9248       return 0xFFFF;
9249 
9250    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9251       return 0xFFFF;
9252 
9253    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9254    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9255    if(VGAEngine == SIS_300_VGA) {
9256       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9257       if(!cr17) {
9258          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9259          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9260          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9261       }
9262    }
9263    if((sr1f) || (!cr17)) {
9264       SiS_WaitRetrace1(SiS_Pr);
9265       SiS_WaitRetrace1(SiS_Pr);
9266       SiS_WaitRetrace1(SiS_Pr);
9267       SiS_WaitRetrace1(SiS_Pr);
9268    }
9269 
9270    if(DDCdatatype == 0) {
9271       result = SiS_ProbeDDC(SiS_Pr);
9272    } else {
9273       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9274       if((!result) && (DDCdatatype == 1)) {
9275          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9276 	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9277 	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9278 	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9279 	    (buffer[0x12] == 1)) {
9280 	    if(!SiS_Pr->DDCPortMixup) {
9281 	       if(adaptnum == 1) {
9282 	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9283 	       } else {
9284 	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9285 	       }
9286 	    }
9287 	 }
9288       }
9289    }
9290    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9291    if(VGAEngine == SIS_300_VGA) {
9292       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9293    }
9294    return result;
9295 }
9296 
9297 /* Generic I2C functions for Chrontel & DDC --------- */
9298 
9299 static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9300 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9301 {
9302   SiS_SetSCLKHigh(SiS_Pr);
9303   SiS_WaitRetrace1(SiS_Pr);
9304 
9305   SiS_SetSCLKLow(SiS_Pr);
9306   SiS_WaitRetrace1(SiS_Pr);
9307 }
9308 
9309 unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9310 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9311 {
9312    SiS_WaitRetrace1(SiS_Pr);
9313    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9314 }
9315 
9316 /* Set I2C start condition */
9317 /* This is done by a SD high-to-low transition while SC is high */
9318 static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9319 SiS_SetStart(struct SiS_Private *SiS_Pr)
9320 {
9321   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9322   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9323 		  SiS_Pr->SiS_DDC_Index,
9324 		  SiS_Pr->SiS_DDC_NData,
9325 		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9326   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9327   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9328 		  SiS_Pr->SiS_DDC_Index,
9329 		  SiS_Pr->SiS_DDC_NData,
9330 		  0x00);					/* SD->low = start condition */
9331   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9332   return 0;
9333 }
9334 
9335 /* Set I2C stop condition */
9336 /* This is done by a SD low-to-high transition while SC is high */
9337 static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9338 SiS_SetStop(struct SiS_Private *SiS_Pr)
9339 {
9340   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9341   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9342 		  SiS_Pr->SiS_DDC_Index,
9343 		  SiS_Pr->SiS_DDC_NData,
9344 		  0x00);					/* SD->low   */
9345   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9346   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9347 		  SiS_Pr->SiS_DDC_Index,
9348 		  SiS_Pr->SiS_DDC_NData,
9349 		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9350   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9351   return 0;
9352 }
9353 
9354 /* Write 8 bits of data */
9355 static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9356 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9357 {
9358   unsigned short i,flag,temp;
9359 
9360   flag = 0x80;
9361   for(i = 0; i < 8; i++) {
9362     SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9363     if(tempax & flag) {
9364       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9365 		      SiS_Pr->SiS_DDC_Index,
9366 		      SiS_Pr->SiS_DDC_NData,
9367 		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9368     } else {
9369       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9370 		      SiS_Pr->SiS_DDC_Index,
9371 		      SiS_Pr->SiS_DDC_NData,
9372 		      0x00);					/* Write bit (0) to SD */
9373     }
9374     SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9375     flag >>= 1;
9376   }
9377   temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9378   return temp;
9379 }
9380 
9381 static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9382 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9383 {
9384   unsigned short i, temp, getdata;
9385 
9386   getdata = 0;
9387   for(i = 0; i < 8; i++) {
9388     getdata <<= 1;
9389     SiS_SetSCLKLow(SiS_Pr);
9390     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9391 		    SiS_Pr->SiS_DDC_Index,
9392 		    SiS_Pr->SiS_DDC_NData,
9393 		    SiS_Pr->SiS_DDC_Data);
9394     SiS_SetSCLKHigh(SiS_Pr);
9395     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9396     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9397   }
9398   return getdata;
9399 }
9400 
9401 static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9402 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9403 {
9404   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9405 		  SiS_Pr->SiS_DDC_Index,
9406 		  SiS_Pr->SiS_DDC_NClk,
9407 		  0x00);					/* SetSCLKLow()  */
9408   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9409   return 0;
9410 }
9411 
9412 static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9413 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9414 {
9415   unsigned short temp, watchdog=1000;
9416 
9417   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418 		  SiS_Pr->SiS_DDC_Index,
9419 		  SiS_Pr->SiS_DDC_NClk,
9420 		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9421   do {
9422     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9423   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9424   if (!watchdog) {
9425   	return 0xFFFF;
9426   }
9427   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9428   return 0;
9429 }
9430 
9431 /* Check I2C acknowledge */
9432 /* Returns 0 if ack ok, non-0 if ack not ok */
9433 static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9434 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9435 {
9436   unsigned short tempah;
9437 
9438   SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9439   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9440 		  SiS_Pr->SiS_DDC_Index,
9441 		  SiS_Pr->SiS_DDC_NData,
9442 		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9443   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9444   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9445   SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9446   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9447   return 0;
9448 }
9449 
9450 /* End of I2C functions ----------------------- */
9451 
9452 
9453 /* =============== SiS 315/330 O.E.M. ================= */
9454 
9455 #ifdef CONFIG_FB_SIS_315
9456 
9457 static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9458 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9459 {
9460   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9461   unsigned short romptr;
9462 
9463   if(SiS_Pr->ChipType < SIS_330) {
9464      romptr = SISGETROMW(0x128);
9465      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9466         romptr = SISGETROMW(0x12a);
9467   } else {
9468      romptr = SISGETROMW(0x1a8);
9469      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9470         romptr = SISGETROMW(0x1aa);
9471   }
9472   return romptr;
9473 }
9474 
9475 static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9476 GetLCDromptr(struct SiS_Private *SiS_Pr)
9477 {
9478   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9479   unsigned short romptr;
9480 
9481   if(SiS_Pr->ChipType < SIS_330) {
9482      romptr = SISGETROMW(0x120);
9483      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9484         romptr = SISGETROMW(0x122);
9485   } else {
9486      romptr = SISGETROMW(0x1a0);
9487      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9488         romptr = SISGETROMW(0x1a2);
9489   }
9490   return romptr;
9491 }
9492 
9493 static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9494 GetTVromptr(struct SiS_Private *SiS_Pr)
9495 {
9496   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9497   unsigned short romptr;
9498 
9499   if(SiS_Pr->ChipType < SIS_330) {
9500      romptr = SISGETROMW(0x114);
9501      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9502         romptr = SISGETROMW(0x11a);
9503   } else {
9504      romptr = SISGETROMW(0x194);
9505      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9506         romptr = SISGETROMW(0x19a);
9507   }
9508   return romptr;
9509 }
9510 
9511 static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9512 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9513 {
9514   unsigned short index;
9515 
9516   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9517      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9518         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9519 	   index >>= 4;
9520 	   index *= 3;
9521 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9522            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9523            return index;
9524 	}
9525      }
9526   }
9527 
9528   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9529   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9530   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9531      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9532      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9533   } else {
9534      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9535   }
9536   index--;
9537   index *= 3;
9538   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9539   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9540   return index;
9541 }
9542 
9543 static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9544 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9545 {
9546   unsigned short index;
9547 
9548   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9549   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9550   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9551   return index;
9552 }
9553 
9554 static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9555 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9556 {
9557   unsigned short index;
9558 
9559   index = 0;
9560   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9561   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9562 
9563   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9564 
9565   index <<= 1;
9566 
9567   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9568      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9569      index++;
9570   }
9571 
9572   return index;
9573 }
9574 
9575 static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9576 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9577 {
9578    unsigned short index = 0, temp = 0;
9579 
9580    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9581    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9582    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9583    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9584    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9585       index = 4;
9586       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9587       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9588    }
9589 
9590    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9591       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9592          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9593 	 index += addme;
9594 	 temp++;
9595       }
9596       temp += 0x0100;
9597    }
9598    return (unsigned int)(index | (temp << 16));
9599 }
9600 
9601 static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9602 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9603 {
9604    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9605 }
9606 
9607 #if 0
9608 static unsigned int
9609 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9610 {
9611    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9612 }
9613 #endif
9614 
9615 static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9616 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9617 {
9618    int index = 0;
9619 
9620    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9621    if(SiS_Pr->SiS_ROMNew) {
9622       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9623       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9624       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9625       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9626    } else {
9627       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9628       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9629       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9630       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9631    }
9632 
9633    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9634 
9635    return index;
9636 }
9637 
9638 static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9639 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9640 {
9641   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9642   unsigned short delay=0,index,myindex,temp,romptr=0;
9643   bool dochiptest = true;
9644 
9645   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9646      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9647   } else {
9648      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9649   }
9650 
9651   /* Find delay (from ROM, internal tables, PCI subsystem) */
9652 
9653   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9654 
9655      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9656         romptr = GetRAMDACromptr(SiS_Pr);
9657      }
9658      if(romptr) delay = ROMAddr[romptr];
9659      else {
9660         delay = 0x04;
9661         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9662 	   if(IS_SIS650) {
9663 	      delay = 0x0a;
9664 	   } else if(IS_SIS740) {
9665 	      delay = 0x00;
9666 	   } else if(SiS_Pr->ChipType < SIS_330) {
9667 	      delay = 0x0c;
9668 	   } else {
9669 	      delay = 0x0c;
9670 	   }
9671 	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9672            delay = 0x00;
9673 	}
9674      }
9675 
9676   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9677 
9678      bool gotitfrompci = false;
9679 
9680      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9681 
9682      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9683 	if(SiS_Pr->PDC != -1) {
9684            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9685 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9686 	   return;
9687 	}
9688      } else {
9689 	if(SiS_Pr->PDCA != -1) {
9690 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9691 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9692 	   return;
9693 	}
9694      }
9695 
9696      /* Custom Panel? */
9697 
9698      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9699         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9700 	   delay = 0x00;
9701 	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9702 	      delay = 0x20;
9703 	   }
9704 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9705 	} else {
9706 	   delay = 0x0c;
9707 	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9708 	      delay = 0x03;
9709 	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9710 	         delay = 0x00;
9711 	      }
9712 	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9713 	      if(IS_SIS740) delay = 0x01;
9714 	      else          delay = 0x03;
9715 	   }
9716 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9717 	}
9718         return;
9719      }
9720 
9721      /* This is a piece of typical SiS crap: They code the OEM LCD
9722       * delay into the code, at no defined place in the BIOS.
9723       * We now have to start doing a PCI subsystem check here.
9724       */
9725 
9726      switch(SiS_Pr->SiS_CustomT) {
9727      case CUT_COMPAQ1280:
9728      case CUT_COMPAQ12802:
9729 	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9730 	   gotitfrompci = true;
9731 	   dochiptest = false;
9732 	   delay = 0x03;
9733 	}
9734 	break;
9735      case CUT_CLEVO1400:
9736      case CUT_CLEVO14002:
9737 	gotitfrompci = true;
9738 	dochiptest = false;
9739 	delay = 0x02;
9740 	break;
9741      case CUT_CLEVO1024:
9742      case CUT_CLEVO10242:
9743         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9744 	   gotitfrompci = true;
9745 	   dochiptest = false;
9746 	   delay = 0x33;
9747 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9748 	   delay &= 0x0f;
9749 	}
9750 	break;
9751      }
9752 
9753      /* Could we find it through the PCI ID? If no, use ROM or table */
9754 
9755      if(!gotitfrompci) {
9756 
9757         index = GetLCDPtrIndexBIOS(SiS_Pr);
9758         myindex = GetLCDPtrIndex(SiS_Pr);
9759 
9760         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9761 
9762            if(SiS_IsNotM650orLater(SiS_Pr)) {
9763 
9764               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9765 	         /* Always use the second pointer on 650; some BIOSes */
9766                  /* still carry old 301 data at the first location    */
9767 	         /* romptr = SISGETROMW(0x120);                       */
9768 	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
9769 	         romptr = SISGETROMW(0x122);
9770 	         if(!romptr) return;
9771 	         delay = ROMAddr[(romptr + index)];
9772 	      } else {
9773                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9774 	      }
9775 
9776           } else {
9777 
9778              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
9779 	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
9780 	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
9781 
9782           }
9783 
9784         } else if(SiS_Pr->SiS_UseROM 			      &&
9785 		  (!(SiS_Pr->SiS_ROMNew))		      &&
9786 	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
9787 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
9788 		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
9789 		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
9790 		  ((romptr = GetLCDromptr(SiS_Pr)))) {
9791 
9792 	   /* Data for 1280x1024 wrong in 301B BIOS */
9793 	   /* Data for 1600x1200 wrong in 301C BIOS */
9794 	   delay = ROMAddr[(romptr + index)];
9795 
9796         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9797 
9798 	   if(IS_SIS740) delay = 0x03;
9799 	   else          delay = 0x00;
9800 
9801 	} else {
9802 
9803            delay = SiS310_LCDDelayCompensation_301[myindex];
9804 	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9805 	      if(IS_SIS740) delay = 0x01;
9806 	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
9807 	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9808 	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9809 	      if(IS_SIS740) delay = 0x01;  /* ? */
9810 	      else          delay = 0x03;
9811 	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
9812 	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9813 	      if(IS_SIS740) delay = 0x01;
9814 	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
9815 	   }
9816 
9817         }
9818 
9819      }  /* got it from PCI */
9820 
9821      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9822 	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
9823 	dochiptest = false;
9824      }
9825 
9826   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
9827 
9828      index = GetTVPtrIndex(SiS_Pr);
9829 
9830      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9831 
9832         if(SiS_IsNotM650orLater(SiS_Pr)) {
9833 
9834            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9835 	      /* Always use the second pointer on 650; some BIOSes */
9836               /* still carry old 301 data at the first location    */
9837               /* romptr = SISGETROMW(0x114);			   */
9838 	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
9839 	      romptr = SISGETROMW(0x11a);
9840 	      if(!romptr) return;
9841 	      delay = ROMAddr[romptr + index];
9842 
9843 	   } else {
9844 
9845 	      delay = SiS310_TVDelayCompensation_301B[index];
9846 
9847 	   }
9848 
9849         } else {
9850 
9851            switch(SiS_Pr->SiS_CustomT) {
9852 	   case CUT_COMPAQ1280:
9853 	   case CUT_COMPAQ12802:
9854 	   case CUT_CLEVO1400:
9855 	   case CUT_CLEVO14002:
9856 	      delay = 0x02;
9857 	      dochiptest = false;
9858 	      break;
9859 	   case CUT_CLEVO1024:
9860 	   case CUT_CLEVO10242:
9861 	      delay = 0x03;
9862 	      dochiptest = false;
9863    	      break;
9864 	   default:
9865               delay = SiS310_TVDelayCompensation_651301LV[index];
9866 	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
9867 	         delay = SiS310_TVDelayCompensation_651302LV[index];
9868 	      }
9869 	   }
9870         }
9871 
9872      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9873 
9874         romptr = GetTVromptr(SiS_Pr);
9875 	if(!romptr) return;
9876 	delay = ROMAddr[romptr + index];
9877 
9878      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9879 
9880         delay = SiS310_TVDelayCompensation_LVDS[index];
9881 
9882      } else {
9883 
9884 	delay = SiS310_TVDelayCompensation_301[index];
9885         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9886 	   if(IS_SIS740) {
9887 	      delay = SiS310_TVDelayCompensation_740301B[index];
9888 	      /* LV: use 301 data? BIOS bug? */
9889 	   } else {
9890               delay = SiS310_TVDelayCompensation_301B[index];
9891 	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
9892 	   }
9893 	}
9894 
9895      }
9896 
9897      if(SiS_LCDAEnabled(SiS_Pr)) {
9898 	delay &= 0x0f;
9899 	dochiptest = false;
9900      }
9901 
9902   } else return;
9903 
9904   /* Write delay */
9905 
9906   if(SiS_Pr->SiS_VBType & VB_SISVB) {
9907 
9908      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
9909 
9910         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
9911         if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
9912 	   delay &= 0x0f;
9913 	   delay |= 0xb0;
9914         } else if(temp == 6) {
9915            delay &= 0x0f;
9916 	   delay |= 0xc0;
9917         } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
9918 	   delay = 0x35;
9919         }
9920         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9921 
9922      } else {
9923 
9924         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9925 
9926      }
9927 
9928   } else {  /* LVDS */
9929 
9930      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9931         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9932      } else {
9933         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
9934            delay <<= 4;
9935            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
9936         } else {
9937            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
9938         }
9939      }
9940 
9941   }
9942 
9943 }
9944 
9945 static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)9946 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
9947 {
9948   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9949   unsigned short index,temp,temp1,romptr=0;
9950 
9951   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
9952 
9953   if(ModeNo<=0x13)
9954      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
9955   else
9956      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
9957 
9958   temp = GetTVPtrIndex(SiS_Pr);
9959   temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9960   temp1 = temp;
9961 
9962   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
9963      if(SiS_Pr->ChipType >= SIS_661) {
9964         temp1 = GetOEMTVPtr661(SiS_Pr);
9965         temp1 >>= 1;
9966         romptr = SISGETROMW(0x260);
9967         if(SiS_Pr->ChipType >= SIS_760) {
9968 	   romptr = SISGETROMW(0x360);
9969 	}
9970      } else if(SiS_Pr->ChipType >= SIS_330) {
9971         romptr = SISGETROMW(0x192);
9972      } else {
9973         romptr = SISGETROMW(0x112);
9974      }
9975   }
9976 
9977   if(romptr) {
9978      temp1 <<= 1;
9979      temp = ROMAddr[romptr + temp1 + index];
9980   } else {
9981      temp = SiS310_TVAntiFlick1[temp][index];
9982   }
9983   temp <<= 4;
9984 
9985   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
9986 }
9987 
9988 static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)9989 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
9990 {
9991   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9992   unsigned short index,temp,temp1,romptr=0;
9993 
9994   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
9995 
9996   if(ModeNo <= 0x13)
9997      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
9998   else
9999      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10000 
10001   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10002      if(SiS_Pr->ChipType >= SIS_661) {
10003         romptr = SISGETROMW(0x26c);
10004         if(SiS_Pr->ChipType >= SIS_760) {
10005 	   romptr = SISGETROMW(0x36c);
10006 	}
10007 	temp1 = GetOEMTVPtr661(SiS_Pr);
10008         temp1 >>= 1;
10009      } else if(SiS_Pr->ChipType >= SIS_330) {
10010         romptr = SISGETROMW(0x1a4);
10011      } else {
10012         romptr = SISGETROMW(0x124);
10013      }
10014   }
10015 
10016   if(romptr) {
10017      temp1 <<= 1;
10018      temp = ROMAddr[romptr + temp1 + index];
10019   } else {
10020      temp = SiS310_TVEdge1[temp][index];
10021   }
10022   temp <<= 5;
10023   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10024 }
10025 
10026 static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10027 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10028 {
10029   unsigned short index, temp, i, j;
10030 
10031   if(ModeNo <= 0x13) {
10032      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10033   } else {
10034      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10035   }
10036 
10037   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10038 
10039   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10040   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10041   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10042   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10043 
10044   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10045      for(i=0x35, j=0; i<=0x38; i++, j++) {
10046         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10047      }
10048      for(i=0x48; i<=0x4A; i++, j++) {
10049         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10050      }
10051   } else {
10052      for(i=0x35, j=0; i<=0x38; i++, j++) {
10053         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10054      }
10055   }
10056 }
10057 
10058 static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10059 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10060 {
10061   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10062   unsigned short index,temp,i,j,resinfo,romptr=0;
10063   unsigned int  lindex;
10064 
10065   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10066 
10067   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10068   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10069 
10070   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10071      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10072      lindex <<= 2;
10073      for(j=0, i=0x31; i<=0x34; i++, j++) {
10074         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10075      }
10076      return;
10077   }
10078 
10079   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10080   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10081 
10082   if(ModeNo<=0x13) {
10083      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10084   } else {
10085      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10086   }
10087 
10088   temp = GetTVPtrIndex(SiS_Pr);
10089   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10090    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10091    */
10092   if(SiS_Pr->SiS_UseROM) {
10093      romptr = SISGETROMW(0x116);
10094      if(SiS_Pr->ChipType >= SIS_330) {
10095         romptr = SISGETROMW(0x196);
10096      }
10097      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10098         romptr = SISGETROMW(0x11c);
10099 	if(SiS_Pr->ChipType >= SIS_330) {
10100 	   romptr = SISGETROMW(0x19c);
10101 	}
10102 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10103 	   romptr = SISGETROMW(0x116);
10104 	   if(SiS_Pr->ChipType >= SIS_330) {
10105               romptr = SISGETROMW(0x196);
10106            }
10107 	}
10108      }
10109   }
10110   if(romptr) {
10111      romptr += (temp << 2);
10112      for(j=0, i=0x31; i<=0x34; i++, j++) {
10113         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10114      }
10115   } else {
10116      index = temp % 2;
10117      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10118      for(j=0, i=0x31; i<=0x34; i++, j++) {
10119         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10120 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10121         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10122            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10123         else
10124            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10125      }
10126   }
10127 
10128   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10129      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10130         if((resinfo == SIS_RI_640x480) ||
10131 	   (resinfo == SIS_RI_800x600)) {
10132 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10133 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10134 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10135 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10136 	} else if(resinfo == SIS_RI_1024x768) {
10137 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10138 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10139 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10140 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10141 	}
10142      }
10143   }
10144 }
10145 
10146 static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10147 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10148                 unsigned short ModeIdIndex, unsigned short RTI)
10149 {
10150    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10151    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10152 
10153    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10154       return;
10155 
10156    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10157    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10158 
10159    if(SiS_Pr->SiS_ROMNew) {
10160       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10161          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10162 	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10163          index = 25;
10164          if(SiS_Pr->UseCustomMode) {
10165 	    index = SiS_Pr->CSRClock;
10166          } else if(ModeNo > 0x13) {
10167             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10168             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10169          }
10170 	 if(index < 25) index = 25;
10171          index = ((index / 25) - 1) << 1;
10172          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10173 	    index++;
10174 	 }
10175 	 romptr = SISGETROMW(0x104);
10176          delay = ROMAddr[romptr + index];
10177          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10178             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10179             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10180          } else {
10181             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10182 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10183          }
10184          return;
10185       }
10186    }
10187 
10188    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10189 
10190    if(SiS_Pr->UseCustomMode) delay = 0x04;
10191    else if(ModeNo <= 0x13)   delay = 0x04;
10192    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10193    delay |= (delay << 8);
10194 
10195    if(SiS_Pr->ChipType >= XGI_20) {
10196 
10197       delay = 0x0606;
10198       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10199 
10200 	 delay = 0x0404;
10201          if(SiS_Pr->SiS_XGIROM) {
10202 	     index = GetTVPtrIndex(SiS_Pr);
10203 	     if((romptr = SISGETROMW(0x35e))) {
10204 	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10205 		delay |= (delay << 8);
10206 	     }
10207 	 }
10208 
10209 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10210 	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10211 	       delay -= 0x0404;
10212 	    }
10213 	 }
10214       }
10215 
10216    } else if(SiS_Pr->ChipType >= SIS_340) {
10217 
10218       delay = 0x0606;
10219       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10220          delay = 0x0404;
10221       }
10222       /* TODO (eventually) */
10223 
10224    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10225 
10226       /* 3. TV */
10227 
10228       index = GetOEMTVPtr661(SiS_Pr);
10229       if(SiS_Pr->SiS_ROMNew) {
10230          romptr = SISGETROMW(0x106);
10231 	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10232          delay = ROMAddr[romptr + index];
10233       } else {
10234          delay = 0x04;
10235 	 if(index > 3) delay = 0;
10236       }
10237 
10238    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10239 
10240       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10241 
10242       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10243           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10244 
10245 	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10246 
10247 	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10248 	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10249 	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10250 
10251       } else {
10252 
10253          /* TMDS: Set our own, since BIOS has no idea */
10254 	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10255          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10256 	    switch(SiS_Pr->SiS_LCDResInfo) {
10257 	    case Panel_1024x768:  delay = 0x0008; break;
10258 	    case Panel_1280x720:  delay = 0x0004; break;
10259 	    case Panel_1280x768:
10260 	    case Panel_1280x768_2:delay = 0x0004; break;
10261 	    case Panel_1280x800:
10262 	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10263 	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10264 	    case Panel_1280x1024: delay = 0x1e04; break;
10265 	    case Panel_1400x1050: delay = 0x0004; break;
10266 	    case Panel_1600x1200: delay = 0x0400; break;
10267 	    case Panel_1680x1050: delay = 0x0e04; break;
10268 	    default:
10269                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10270 	          delay = 0x0008;
10271 	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10272 	          delay = 0x1e04;
10273                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10274 	          delay = 0x0004;
10275 	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10276 	          delay = 0x0400;
10277                } else
10278 	          delay = 0x0e04;
10279 	       break;
10280 	    }
10281          }
10282 
10283 	 /* Override by detected or user-set values */
10284 	 /* (but only if, for some reason, we can't read value from BIOS) */
10285          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10286             delay = SiS_Pr->PDC & 0x1f;
10287          }
10288          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10289             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10290          }
10291 
10292       }
10293 
10294    }
10295 
10296    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10297       delay >>= 8;
10298       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10299       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10300    } else {
10301       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10302       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10303    }
10304 }
10305 
10306 static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10307 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10308 {
10309    unsigned short infoflag;
10310    unsigned char  temp;
10311 
10312    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10313 
10314       if(ModeNo <= 0x13) {
10315          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10316       } else if(SiS_Pr->UseCustomMode) {
10317          infoflag = SiS_Pr->CInfoFlag;
10318       } else {
10319          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10320       }
10321 
10322       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10323          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10324       }
10325 
10326       infoflag &= 0xc0;
10327 
10328       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10329          temp = (infoflag >> 6) | 0x0c;
10330          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10331 	    temp ^= 0x04;
10332 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10333 	 }
10334          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10335       } else {
10336          temp = 0x30;
10337          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10338          temp |= infoflag;
10339          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10340          temp = 0;
10341          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10342 	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10343 	 }
10344          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10345       }
10346 
10347    }
10348 }
10349 
10350 static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10351 SetPanelParms661(struct SiS_Private *SiS_Pr)
10352 {
10353    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10354    unsigned short romptr, temp1, temp2;
10355 
10356    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10357       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10358    }
10359 
10360    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10361       if(SiS_Pr->LVDSHL != -1) {
10362          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10363       }
10364    }
10365 
10366    if(SiS_Pr->SiS_ROMNew) {
10367 
10368       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10369          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10370             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10371 	    temp2 = 0xfc;
10372 	    if(SiS_Pr->LVDSHL != -1) {
10373 	      temp1 &= 0xfc;
10374 	      temp2 = 0xf3;
10375 	    }
10376 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10377          }
10378 	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10379             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10380             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10381 	 }
10382       }
10383 
10384    }
10385 }
10386 
10387 static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10388 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10389 {
10390    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10391       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10392       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10393          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10394          SetPanelParms661(SiS_Pr);
10395       }
10396    } else {
10397       SetDelayComp(SiS_Pr,ModeNo);
10398    }
10399 
10400    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10401       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10402       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10403       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10404       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10405          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10406       }
10407    }
10408 }
10409 
10410 static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10411 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10412 			unsigned short ModeIdIndex, unsigned short RRTI)
10413 {
10414    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10415 
10416       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10417 
10418       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10419          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10420          SetPanelParms661(SiS_Pr);
10421       }
10422 
10423       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10424          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10425          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10426          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10427          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10428             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10429          }
10430       }
10431    }
10432 }
10433 
10434 /* FinalizeLCD
10435  * This finalizes some CRT2 registers for the very panel used.
10436  * If we have a backup if these registers, we use it; otherwise
10437  * we set the register according to most BIOSes. However, this
10438  * function looks quite different in every BIOS, so you better
10439  * pray that we have a backup...
10440  */
10441 static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10442 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10443 {
10444   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10445   unsigned short resinfo,modeflag;
10446 
10447   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10448   if(SiS_Pr->SiS_ROMNew) return;
10449 
10450   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10451      if(SiS_Pr->LVDSHL != -1) {
10452         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10453      }
10454   }
10455 
10456   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10457   if(SiS_Pr->UseCustomMode) return;
10458 
10459   switch(SiS_Pr->SiS_CustomT) {
10460   case CUT_COMPAQ1280:
10461   case CUT_COMPAQ12802:
10462   case CUT_CLEVO1400:
10463   case CUT_CLEVO14002:
10464      return;
10465   }
10466 
10467   if(ModeNo <= 0x13) {
10468      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10469      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10470   } else {
10471      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10472      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10473   }
10474 
10475   if(IS_SIS650) {
10476      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10477         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10478 	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10479 	} else {
10480            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10481 	}
10482      }
10483   }
10484 
10485   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10486      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10487         /* Maybe all panels? */
10488         if(SiS_Pr->LVDSHL == -1) {
10489            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10490 	}
10491 	return;
10492      }
10493   }
10494 
10495   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10496      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10497         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10498 	   if(SiS_Pr->LVDSHL == -1) {
10499 	      /* Maybe all panels? */
10500               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10501 	   }
10502 	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10503 	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10504 	      if(tempch == 3) {
10505 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10506 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10507 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10508 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10509 	      }
10510 	   }
10511 	   return;
10512 	}
10513      }
10514   }
10515 
10516   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10517      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10518 	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10519 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10520 #ifdef SET_EMI
10521 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10522 #endif
10523 	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10524 	}
10525      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10526         if(SiS_Pr->LVDSHL == -1) {
10527            /* Maybe ACER only? */
10528            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10529 	}
10530      }
10531      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10532      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10533 	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10534 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10535 	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10536 	   if(tempch == 0x03) {
10537 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10538 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10539 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10540 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10541 	   }
10542 	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10543 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10544 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10545 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10546 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10547 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10548 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10549 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10550 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10551 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10552 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10553 	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10554 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10555 	      if(ModeNo <= 0x13) {
10556 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10557 		 if((resinfo == 0) || (resinfo == 2)) return;
10558 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10559 		 if((resinfo == 1) || (resinfo == 3)) return;
10560 	      }
10561 	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10562 	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10563 	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10564 #if 0
10565 	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10566 		 tempbx--;
10567 		 temp = tempbx & 0xff;
10568 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10569 		 temp = (tempbx >> 8) & 0x03;
10570 		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10571 #endif
10572 	      }
10573 	   } else if(ModeNo <= 0x13) {
10574 	      if(ModeNo <= 1) {
10575 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10576 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10577 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10578 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10579 	      }
10580 	      if(!(modeflag & HalfDCLK)) {
10581 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10582 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10583 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10584 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10585 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10586 		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10587 		 if(ModeNo == 0x12) {
10588 		    switch(tempch) {
10589 		       case 0:
10590 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10591 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10592 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10593 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10594 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10595 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10596 			  break;
10597 		       case 2:
10598 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10599 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10600 			  break;
10601 		       case 3:
10602 			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10603 			  break;
10604 		    }
10605 		 }
10606 	      }
10607 	   }
10608 	}
10609      } else {
10610         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10611 	tempcl &= 0x0f;
10612 	tempbh &= 0x70;
10613 	tempbh >>= 4;
10614 	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10615 	tempbx = (tempbh << 8) | tempbl;
10616 	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10617 	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10618 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10619 	      	 tempbx = 770;
10620 	      } else {
10621 	         if(tempbx > 770) tempbx = 770;
10622 		 if(SiS_Pr->SiS_VGAVDE < 600) {
10623 		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10624 		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10625 		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10626 		    tempbx -= tempax;
10627 		 }
10628 	      }
10629 	   } else return;
10630 	}
10631 	temp = tempbx & 0xff;
10632 	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10633 	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10634 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10635      }
10636   }
10637 }
10638 
10639 #endif
10640 
10641 /*  =================  SiS 300 O.E.M. ================== */
10642 
10643 #ifdef CONFIG_FB_SIS_300
10644 
10645 static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10646 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10647 		unsigned short RefTabIndex)
10648 {
10649   unsigned short crt2crtc=0, modeflag, myindex=0;
10650   unsigned char  temp;
10651   int i;
10652 
10653   if(ModeNo <= 0x13) {
10654      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10655      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10656   } else {
10657      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10658      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10659   }
10660 
10661   crt2crtc &= 0x3f;
10662 
10663   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10664      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10665   }
10666 
10667   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10668      if(modeflag & HalfDCLK) myindex = 1;
10669 
10670      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10671         for(i=0; i<7; i++) {
10672            if(barco_p1[myindex][crt2crtc][i][0]) {
10673 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10674 	                      barco_p1[myindex][crt2crtc][i][0],
10675 	   	   	      barco_p1[myindex][crt2crtc][i][2],
10676 			      barco_p1[myindex][crt2crtc][i][1]);
10677 	   }
10678         }
10679      }
10680      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10681      if(temp & 0x80) {
10682         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10683         temp++;
10684         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10685      }
10686   }
10687 }
10688 
10689 static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10690 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10691 {
10692   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10693   unsigned short tempbx=0,romptr=0;
10694   static const unsigned char customtable300[] = {
10695 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10696 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10697   };
10698   static const unsigned char customtable630[] = {
10699 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10700 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10701   };
10702 
10703   if(SiS_Pr->ChipType == SIS_300) {
10704 
10705     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10706     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10707     tempbx -= 2;
10708     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10709     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10710        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10711     }
10712     if(SiS_Pr->SiS_UseROM) {
10713        if(ROMAddr[0x235] & 0x80) {
10714           tempbx = SiS_Pr->SiS_LCDTypeInfo;
10715           if(Flag) {
10716 	     romptr = SISGETROMW(0x255);
10717 	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10718 	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10719              if(tempbx == 0xFF) return 0xFFFF;
10720           }
10721 	  tempbx <<= 1;
10722 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10723        }
10724     }
10725 
10726   } else {
10727 
10728     if(Flag) {
10729        if(SiS_Pr->SiS_UseROM) {
10730           romptr = SISGETROMW(0x255);
10731 	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10732 	  else 	     tempbx = 0xff;
10733        } else {
10734           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10735        }
10736        if(tempbx == 0xFF) return 0xFFFF;
10737        tempbx <<= 2;
10738        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10739        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10740        return tempbx;
10741     }
10742     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10743     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10744     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10745 
10746   }
10747 
10748   return tempbx;
10749 }
10750 
10751 static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10752 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10753 {
10754   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10755   unsigned short index,temp,romptr=0;
10756 
10757   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10758 
10759   if(SiS_Pr->SiS_UseROM) {
10760      if(!(ROMAddr[0x237] & 0x01)) return;
10761      if(!(ROMAddr[0x237] & 0x02)) return;
10762      romptr = SISGETROMW(0x24b);
10763   }
10764 
10765   /* The Panel Compensation Delay should be set according to tables
10766    * here. Unfortunately, various BIOS versions don't care about
10767    * a uniform way using eg. ROM byte 0x220, but use different
10768    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10769    * Thus we don't set this if the user selected a custom pdc or if
10770    * we otherwise detected a valid pdc.
10771    */
10772   if(SiS_Pr->PDC != -1) return;
10773 
10774   temp = GetOEMLCDPtr(SiS_Pr, 0);
10775 
10776   if(SiS_Pr->UseCustomMode)
10777      index = 0;
10778   else
10779      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
10780 
10781   if(SiS_Pr->ChipType != SIS_300) {
10782      if(romptr) {
10783 	romptr += (temp * 2);
10784 	romptr = SISGETROMW(romptr);
10785 	romptr += index;
10786 	temp = ROMAddr[romptr];
10787      } else {
10788 	if(SiS_Pr->SiS_VBType & VB_SISVB) {
10789     	   temp = SiS300_OEMLCDDelay2[temp][index];
10790 	} else {
10791            temp = SiS300_OEMLCDDelay3[temp][index];
10792         }
10793      }
10794   } else {
10795      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
10796 	if(romptr) {
10797 	   romptr += (temp * 2);
10798 	   romptr = SISGETROMW(romptr);
10799 	   romptr += index;
10800 	   temp = ROMAddr[romptr];
10801 	} else {
10802 	   temp = SiS300_OEMLCDDelay5[temp][index];
10803 	}
10804      } else {
10805         if(SiS_Pr->SiS_UseROM) {
10806 	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
10807 	   if(romptr) {
10808 	      romptr += (temp * 2);
10809 	      romptr = SISGETROMW(romptr);
10810 	      romptr += index;
10811 	      temp = ROMAddr[romptr];
10812 	   } else {
10813 	      temp = SiS300_OEMLCDDelay4[temp][index];
10814 	   }
10815 	} else {
10816 	   temp = SiS300_OEMLCDDelay4[temp][index];
10817 	}
10818      }
10819   }
10820   temp &= 0x3c;
10821   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
10822 }
10823 
10824 static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10825 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10826 {
10827 #if 0  /* Unfinished; Data table missing */
10828   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10829   unsigned short index,temp;
10830 
10831   if((SiS_Pr->SiS_UseROM) {
10832      if(!(ROMAddr[0x237] & 0x01)) return;
10833      if(!(ROMAddr[0x237] & 0x04)) return;
10834      /* No rom pointer in BIOS header! */
10835   }
10836 
10837   temp = GetOEMLCDPtr(SiS_Pr, 1);
10838   if(temp == 0xFFFF) return;
10839 
10840   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
10841   for(i=0x14, j=0; i<=0x17; i++, j++) {
10842       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
10843   }
10844   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
10845 
10846   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
10847   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
10848   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
10849   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
10850   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
10851       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
10852   }
10853 #endif
10854 }
10855 
10856 static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)10857 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
10858 {
10859   unsigned short index;
10860 
10861   index = 0;
10862   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
10863   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10864      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
10865      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
10866      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
10867   } else {
10868      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
10869      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
10870   }
10871   return index;
10872 }
10873 
10874 static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10875 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10876 {
10877   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10878   unsigned short index,temp,romptr=0;
10879 
10880   if(SiS_Pr->SiS_UseROM) {
10881      if(!(ROMAddr[0x238] & 0x01)) return;
10882      if(!(ROMAddr[0x238] & 0x02)) return;
10883      romptr = SISGETROMW(0x241);
10884   }
10885 
10886   temp = GetOEMTVPtr(SiS_Pr);
10887 
10888   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
10889 
10890   if(romptr) {
10891      romptr += (temp * 2);
10892      romptr = SISGETROMW(romptr);
10893      romptr += index;
10894      temp = ROMAddr[romptr];
10895   } else {
10896      if(SiS_Pr->SiS_VBType & VB_SISVB) {
10897         temp = SiS300_OEMTVDelay301[temp][index];
10898      } else {
10899         temp = SiS300_OEMTVDelayLVDS[temp][index];
10900      }
10901   }
10902   temp &= 0x3c;
10903   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
10904 }
10905 
10906 static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10907 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10908 {
10909   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10910   unsigned short index,temp,romptr=0;
10911 
10912   if(SiS_Pr->SiS_UseROM) {
10913      if(!(ROMAddr[0x238] & 0x01)) return;
10914      if(!(ROMAddr[0x238] & 0x04)) return;
10915      romptr = SISGETROMW(0x243);
10916   }
10917 
10918   temp = GetOEMTVPtr(SiS_Pr);
10919 
10920   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
10921 
10922   if(romptr) {
10923      romptr += (temp * 2);
10924      romptr = SISGETROMW(romptr);
10925      romptr += index;
10926      temp = ROMAddr[romptr];
10927   } else {
10928      temp = SiS300_OEMTVFlicker[temp][index];
10929   }
10930   temp &= 0x70;
10931   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
10932 }
10933 
10934 static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10935 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10936 {
10937   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10938   unsigned short index,i,j,temp,romptr=0;
10939 
10940   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
10941 
10942   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
10943 
10944   if(SiS_Pr->SiS_UseROM) {
10945      if(!(ROMAddr[0x238] & 0x01)) return;
10946      if(!(ROMAddr[0x238] & 0x08)) return;
10947      romptr = SISGETROMW(0x245);
10948   }
10949 
10950   temp = GetOEMTVPtr(SiS_Pr);
10951 
10952   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
10953 
10954   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10955      for(i=0x31, j=0; i<=0x34; i++, j++) {
10956         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
10957      }
10958   } else {
10959      if(romptr) {
10960         romptr += (temp * 2);
10961 	romptr = SISGETROMW(romptr);
10962 	romptr += (index * 4);
10963         for(i=0x31, j=0; i<=0x34; i++, j++) {
10964 	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10965 	}
10966      } else {
10967         for(i=0x31, j=0; i<=0x34; i++, j++) {
10968            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
10969 	}
10970      }
10971   }
10972 }
10973 
10974 static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10975 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10976 {
10977   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10978   unsigned short index,temp,i,j,romptr=0;
10979 
10980   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
10981 
10982   if(SiS_Pr->SiS_UseROM) {
10983      if(!(ROMAddr[0x238] & 0x01)) return;
10984      if(!(ROMAddr[0x238] & 0x10)) return;
10985      romptr = SISGETROMW(0x247);
10986   }
10987 
10988   temp = GetOEMTVPtr(SiS_Pr);
10989 
10990   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
10991   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
10992   /* NTSCJ uses NTSC filters */
10993 
10994   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
10995 
10996   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10997       for(i=0x35, j=0; i<=0x38; i++, j++) {
10998        	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
10999       }
11000       for(i=0x48; i<=0x4A; i++, j++) {
11001      	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11002       }
11003   } else {
11004       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11005          romptr += (temp * 2);
11006 	 romptr = SISGETROMW(romptr);
11007 	 romptr += (index * 4);
11008 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11009        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11010          }
11011       } else {
11012          for(i=0x35, j=0; i<=0x38; i++, j++) {
11013        	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11014          }
11015       }
11016   }
11017 }
11018 
11019 static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11020 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11021 {
11022    unsigned short ModeIdIndex;
11023    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11024 
11025    if(*ModeNo <= 5) *ModeNo |= 1;
11026 
11027    for(ModeIdIndex=0; ; ModeIdIndex++) {
11028       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11029       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11030    }
11031 
11032    if(*ModeNo != 0x07) {
11033       if(*ModeNo > 0x03) return ModeIdIndex;
11034       if(VGAINFO & 0x80) return ModeIdIndex;
11035       ModeIdIndex++;
11036    }
11037 
11038    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11039 	                               /* else 350 lines */
11040    return ModeIdIndex;
11041 }
11042 
11043 static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11044 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11045 		  unsigned short RefTableIndex)
11046 {
11047   unsigned short OEMModeIdIndex = 0;
11048 
11049   if(!SiS_Pr->UseCustomMode) {
11050      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11051      if(!(OEMModeIdIndex)) return;
11052   }
11053 
11054   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11055      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11056      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11057         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11058      }
11059   }
11060   if(SiS_Pr->UseCustomMode) return;
11061   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11062      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11063      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11064         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11065     	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11066        	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11067      }
11068   }
11069 }
11070 #endif
11071 
11072