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