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