1 /*
2 * Mode initializing code (CRT2 section)
3 * for SiS 300/305/540/630/730,
4 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
5 * XGI V3XT/V5/V8, Z7
6 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
7 *
8 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
9 *
10 * If distributed as part of the Linux kernel, the following license terms
11 * apply:
12 *
13 * * This program is free software; you can redistribute it and/or modify
14 * * it under the terms of the GNU General Public License as published by
15 * * the Free Software Foundation; either version 2 of the named License,
16 * * or any later version.
17 * *
18 * * This program is distributed in the hope that it will be useful,
19 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * * GNU General Public License for more details.
22 * *
23 * * You should have received a copy of the GNU General Public License
24 * * along with this program; if not, write to the Free Software
25 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
26 *
27 * Otherwise, the following license terms apply:
28 *
29 * * Redistribution and use in source and binary forms, with or without
30 * * modification, are permitted provided that the following conditions
31 * * are met:
32 * * 1) Redistributions of source code must retain the above copyright
33 * * notice, this list of conditions and the following disclaimer.
34 * * 2) Redistributions in binary form must reproduce the above copyright
35 * * notice, this list of conditions and the following disclaimer in the
36 * * documentation and/or other materials provided with the distribution.
37 * * 3) The name of the author may not be used to endorse or promote products
38 * * derived from this software without specific prior written permission.
39 * *
40 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
43 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
44 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
46 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
47 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
49 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 *
51 * Author: Thomas Winischhofer <thomas@winischhofer.net>
52 *
53 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
54 * Used by permission.
55 *
56 */
57
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61
62 #if 1
63 #define SET_EMI /* 302LV/ELV: Set EMI values */
64 #endif
65
66 #if 1
67 #define SET_PWD /* 301/302LV: Set PWD */
68 #endif
69
70 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
71 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
72 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
73
74 #include "init301.h"
75
76 #ifdef SIS300
77 #include "oem300.h"
78 #endif
79
80 #ifdef SIS315H
81 #include "oem310.h"
82 #endif
83
84 #define SiS_I2CDELAY 1000
85 #define SiS_I2CDELAYSHORT 150
86
87 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
88 #ifdef SIS_LINUX_KERNEL
89 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
90 #endif
91
92 /*********************************************/
93 /* HELPER: Lock/Unlock CRT2 */
94 /*********************************************/
95
96 void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)97 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
98 {
99 if(SiS_Pr->ChipType == XGI_20)
100 return;
101 else if(SiS_Pr->ChipType >= SIS_315H)
102 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
103 else
104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
105 }
106
107 #ifdef SIS_LINUX_KERNEL
108 static
109 #endif
110 void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)111 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
112 {
113 if(SiS_Pr->ChipType == XGI_20)
114 return;
115 else if(SiS_Pr->ChipType >= SIS_315H)
116 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
117 else
118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
119 }
120
121 /*********************************************/
122 /* HELPER: Write SR11 */
123 /*********************************************/
124
125 static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)126 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND,
127 unsigned short DataOR)
128 {
129 if(SiS_Pr->ChipType >= SIS_661) {
130 DataAND &= 0x0f;
131 DataOR &= 0x0f;
132 }
133 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
134 }
135
136 /*********************************************/
137 /* HELPER: Get Pointer to LCD structure */
138 /*********************************************/
139
140 #ifdef SIS315H
141 static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)142 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
143 {
144 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
145 unsigned char *myptr = NULL;
146 unsigned short romindex = 0, reg = 0, idx = 0;
147
148 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
149 * due to the variaty of panels the BIOS doesn't know about.
150 * Exception: If the BIOS has better knowledge (such as in case
151 * of machines with a 301C and a panel that does not support DDC)
152 * use the BIOS data as well.
153 */
154
155 if((SiS_Pr->SiS_ROMNew) &&
156 ( (SiS_Pr->SiS_VBType & VB_SISLVDS) ||
157 (!SiS_Pr->PanelSelfDetected) )) {
158
159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
160 else reg = 0x7d;
161
162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
163
164 if(idx < (8*26)) {
165 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
166 }
167 romindex = SISGETROMW(0x100);
168 if(romindex) {
169 romindex += idx;
170 myptr = &ROMAddr[romindex];
171 }
172 }
173 return myptr;
174 }
175
176 static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
178 {
179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
180 unsigned short romptr = 0;
181
182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183 * due to the variaty of panels the BIOS doesn't know about.
184 * Exception: If the BIOS has better knowledge (such as in case
185 * of machines with a 301C and a panel that does not support DDC)
186 * use the BIOS data as well.
187 */
188
189 if((SiS_Pr->SiS_ROMNew) &&
190 ( (SiS_Pr->SiS_VBType & VB_SISLVDS) ||
191 (!SiS_Pr->PanelSelfDetected) )) {
192 romptr = SISGETROMW(0x102);
193 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
194 }
195
196 return romptr;
197 }
198 #endif
199
200 /*********************************************/
201 /* Adjust Rate for CRT2 */
202 /*********************************************/
203
204 static BOOLEAN
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)205 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
206 unsigned short RRTI, unsigned short *i)
207 {
208 unsigned short checkmask=0, modeid, infoflag;
209
210 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
211
212 if(SiS_Pr->SiS_VBType & VB_SISVB) {
213
214 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
215
216 checkmask |= SupportRAMDAC2;
217 if(SiS_Pr->ChipType >= SIS_315H) {
218 checkmask |= SupportRAMDAC2_135;
219 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
220 checkmask |= SupportRAMDAC2_162;
221 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
222 checkmask |= SupportRAMDAC2_202;
223 }
224 }
225 }
226
227 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
228
229 checkmask |= SupportLCD;
230 if(SiS_Pr->ChipType >= SIS_315H) {
231 if(SiS_Pr->SiS_VBType & VB_SISVB) {
232 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
233 if(modeid == 0x2e) checkmask |= Support64048060Hz;
234 }
235 }
236 }
237
238 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
239
240 checkmask |= SupportHiVision;
241
242 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
243
244 checkmask |= SupportTV;
245 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
246 checkmask |= SupportTV1024;
247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
248 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
249 checkmask |= SupportYPbPr750p;
250 }
251 }
252 }
253
254 }
255
256 } else { /* LVDS */
257
258 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
260 checkmask |= SupportCHTV;
261 }
262 }
263
264 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
265 checkmask |= SupportLCD;
266 }
267
268 }
269
270 /* Look backwards in table for matching CRT2 mode */
271 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
272 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
273 if(infoflag & checkmask) return TRUE;
274 if((*i) == 0) break;
275 }
276
277 /* Look through the whole mode-section of the table from the beginning
278 * for a matching CRT2 mode if no mode was found yet.
279 */
280 for((*i) = 0; ; (*i)++) {
281 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
282 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
283 if(infoflag & checkmask) return TRUE;
284 }
285 return FALSE;
286 }
287
288 /*********************************************/
289 /* Get rate index */
290 /*********************************************/
291
292 unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)293 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
294 {
295 unsigned short RRTI,i,backup_i;
296 unsigned short modeflag,index,temp,backupindex;
297 static const unsigned short LCDRefreshIndex[] = {
298 0x00, 0x00, 0x01, 0x01,
299 0x01, 0x01, 0x01, 0x01,
300 0x01, 0x01, 0x01, 0x01,
301 0x01, 0x01, 0x01, 0x01,
302 0x00, 0x00, 0x00, 0x00
303 };
304
305 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
306 if(ModeNo == 0xfe) return 0;
307
308 if(ModeNo <= 0x13) {
309 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
310 } else {
311 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
312 }
313
314 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
315 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
316 if(modeflag & HalfDCLK) return 0;
317 }
318 }
319
320 if(ModeNo < 0x14) return 0xFFFF;
321
322 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
323 backupindex = index;
324
325 if(index > 0) index--;
326
327 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
328 if(SiS_Pr->SiS_VBType & VB_SISVB) {
329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
330 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
331 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
332 }
333 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
334 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
335 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
336 if(index > temp) index = temp;
337 }
338 }
339 } else {
340 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
341 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
342 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
343 }
344 }
345 }
346
347 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
348 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
349
350 if(SiS_Pr->ChipType >= SIS_315H) {
351 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
352 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
353 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
354 if(backupindex <= 1) RRTI++;
355 }
356 }
357 }
358
359 i = 0;
360 do {
361 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
362 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
363 temp &= ModeTypeMask;
364 if(temp < SiS_Pr->SiS_ModeType) break;
365 i++;
366 index--;
367 } while(index != 0xFFFF);
368
369 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
370 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
371 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
372 if(temp & InterlaceMode) i++;
373 }
374 }
375
376 i--;
377
378 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
379 backup_i = i;
380 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
381 i = backup_i;
382 }
383 }
384
385 return (RRTI + i);
386 }
387
388 /*********************************************/
389 /* STORE CRT2 INFO in CR34 */
390 /*********************************************/
391
392 static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)393 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
394 {
395 unsigned short temp1, temp2;
396
397 /* Store CRT1 ModeNo in CR34 */
398 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
399 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
400 temp2 = ~(SetInSlaveMode >> 8);
401 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
402 }
403
404 /*********************************************/
405 /* HELPER: GET SOME DATA FROM BIOS ROM */
406 /*********************************************/
407
408 #ifdef SIS300
409 static BOOLEAN
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)410 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
411 {
412 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
413 unsigned short temp,temp1;
414
415 if(SiS_Pr->SiS_UseROM) {
416 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
417 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
418 temp1 = SISGETROMW(0x23b);
419 if(temp1 & temp) return TRUE;
420 }
421 }
422 return FALSE;
423 }
424
425 static BOOLEAN
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)426 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
427 {
428 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
429 unsigned short temp,temp1;
430
431 if(SiS_Pr->SiS_UseROM) {
432 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
433 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
434 temp1 = SISGETROMW(0x23d);
435 if(temp1 & temp) return TRUE;
436 }
437 }
438 return FALSE;
439 }
440 #endif
441
442 /*********************************************/
443 /* HELPER: DELAY FUNCTIONS */
444 /*********************************************/
445
446 void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)447 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
448 {
449 unsigned int i, j = 0;
450
451 for(i = 0; i < delaytime; i++) {
452 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
453 }
454 }
455
456 #if defined(SIS300) || defined(SIS315H)
457 static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)458 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
459 {
460 SiS_DDC2Delay(SiS_Pr, delay * 36);
461 }
462 #endif
463
464 #ifdef SIS315H
465 static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)466 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
467 {
468 while(delay--) {
469 SiS_GenericDelay(SiS_Pr, 6623);
470 }
471 }
472 #endif
473
474 #if defined(SIS300) || defined(SIS315H)
475 static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)476 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
477 {
478 while(delay--) {
479 SiS_GenericDelay(SiS_Pr, 66);
480 }
481 }
482 #endif
483
484 static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)485 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
486 {
487 #if defined(SIS300) || defined(SIS315H)
488 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
489 unsigned short PanelID, DelayIndex, Delay=0;
490 #endif
491
492 if(SiS_Pr->ChipType < SIS_315H) {
493
494 #ifdef SIS300
495
496 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
497 if(SiS_Pr->SiS_VBType & VB_SISVB) {
498 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
499 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
500 }
501 DelayIndex = PanelID >> 4;
502 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
503 Delay = 3;
504 } else {
505 if(DelayTime >= 2) DelayTime -= 2;
506 if(!(DelayTime & 0x01)) {
507 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
508 } else {
509 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
510 }
511 if(SiS_Pr->SiS_UseROM) {
512 if(ROMAddr[0x220] & 0x40) {
513 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
514 else Delay = (unsigned short)ROMAddr[0x226];
515 }
516 }
517 }
518 SiS_ShortDelay(SiS_Pr, Delay);
519
520 #endif /* SIS300 */
521
522 } else {
523
524 #ifdef SIS315H
525
526 if((SiS_Pr->ChipType >= SIS_661) ||
527 (SiS_Pr->ChipType <= SIS_315PRO) ||
528 (SiS_Pr->ChipType == SIS_330) ||
529 (SiS_Pr->SiS_ROMNew)) {
530
531 if(!(DelayTime & 0x01)) {
532 SiS_DDC2Delay(SiS_Pr, 0x1000);
533 } else {
534 SiS_DDC2Delay(SiS_Pr, 0x4000);
535 }
536
537 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS; Special */
538
539 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
540 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
541 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
542 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
543 }
544 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
545 DelayIndex = PanelID & 0x0f;
546 } else {
547 DelayIndex = PanelID >> 4;
548 }
549 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
550 Delay = 3;
551 } else {
552 if(DelayTime >= 2) DelayTime -= 2;
553 if(!(DelayTime & 0x01)) {
554 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
555 } else {
556 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
557 }
558 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
559 if(ROMAddr[0x13c] & 0x40) {
560 if(!(DelayTime & 0x01)) {
561 Delay = (unsigned short)ROMAddr[0x17e];
562 } else {
563 Delay = (unsigned short)ROMAddr[0x17f];
564 }
565 }
566 }
567 }
568 SiS_ShortDelay(SiS_Pr, Delay);
569 }
570
571 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
572
573 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
574 if(!(DelayTime & 0x01)) {
575 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
576 } else {
577 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
578 }
579 Delay <<= 8;
580 SiS_DDC2Delay(SiS_Pr, Delay);
581
582 }
583
584 #endif /* SIS315H */
585
586 }
587 }
588
589 #ifdef SIS315H
590 static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)591 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
592 {
593 int i;
594 for(i = 0; i < DelayLoop; i++) {
595 SiS_PanelDelay(SiS_Pr, DelayTime);
596 }
597 }
598 #endif
599
600 /*********************************************/
601 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
602 /*********************************************/
603
604 void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)605 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
606 {
607 unsigned short watchdog;
608
609 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
610 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
611
612 watchdog = 65535;
613 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
614 watchdog = 65535;
615 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616 }
617
618 #if defined(SIS300) || defined(SIS315H)
619 static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)620 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
621 {
622 unsigned short watchdog;
623
624 watchdog = 65535;
625 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
626 watchdog = 65535;
627 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
628 }
629 #endif
630
631 static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)632 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
633 {
634 if(SiS_Pr->ChipType < SIS_315H) {
635 #ifdef SIS300
636 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
638 }
639 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
640 SiS_WaitRetrace1(SiS_Pr);
641 } else {
642 SiS_WaitRetrace2(SiS_Pr, 0x25);
643 }
644 #endif
645 } else {
646 #ifdef SIS315H
647 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
648 SiS_WaitRetrace1(SiS_Pr);
649 } else {
650 SiS_WaitRetrace2(SiS_Pr, 0x30);
651 }
652 #endif
653 }
654 }
655
656 static void
SiS_VBWait(struct SiS_Private * SiS_Pr)657 SiS_VBWait(struct SiS_Private *SiS_Pr)
658 {
659 unsigned short tempal,temp,i,j;
660
661 temp = 0;
662 for(i = 0; i < 3; i++) {
663 for(j = 0; j < 100; j++) {
664 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
665 if(temp & 0x01) {
666 if((tempal & 0x08)) continue;
667 else break;
668 } else {
669 if(!(tempal & 0x08)) continue;
670 else break;
671 }
672 }
673 temp ^= 0x01;
674 }
675 }
676
677 static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)678 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
679 {
680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681 SiS_VBWait(SiS_Pr);
682 } else {
683 SiS_WaitRetrace1(SiS_Pr);
684 }
685 }
686
687 /*********************************************/
688 /* HELPER: MISC */
689 /*********************************************/
690
691 #ifdef SIS300
692 static BOOLEAN
SiS_Is301B(struct SiS_Private * SiS_Pr)693 SiS_Is301B(struct SiS_Private *SiS_Pr)
694 {
695 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
696 return FALSE;
697 }
698 #endif
699
700 static BOOLEAN
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)701 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
702 {
703 if(SiS_Pr->ChipType == SIS_730) {
704 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
705 }
706 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
707 return FALSE;
708 }
709
710 BOOLEAN
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)711 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
712 {
713 #ifdef SIS315H
714 if(SiS_Pr->ChipType >= SIS_315H) {
715 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
716 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
717 }
718 }
719 #endif
720 return FALSE;
721 }
722
723 BOOLEAN
SiS_IsVAMode(struct SiS_Private * SiS_Pr)724 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
725 {
726 #ifdef SIS315H
727 unsigned short flag;
728
729 if(SiS_Pr->ChipType >= SIS_315H) {
730 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
731 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
732 }
733 #endif
734 return FALSE;
735 }
736
737 #ifdef SIS315H
738 static BOOLEAN
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)739 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
740 {
741 if(SiS_IsVAMode(SiS_Pr)) return TRUE;
742 if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
743 return FALSE;
744 }
745 #endif
746
747 static BOOLEAN
SiS_IsDualLink(struct SiS_Private * SiS_Pr)748 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
749 {
750 #ifdef SIS315H
751 if(SiS_Pr->ChipType >= SIS_315H) {
752 if((SiS_CRT2IsLCD(SiS_Pr)) ||
753 (SiS_IsVAMode(SiS_Pr))) {
754 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
755 }
756 }
757 #endif
758 return FALSE;
759 }
760
761 #ifdef SIS315H
762 static BOOLEAN
SiS_TVEnabled(struct SiS_Private * SiS_Pr)763 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
764 {
765 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
766 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
767 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
768 }
769 return FALSE;
770 }
771 #endif
772
773 #ifdef SIS315H
774 static BOOLEAN
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)775 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
776 {
777 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
778 return FALSE;
779 }
780 #endif
781
782 #ifdef SIS315H
783 static BOOLEAN
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)784 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
785 {
786 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
787 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
788 }
789 return FALSE;
790 }
791 #endif
792
793 #ifdef SIS315H
794 static BOOLEAN
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)795 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
796 {
797 unsigned short flag;
798
799 if(SiS_Pr->ChipType == SIS_650) {
800 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
801 /* Check for revision != A0 only */
802 if((flag == 0xe0) || (flag == 0xc0) ||
803 (flag == 0xb0) || (flag == 0x90)) return FALSE;
804 } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
805 return TRUE;
806 }
807 #endif
808
809 #ifdef SIS315H
810 static BOOLEAN
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)811 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
812 {
813 if(SiS_Pr->ChipType >= SIS_315H) {
814 /* YPrPb = 0x08 */
815 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
816 }
817 return FALSE;
818 }
819 #endif
820
821 #ifdef SIS315H
822 static BOOLEAN
SiS_IsChScart(struct SiS_Private * SiS_Pr)823 SiS_IsChScart(struct SiS_Private *SiS_Pr)
824 {
825 if(SiS_Pr->ChipType >= SIS_315H) {
826 /* Scart = 0x04 */
827 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
828 }
829 return FALSE;
830 }
831 #endif
832
833 #ifdef SIS315H
834 static BOOLEAN
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)835 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
836 {
837 unsigned short flag;
838
839 if(SiS_Pr->ChipType >= SIS_315H) {
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
841 if(flag & SetCRT2ToTV) return TRUE;
842 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
843 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
844 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
845 } else {
846 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
847 if(flag & SetCRT2ToTV) return TRUE;
848 }
849 return FALSE;
850 }
851 #endif
852
853 #ifdef SIS315H
854 static BOOLEAN
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)855 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
856 {
857 unsigned short flag;
858
859 if(SiS_Pr->ChipType >= SIS_315H) {
860 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
861 if(flag & SetCRT2ToLCD) return TRUE;
862 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
863 if(flag & SetToLCDA) return TRUE;
864 } else {
865 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
866 if(flag & SetCRT2ToLCD) return TRUE;
867 }
868 return FALSE;
869 }
870 #endif
871
872 static BOOLEAN
SiS_HaveBridge(struct SiS_Private * SiS_Pr)873 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
874 {
875 unsigned short flag;
876
877 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
878 return TRUE;
879 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
880 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
881 if((flag == 1) || (flag == 2)) return TRUE;
882 }
883 return FALSE;
884 }
885
886 static BOOLEAN
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)887 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
888 {
889 unsigned short flag;
890
891 if(SiS_HaveBridge(SiS_Pr)) {
892 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
893 if(SiS_Pr->ChipType < SIS_315H) {
894 flag &= 0xa0;
895 if((flag == 0x80) || (flag == 0x20)) return TRUE;
896 } else {
897 flag &= 0x50;
898 if((flag == 0x40) || (flag == 0x10)) return TRUE;
899 }
900 }
901 return FALSE;
902 }
903
904 static BOOLEAN
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)905 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
906 {
907 unsigned short flag1;
908
909 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
910 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
911 return FALSE;
912 }
913
914 /*********************************************/
915 /* GET VIDEO BRIDGE CONFIG INFO */
916 /*********************************************/
917
918 /* Setup general purpose IO for Chrontel communication */
919 #ifdef SIS300
920 void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)921 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
922 {
923 unsigned int acpibase;
924 unsigned short temp;
925
926 if(!(SiS_Pr->SiS_ChSW)) return;
927
928 #ifdef SIS_LINUX_KERNEL
929 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
930 #else
931 acpibase = sis_pci_read_device_u32(1, 0x74);
932 #endif
933 acpibase &= 0xFFFF;
934 if(!acpibase) return;
935 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
936 temp &= 0xFEFF;
937 SiS_SetRegShort((acpibase + 0x3c), temp);
938 temp = SiS_GetRegShort((acpibase + 0x3c));
939 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
940 temp &= 0xFEFF;
941 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
942 SiS_SetRegShort((acpibase + 0x3a), temp);
943 temp = SiS_GetRegShort((acpibase + 0x3a));
944 }
945 #endif
946
947 void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)948 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
949 unsigned short ModeIdIndex, int checkcrt2mode)
950 {
951 unsigned short tempax, tempbx, temp;
952 unsigned short modeflag, resinfo = 0;
953
954 SiS_Pr->SiS_SetFlag = 0;
955
956 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
957
958 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
959
960 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
961 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
962 }
963
964 tempbx = 0;
965
966 if(SiS_HaveBridge(SiS_Pr)) {
967
968 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
969 tempbx |= temp;
970 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
971 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
972 tempbx |= tempax;
973
974 #ifdef SIS315H
975 if(SiS_Pr->ChipType >= SIS_315H) {
976 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
977 if(ModeNo == 0x03) {
978 /* Mode 0x03 is never in driver mode */
979 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
980 }
981 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
982 /* Reset LCDA setting if not driver mode */
983 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 }
985 if(IS_SIS650) {
986 if(SiS_Pr->SiS_UseLCDA) {
987 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
988 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
989 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
990 }
991 }
992 }
993 }
994 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
995 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
996 tempbx |= SetCRT2ToLCDA;
997 }
998 }
999
1000 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1001 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1002 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1003 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1004 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1005 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1006 tempbx |= SetCRT2ToYPbPr525750;
1007 }
1008 }
1009 }
1010
1011 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1012 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1013 if(temp & SetToLCDA) {
1014 tempbx |= SetCRT2ToLCDA;
1015 }
1016 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1017 if(temp & EnableCHYPbPr) {
1018 tempbx |= SetCRT2ToCHYPbPr;
1019 }
1020 }
1021 }
1022 }
1023
1024 #endif /* SIS315H */
1025
1026 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1027 tempbx &= ~(SetCRT2ToRAMDAC);
1028 }
1029
1030 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1031 temp = SetCRT2ToSVIDEO |
1032 SetCRT2ToAVIDEO |
1033 SetCRT2ToSCART |
1034 SetCRT2ToLCDA |
1035 SetCRT2ToLCD |
1036 SetCRT2ToRAMDAC |
1037 SetCRT2ToHiVision |
1038 SetCRT2ToYPbPr525750;
1039 } else {
1040 if(SiS_Pr->ChipType >= SIS_315H) {
1041 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1042 temp = SetCRT2ToAVIDEO |
1043 SetCRT2ToSVIDEO |
1044 SetCRT2ToSCART |
1045 SetCRT2ToLCDA |
1046 SetCRT2ToLCD |
1047 SetCRT2ToCHYPbPr;
1048 } else {
1049 temp = SetCRT2ToLCDA |
1050 SetCRT2ToLCD;
1051 }
1052 } else {
1053 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1054 temp = SetCRT2ToTV | SetCRT2ToLCD;
1055 } else {
1056 temp = SetCRT2ToLCD;
1057 }
1058 }
1059 }
1060
1061 if(!(tempbx & temp)) {
1062 tempax = DisableCRT2Display;
1063 tempbx = 0;
1064 }
1065
1066 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1067
1068 unsigned short clearmask = ( DriverMode |
1069 DisableCRT2Display |
1070 LoadDACFlag |
1071 SetNotSimuMode |
1072 SetInSlaveMode |
1073 SetPALTV |
1074 SwitchCRT2 |
1075 SetSimuScanMode );
1076
1077 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1078 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1079 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1080 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1081 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1082 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1083
1084 } else {
1085
1086 if(SiS_Pr->ChipType >= SIS_315H) {
1087 if(tempbx & SetCRT2ToLCDA) {
1088 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1089 }
1090 }
1091 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1092 if(tempbx & SetCRT2ToTV) {
1093 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1094 }
1095 }
1096 if(tempbx & SetCRT2ToLCD) {
1097 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1098 }
1099 if(SiS_Pr->ChipType >= SIS_315H) {
1100 if(tempbx & SetCRT2ToLCDA) {
1101 tempbx |= SetCRT2ToLCD;
1102 }
1103 }
1104
1105 }
1106
1107 if(tempax & DisableCRT2Display) {
1108 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1109 tempbx = SetSimuScanMode | DisableCRT2Display;
1110 }
1111 }
1112
1113 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1114
1115 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1116 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1117 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1118 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1119 modeflag &= (~CRT2Mode);
1120 }
1121 }
1122
1123 if(!(tempbx & SetSimuScanMode)) {
1124 if(tempbx & SwitchCRT2) {
1125 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1126 if(resinfo != SIS_RI_1600x1200) {
1127 tempbx |= SetSimuScanMode;
1128 }
1129 }
1130 } else {
1131 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1132 if(!(tempbx & DriverMode)) {
1133 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1134 tempbx |= SetSimuScanMode;
1135 }
1136 }
1137 }
1138 }
1139 }
1140
1141 if(!(tempbx & DisableCRT2Display)) {
1142 if(tempbx & DriverMode) {
1143 if(tempbx & SetSimuScanMode) {
1144 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1145 if(resinfo != SIS_RI_1600x1200) {
1146 tempbx |= SetInSlaveMode;
1147 }
1148 }
1149 }
1150 } else {
1151 tempbx |= SetInSlaveMode;
1152 }
1153 }
1154
1155 }
1156
1157 SiS_Pr->SiS_VBInfo = tempbx;
1158
1159 #ifdef SIS300
1160 if(SiS_Pr->ChipType == SIS_630) {
1161 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1162 }
1163 #endif
1164
1165 #ifdef SIS_LINUX_KERNEL
1166 #if 0
1167 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1168 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1169 #endif
1170 #endif
1171 #ifdef SIS_XORG_XF86
1172 #ifdef TWDEBUG
1173 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1174 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1175 #endif
1176 #endif
1177 }
1178
1179 /*********************************************/
1180 /* DETERMINE YPbPr MODE */
1181 /*********************************************/
1182
1183 void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1184 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1185 {
1186
1187 unsigned char temp;
1188
1189 /* Note: This variable is only used on 30xLV systems.
1190 * CR38 has a different meaning on LVDS/CH7019 systems.
1191 * On 661 and later, these bits moved to CR35.
1192 *
1193 * On 301, 301B, only HiVision 1080i is supported.
1194 * On 30xLV, 301C, only YPbPr 1080i is supported.
1195 */
1196
1197 SiS_Pr->SiS_YPbPr = 0;
1198 if(SiS_Pr->ChipType >= SIS_661) return;
1199
1200 if(SiS_Pr->SiS_VBType) {
1201 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1202 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1203 }
1204 }
1205
1206 if(SiS_Pr->ChipType >= SIS_315H) {
1207 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1208 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1209 if(temp & 0x08) {
1210 switch((temp >> 4)) {
1211 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1212 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1213 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1214 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1215 }
1216 }
1217 }
1218 }
1219
1220 }
1221
1222 /*********************************************/
1223 /* DETERMINE TVMode flag */
1224 /*********************************************/
1225
1226 void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1227 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1228 {
1229 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1230 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1231 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1232
1233 SiS_Pr->SiS_TVMode = 0;
1234
1235 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1236 if(SiS_Pr->UseCustomMode) return;
1237
1238 if(ModeNo > 0x13) {
1239 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1240 }
1241
1242 if(SiS_Pr->ChipType < SIS_661) {
1243
1244 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1245
1246 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1247 temp = 0;
1248 if((SiS_Pr->ChipType == SIS_630) ||
1249 (SiS_Pr->ChipType == SIS_730)) {
1250 temp = 0x35;
1251 romindex = 0xfe;
1252 } else if(SiS_Pr->ChipType >= SIS_315H) {
1253 temp = 0x38;
1254 if(SiS_Pr->ChipType < XGI_20) {
1255 romindex = 0xf3;
1256 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1257 }
1258 }
1259 if(temp) {
1260 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1261 OutputSelect = ROMAddr[romindex];
1262 if(!(OutputSelect & EnablePALMN)) {
1263 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1264 }
1265 }
1266 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1267 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1268 if(temp1 & EnablePALM) { /* 0x40 */
1269 SiS_Pr->SiS_TVMode |= TVSetPALM;
1270 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1271 } else if(temp1 & EnablePALN) { /* 0x80 */
1272 SiS_Pr->SiS_TVMode |= TVSetPALN;
1273 }
1274 } else {
1275 if(temp1 & EnableNTSCJ) { /* 0x40 */
1276 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1277 }
1278 }
1279 }
1280 /* Translate HiVision/YPbPr to our new flags */
1281 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1282 if(SiS_Pr->SiS_YPbPr == YPbPr750p) {
1283 SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1284 } else if(SiS_Pr->SiS_YPbPr == YPbPr525p) {
1285 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1286 SiS_Pr->SiS_TVMode |= TVSetYPbPr625p;
1287 } else {
1288 SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1289 }
1290 } else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) {
1291 SiS_Pr->SiS_TVMode |= TVSetHiVision;
1292 } else {
1293 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1294 SiS_Pr->SiS_TVMode |= TVSetYPbPr625i;
1295 } else {
1296 SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1297 }
1298 }
1299 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p |
1300 TVSetYPbPr525p |
1301 TVSetYPbPr625p |
1302 TVSetYPbPr525i |
1303 TVSetYPbPr625i)) {
1304 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1305 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1306 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1307 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1308 SiS_Pr->SiS_TVMode |= TVSetPAL;
1309 }
1310 }
1311 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1312 if(SiS_Pr->SiS_CHOverScan) {
1313 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1314 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1315 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1316 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1317 }
1318 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1319 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1320 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1321 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1322 }
1323 }
1324 if(SiS_Pr->SiS_CHSOverScan) {
1325 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1326 }
1327 }
1328 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1329 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1330 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1331 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1332 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1333 } else {
1334 if(temp & EnableNTSCJ) {
1335 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1336 }
1337 }
1338 }
1339 }
1340
1341 } else { /* 661 and later */
1342
1343 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1344 if(temp1 & 0x01) {
1345 SiS_Pr->SiS_TVMode |= TVSetPAL;
1346 if(temp1 & 0x08) {
1347 SiS_Pr->SiS_TVMode |= TVSetPALN;
1348 } else if(temp1 & 0x04) {
1349 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1350 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1351 }
1352 SiS_Pr->SiS_TVMode |= TVSetPALM;
1353 }
1354 } else {
1355 if(temp1 & 0x02) {
1356 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1357 }
1358 }
1359 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1360 if(SiS_Pr->SiS_CHOverScan) {
1361 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1362 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1363 }
1364 }
1365 }
1366 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1367 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1368 temp1 &= 0xe0;
1369 if(temp1 == 0x00) {
1370 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1371 SiS_Pr->SiS_TVMode |= TVSetYPbPr625i;
1372 } else {
1373 SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1374 }
1375 } else if(temp1 == 0x20) {
1376 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1377 SiS_Pr->SiS_TVMode |= TVSetYPbPr625p;
1378 } else {
1379 SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1380 }
1381 } else if(temp1 == 0x40) {
1382 SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1383 }
1384 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1385 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1386 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1387 }
1388 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1389 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1390 SiS_Pr->SiS_TVMode |= TVAspect169;
1391 } else {
1392 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1393 if(temp1 & 0x02) {
1394 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1395 SiS_Pr->SiS_TVMode |= TVAspect169;
1396 } else {
1397 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1398 }
1399 } else {
1400 SiS_Pr->SiS_TVMode |= TVAspect43;
1401 }
1402 }
1403 }
1404 }
1405 }
1406
1407 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1408
1409 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1410
1411 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1412 SiS_Pr->SiS_TVMode |= TVSetPAL;
1413 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1414 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1415 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i |
1416 TVSetYPbPr625i |
1417 TVSetYPbPr525p |
1418 TVSetYPbPr625p |
1419 TVSetYPbPr750p)) {
1420 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1421 }
1422 }
1423
1424 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1425 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1426 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1427 }
1428 }
1429
1430 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1431 if(resinfo == SIS_RI_1024x768) {
1432 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1433 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1434 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision |
1435 TVSetYPbPr750p |
1436 TVSetYPbPr625p |
1437 TVSetYPbPr625i))) {
1438 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1439 }
1440 }
1441 }
1442
1443 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1444 if(resinfo == SIS_RI_960x540) {
1445 SiS_Pr->SiS_TVMode |= TVSetHiVi960540;
1446 }
1447 }
1448
1449 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1450 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1451 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1452 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1453 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) {
1454 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1455 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1456 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1457 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1458 }
1459 }
1460
1461 }
1462
1463 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1464
1465 #ifdef SIS_XORG_XF86
1466 #ifdef TWDEBUG
1467 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1468 #endif
1469 #endif
1470 }
1471
1472 /*********************************************/
1473 /* GET LCD INFO */
1474 /*********************************************/
1475
1476 static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1477 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1478 {
1479 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1480 /* Translate my LCDResInfo to BIOS value */
1481 switch(temp) {
1482 case Panel_1280x768_2: temp = Panel_1280x768; break;
1483 case Panel_1280x800_2: temp = Panel_1280x800; break;
1484 case Panel_1280x854: temp = Panel661_1280x854; break;
1485 }
1486 return temp;
1487 }
1488
1489 static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1490 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1491 {
1492 #ifdef SIS315H
1493 unsigned char *ROMAddr;
1494 unsigned short temp;
1495
1496 #ifdef SIS_XORG_XF86
1497 #ifdef TWDEBUG
1498 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1499 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1500 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1501 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1502 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1503 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1504 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1505 #endif
1506 #endif
1507
1508 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1509 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1510 SiS_Pr->SiS_NeedRomModeData = TRUE;
1511 SiS_Pr->PanelHT = temp;
1512 }
1513 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1514 SiS_Pr->SiS_NeedRomModeData = TRUE;
1515 SiS_Pr->PanelVT = temp;
1516 }
1517 SiS_Pr->PanelHRS = SISGETROMW(10);
1518 SiS_Pr->PanelHRE = SISGETROMW(12);
1519 SiS_Pr->PanelVRS = SISGETROMW(14);
1520 SiS_Pr->PanelVRE = SISGETROMW(16);
1521 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1522 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1523 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1524 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1525 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1526 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1527 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1528
1529 #ifdef SIS_XORG_XF86
1530 #ifdef TWDEBUG
1531 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1532 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1533 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1534 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1535 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1536 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1537 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1538 #endif
1539 #endif
1540
1541 }
1542 #endif
1543 }
1544
1545 static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1546 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1547 const unsigned char *nonscalingmodes)
1548 {
1549 int i = 0;
1550 while(nonscalingmodes[i] != 0xff) {
1551 if(nonscalingmodes[i++] == resinfo) {
1552 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1553 (SiS_Pr->UsePanelScaler == -1)) {
1554 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1555 }
1556 break;
1557 }
1558 }
1559 }
1560
1561 void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1562 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1563 {
1564 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1565 BOOLEAN panelcanscale = FALSE;
1566 #ifdef SIS300
1567 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1568 static const unsigned char SiS300SeriesLCDRes[] =
1569 { 0, 1, 2, 3, 7, 4, 5, 8,
1570 0, 0, 10, 0, 0, 0, 0, 15 };
1571 #endif
1572 #ifdef SIS315H
1573 unsigned char *myptr = NULL;
1574 #endif
1575
1576 SiS_Pr->SiS_LCDResInfo = 0;
1577 SiS_Pr->SiS_LCDTypeInfo = 0;
1578 SiS_Pr->SiS_LCDInfo = 0;
1579 SiS_Pr->PanelHRS = 999; /* HSync start */
1580 SiS_Pr->PanelHRE = 999; /* HSync end */
1581 SiS_Pr->PanelVRS = 999; /* VSync start */
1582 SiS_Pr->PanelVRE = 999; /* VSync end */
1583 SiS_Pr->SiS_NeedRomModeData = FALSE;
1584
1585 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1586 SiS_Pr->Alternate1600x1200 = FALSE;
1587
1588 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1589
1590 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1591
1592 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1593 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1594 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1595 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1596 }
1597
1598 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1599
1600 /* For broken BIOSes: Assume 1024x768 */
1601 if(temp == 0) temp = 0x02;
1602
1603 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1604 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1605 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1606 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1607 } else {
1608 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1609 }
1610 temp &= 0x0f;
1611 #ifdef SIS300
1612 if(SiS_Pr->ChipType < SIS_315H) {
1613 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1614 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1615 if(temp < 0x0f) temp &= 0x07;
1616 }
1617 /* Translate 300 series LCDRes to 315 series for unified usage */
1618 temp = SiS300SeriesLCDRes[temp];
1619 }
1620 #endif
1621
1622 /* Translate to our internal types */
1623 #ifdef SIS315H
1624 if(SiS_Pr->ChipType == SIS_550) {
1625 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1626 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1627 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1628 } else if(SiS_Pr->ChipType >= SIS_661) {
1629 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1630 }
1631 #endif
1632
1633 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1634 if(temp == Panel310_1280x768) {
1635 temp = Panel_1280x768_2;
1636 }
1637 if(SiS_Pr->SiS_ROMNew) {
1638 if(temp == Panel661_1280x800) {
1639 temp = Panel_1280x800_2;
1640 }
1641 }
1642 }
1643
1644 SiS_Pr->SiS_LCDResInfo = temp;
1645
1646 #ifdef SIS300
1647 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1648 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1649 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1650 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1651 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1652 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1653 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1654 }
1655 }
1656 #endif
1657
1658 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1659 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1660 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1661 } else {
1662 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1663 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1664 }
1665
1666 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1667 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1668 /* Need temp below! */
1669
1670 /* These must/can't scale no matter what */
1671 switch(SiS_Pr->SiS_LCDResInfo) {
1672 case Panel_320x240_1:
1673 case Panel_320x240_2:
1674 case Panel_320x240_3:
1675 case Panel_1280x960:
1676 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1677 break;
1678 case Panel_640x480:
1679 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1680 }
1681
1682 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1683
1684 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1685 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1686
1687 /* Dual link, Pass 1:1 BIOS default, etc. */
1688 #ifdef SIS315H
1689 if(SiS_Pr->ChipType >= SIS_661) {
1690 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1691 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1692 }
1693 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1694 if(SiS_Pr->SiS_ROMNew) {
1695 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1696 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1697 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1698 }
1699 }
1700 } else if(SiS_Pr->ChipType >= SIS_315H) {
1701 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1702 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1703 }
1704 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1705 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1706 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1707 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1708 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1709 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1710 }
1711 } else if(!(SiS_Pr->SiS_ROMNew)) {
1712 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1713 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1714 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1715 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1716 }
1717 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1718 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1719 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1720 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1721 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1722 }
1723 }
1724 }
1725 }
1726 #endif
1727
1728 /* Pass 1:1 */
1729 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1730 /* Always center screen on LVDS (if scaling is disabled) */
1731 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1732 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1733 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1734 /* Always center screen on SiS LVDS (if scaling is disabled) */
1735 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1736 } else {
1737 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1738 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1739 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1740 }
1741 }
1742
1743 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1744 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1745
1746 switch(SiS_Pr->SiS_LCDResInfo) {
1747 case Panel_320x240_1:
1748 case Panel_320x240_2:
1749 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1750 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1751 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1752 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1753 break;
1754 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1755 SiS_Pr->PanelVRE = 3;
1756 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1757 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1758 break;
1759 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1760 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1761 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1762 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1763 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1764 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1765 break;
1766 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1767 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1768 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1769 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1770 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1771 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1772 break;
1773 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1774 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1775 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1776 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1777 if(SiS_Pr->ChipType < SIS_315H) {
1778 SiS_Pr->PanelHRS = 23;
1779 SiS_Pr->PanelVRE = 5;
1780 }
1781 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1782 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1783 SiS_GetLCDInfoBIOS(SiS_Pr);
1784 break;
1785 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1786 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1787 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1788 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1789 if(SiS_Pr->ChipType < SIS_315H) {
1790 SiS_Pr->PanelHRS = 23;
1791 SiS_Pr->PanelVRE = 5;
1792 }
1793 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1794 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1795 break;
1796 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1797 break;
1798 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1799 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1800 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1801 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1802 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1803 /* Data above for TMDS (projector); get from BIOS for LVDS */
1804 SiS_GetLCDInfoBIOS(SiS_Pr);
1805 break;
1806 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1807 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1808 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1809 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1810 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1811 } else {
1812 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1813 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1814 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1815 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1816 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1817 }
1818 break;
1819 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1820 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1821 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1822 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1823 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1824 SiS_GetLCDInfoBIOS(SiS_Pr);
1825 break;
1826 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1827 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1828 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1829 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1830 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1831 SiS_GetLCDInfoBIOS(SiS_Pr);
1832 break;
1833 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1834 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1835 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1836 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1837 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1838 SiS_GetLCDInfoBIOS(SiS_Pr);
1839 break;
1840 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1841 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1842 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1843 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1844 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1845 SiS_GetLCDInfoBIOS(SiS_Pr);
1846 break;
1847 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1848 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1849 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1850 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1851 if(resinfo == SIS_RI_1280x1024) {
1852 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1853 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1854 }
1855 break;
1856 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1857 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1858 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1859 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1860 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1861 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1862 SiS_GetLCDInfoBIOS(SiS_Pr);
1863 break;
1864 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1865 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1866 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1867 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1868 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1869 SiS_GetLCDInfoBIOS(SiS_Pr);
1870 break;
1871 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1872 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1873 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1874 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1875 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1876 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1877 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1878 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1879 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1880 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1881 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1882 SiS_Pr->Alternate1600x1200 = TRUE;
1883 }
1884 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1885 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1886 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1887 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1888 }
1889 SiS_GetLCDInfoBIOS(SiS_Pr);
1890 break;
1891 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1892 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1893 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1894 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1895 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1896 SiS_GetLCDInfoBIOS(SiS_Pr);
1897 break;
1898 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1899 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1900 break;
1901 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1902 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1903 break;
1904 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1905 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1906 break;
1907 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1908 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1909 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1910 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1911 if(SiS_Pr->CP_PreferredIndex != -1) {
1912 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1913 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1914 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1915 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1916 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1917 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1918 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1919 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1920 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1921 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1922 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1923 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1924 if(SiS_Pr->CP_PrefClock) {
1925 int idx;
1926 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1927 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1928 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1929 else idx = VCLK_CUSTOM_315;
1930 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1931 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1932 SiS_Pr->SiS_VCLKData[idx].SR2B =
1933 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1934 SiS_Pr->SiS_VCLKData[idx].SR2C =
1935 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1936 }
1937 }
1938 break;
1939 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1940 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1941 break;
1942 }
1943
1944 /* Special cases */
1945 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1946 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1947 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1948 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1949 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1950 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1951 SiS_Pr->PanelHRS = 999;
1952 SiS_Pr->PanelHRE = 999;
1953 }
1954
1955 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1956 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1957 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1958 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1959 SiS_Pr->PanelVRS = 999;
1960 SiS_Pr->PanelVRE = 999;
1961 }
1962
1963 /* DontExpand overrule */
1964 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1965
1966 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1967 /* No scaling for this mode on any panel (LCD=CRT2)*/
1968 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1969 }
1970
1971 switch(SiS_Pr->SiS_LCDResInfo) {
1972
1973 case Panel_Custom:
1974 case Panel_1152x864:
1975 case Panel_1280x768: /* TMDS only */
1976 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1977 break;
1978
1979 case Panel_800x600: {
1980 static const unsigned char nonscalingmodes[] = {
1981 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1982 };
1983 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1984 break;
1985 }
1986 case Panel_1024x768: {
1987 static const unsigned char nonscalingmodes[] = {
1988 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1989 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1990 0xff
1991 };
1992 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1993 break;
1994 }
1995 case Panel_1280x720: {
1996 static const unsigned char nonscalingmodes[] = {
1997 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1998 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1999 0xff
2000 };
2001 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2002 if(SiS_Pr->PanelHT == 1650) {
2003 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2004 }
2005 break;
2006 }
2007 case Panel_1280x768_2: { /* LVDS only */
2008 static const unsigned char nonscalingmodes[] = {
2009 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2010 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2011 SIS_RI_1152x768,0xff
2012 };
2013 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 switch(resinfo) {
2015 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2016 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2017 }
2018 break;
2019 }
2020 break;
2021 }
2022 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
2023 static const unsigned char nonscalingmodes[] = {
2024 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2025 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2026 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2027 };
2028 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2029 break;
2030 }
2031 case Panel_1280x800_2: { /* SiS LVDS */
2032 static const unsigned char nonscalingmodes[] = {
2033 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2034 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2035 SIS_RI_1152x768,0xff
2036 };
2037 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2038 switch(resinfo) {
2039 case SIS_RI_1280x720:
2040 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
2041 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2042 }
2043 break;
2044 }
2045 break;
2046 }
2047 case Panel_1280x854: { /* SiS LVDS */
2048 static const unsigned char nonscalingmodes[] = {
2049 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2050 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2051 SIS_RI_1152x768,0xff
2052 };
2053 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2054 switch(resinfo) {
2055 case SIS_RI_1280x720:
2056 case SIS_RI_1280x768:
2057 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2058 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2059 }
2060 break;
2061 }
2062 break;
2063 }
2064 case Panel_1280x960: {
2065 static const unsigned char nonscalingmodes[] = {
2066 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2067 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2068 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2069 SIS_RI_1280x854,0xff
2070 };
2071 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2072 break;
2073 }
2074 case Panel_1280x1024: {
2075 static const unsigned char nonscalingmodes[] = {
2076 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2077 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2078 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2079 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2080 };
2081 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2082 break;
2083 }
2084 case Panel_1400x1050: {
2085 static const unsigned char nonscalingmodes[] = {
2086 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2087 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2088 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2089 SIS_RI_1280x960,0xff
2090 };
2091 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2092 switch(resinfo) {
2093 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2094 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2095 }
2096 break;
2097 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2098 break;
2099 }
2100 break;
2101 }
2102 case Panel_1600x1200: {
2103 static const unsigned char nonscalingmodes[] = {
2104 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2105 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2106 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2107 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2108 };
2109 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2110 break;
2111 }
2112 case Panel_1680x1050: {
2113 static const unsigned char nonscalingmodes[] = {
2114 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2115 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2116 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2117 SIS_RI_1360x1024,0xff
2118 };
2119 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2120 break;
2121 }
2122 }
2123 }
2124
2125 #ifdef SIS300
2126 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2127 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2128 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2129 }
2130 }
2131
2132 if(SiS_Pr->ChipType < SIS_315H) {
2133 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2134 if(SiS_Pr->SiS_UseROM) {
2135 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2136 if(!(ROMAddr[0x235] & 0x02)) {
2137 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2138 }
2139 }
2140 }
2141 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2142 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2143 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2144 }
2145 }
2146 }
2147 #endif
2148
2149 /* Special cases */
2150
2151 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2152 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2153 }
2154
2155 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2156 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2157 }
2158
2159 switch(SiS_Pr->SiS_LCDResInfo) {
2160 case Panel_640x480:
2161 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2162 break;
2163 case Panel_1280x800:
2164 /* Don't pass 1:1 by default (TMDS special) */
2165 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2166 break;
2167 case Panel_1280x960:
2168 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2169 break;
2170 case Panel_Custom:
2171 if((!SiS_Pr->CP_PrefClock) ||
2172 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2173 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2174 }
2175 break;
2176 }
2177
2178 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2179 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2180 }
2181
2182 /* (In)validate LCDPass11 flag */
2183 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2184 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2185 }
2186
2187 /* LVDS DDA */
2188 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2189
2190 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2191 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2192 if(ModeNo == 0x12) {
2193 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2194 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2195 }
2196 } else if(ModeNo > 0x13) {
2197 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2198 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2199 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2200 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2201 }
2202 }
2203 }
2204 }
2205 }
2206 }
2207
2208 if(modeflag & HalfDCLK) {
2209 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2210 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2211 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2212 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2213 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2214 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2215 } else if(ModeNo > 0x13) {
2216 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2217 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2218 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2219 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2220 }
2221 }
2222 }
2223
2224 }
2225
2226 /* VESA timing */
2227 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2228 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2229 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2230 }
2231 } else {
2232 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2233 }
2234
2235 #ifdef SIS_LINUX_KERNEL
2236 #if 0
2237 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2238 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2239 #endif
2240 #endif
2241 #ifdef SIS_XORG_XF86
2242 xf86DrvMsgVerb(0, X_PROBED, 4,
2243 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2244 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2245 #endif
2246 }
2247
2248 /*********************************************/
2249 /* GET VCLK */
2250 /*********************************************/
2251
2252 unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2253 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2254 unsigned short RefreshRateTableIndex)
2255 {
2256 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2257 unsigned short resinfo, tempbx;
2258 const unsigned char *CHTVVCLKPtr = NULL;
2259
2260 if(ModeNo <= 0x13) {
2261 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2262 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2263 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2264 VCLKIndexGENCRT = VCLKIndexGEN;
2265 } else {
2266 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2267 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2268 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2269 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2270 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2271 }
2272
2273 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2274
2275 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2276
2277 CRT2Index >>= 6;
2278 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2279
2280 if(SiS_Pr->ChipType < SIS_315H) {
2281 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2282 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2283 VCLKIndex = VCLKIndexGEN;
2284 }
2285 } else {
2286 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2287 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2288 switch(resinfo) {
2289 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2290 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2291 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2292 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2293 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2294 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2295 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2296 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2297 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2298 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2299 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2300 default: VCLKIndex = VCLKIndexGEN;
2301 }
2302
2303 if(ModeNo <= 0x13) {
2304 if(SiS_Pr->ChipType <= SIS_315PRO) {
2305 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2306 } else {
2307 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2308 }
2309 }
2310 if(SiS_Pr->ChipType <= SIS_315PRO) {
2311 if(VCLKIndex == 0) VCLKIndex = 0x41;
2312 if(VCLKIndex == 1) VCLKIndex = 0x43;
2313 if(VCLKIndex == 4) VCLKIndex = 0x44;
2314 }
2315 }
2316 }
2317
2318 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2319
2320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2321 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2322 else VCLKIndex = HiTVVCLK;
2323 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2324 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)
2325 VCLKIndex = YPbPr750pVCLK;
2326 else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p | TVRPLLDIV2XO))
2327 VCLKIndex = TVVCLKDIV2;
2328 else
2329 VCLKIndex = TVVCLK;
2330
2331 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2332 else VCLKIndex += TVCLKBASE_315;
2333
2334 } else { /* VGA2 */
2335
2336 VCLKIndex = VCLKIndexGENCRT;
2337 if(SiS_Pr->ChipType < SIS_315H) {
2338 if(ModeNo > 0x13) {
2339 if( (SiS_Pr->ChipType == SIS_630) &&
2340 (SiS_Pr->ChipRevision >= 0x30)) {
2341 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2342 }
2343 /* Better VGA2 clock for 1280x1024@75 */
2344 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2345 }
2346 }
2347 }
2348
2349 } else { /* If not programming CRT2 */
2350
2351 VCLKIndex = VCLKIndexGENCRT;
2352 if(SiS_Pr->ChipType < SIS_315H) {
2353 if(ModeNo > 0x13) {
2354 if( (SiS_Pr->ChipType != SIS_630) &&
2355 (SiS_Pr->ChipType != SIS_300) ) {
2356 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2357 }
2358 }
2359 }
2360 }
2361
2362 } else { /* LVDS */
2363
2364 VCLKIndex = CRT2Index;
2365
2366 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2367
2368 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2369
2370 VCLKIndex &= 0x1f;
2371 tempbx = 0;
2372 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2373 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2374 tempbx += 2;
2375 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2376 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2377 }
2378 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2379 tempbx = 4;
2380 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2381 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2382 tempbx = 6;
2383 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2384 }
2385 }
2386 switch(tempbx) {
2387 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2388 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2389 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2390 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2391 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2392 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2393 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2394 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2395 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2396 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2397 }
2398 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2399
2400 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2401
2402 if(SiS_Pr->ChipType < SIS_315H) {
2403 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2404 } else {
2405 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2406 }
2407
2408 #ifdef SIS300
2409 /* Special Timing: Barco iQ Pro R series */
2410 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2411
2412 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2413 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2414 if(SiS_Pr->ChipType < SIS_315H) {
2415 VCLKIndex = VCLK34_300;
2416 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2417 } else {
2418 VCLKIndex = VCLK34_315;
2419 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2420 }
2421 }
2422 #endif
2423
2424 } else {
2425
2426 VCLKIndex = VCLKIndexGENCRT;
2427 if(SiS_Pr->ChipType < SIS_315H) {
2428 if(ModeNo > 0x13) {
2429 if( (SiS_Pr->ChipType == SIS_630) &&
2430 (SiS_Pr->ChipRevision >= 0x30) ) {
2431 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2432 }
2433 }
2434 }
2435 }
2436
2437 } else { /* if not programming CRT2 */
2438
2439 VCLKIndex = VCLKIndexGENCRT;
2440 if(SiS_Pr->ChipType < SIS_315H) {
2441 if(ModeNo > 0x13) {
2442 if( (SiS_Pr->ChipType != SIS_630) &&
2443 (SiS_Pr->ChipType != SIS_300) ) {
2444 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2445 }
2446 #if 0
2447 if(SiS_Pr->ChipType == SIS_730) {
2448 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2449 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2450 }
2451 #endif
2452 }
2453 }
2454
2455 }
2456
2457 }
2458
2459 #ifdef SIS_XORG_XF86
2460 #ifdef TWDEBUG
2461 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2462 #endif
2463 #endif
2464
2465 return VCLKIndex;
2466 }
2467
2468 /*********************************************/
2469 /* SET CRT2 MODE TYPE REGISTERS */
2470 /*********************************************/
2471
2472 static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2473 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2474 {
2475 unsigned short i, j, modeflag, tempah=0;
2476 short tempcl;
2477 #if defined(SIS300) || defined(SIS315H)
2478 unsigned short tempbl;
2479 #endif
2480 #ifdef SIS315H
2481 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2482 unsigned short tempah2, tempbl2;
2483 #endif
2484
2485 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2486
2487 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2488
2489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2490 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2491
2492 } else {
2493
2494 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2495 if(SiS_Pr->ChipType >= SIS_315H) {
2496 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2497 }
2498
2499 tempcl = SiS_Pr->SiS_ModeType;
2500
2501 if(SiS_Pr->ChipType < SIS_315H) {
2502
2503 #ifdef SIS300 /* ---- 300 series ---- */
2504
2505 /* For 301BDH: (with LCD via LVDS) */
2506 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2507 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2508 tempbl &= 0xef;
2509 tempbl |= 0x02;
2510 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2511 tempbl |= 0x10;
2512 tempbl &= 0xfd;
2513 }
2514 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2515 }
2516
2517 if(ModeNo > 0x13) {
2518 tempcl -= ModeVGA;
2519 if(tempcl >= 0) {
2520 tempah = ((0x10 >> tempcl) | 0x80);
2521 }
2522 } else tempah = 0x80;
2523
2524 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2525
2526 #endif /* SIS300 */
2527
2528 } else {
2529
2530 #ifdef SIS315H /* ------- 315/330 series ------ */
2531
2532 if(ModeNo > 0x13) {
2533 tempcl -= ModeVGA;
2534 if(tempcl >= 0) {
2535 tempah = (0x08 >> tempcl);
2536 if (tempah == 0) tempah = 1;
2537 tempah |= 0x40;
2538 }
2539 } else tempah = 0x40;
2540
2541 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2542
2543 #endif /* SIS315H */
2544
2545 }
2546
2547 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2548
2549 if(SiS_Pr->ChipType < SIS_315H) {
2550 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2551 } else {
2552 #ifdef SIS315H
2553 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2554 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2555 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2556 if(IS_SIS740) {
2557 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2558 } else {
2559 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2560 }
2561 }
2562 #endif
2563 }
2564
2565 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2566
2567 tempah = 0x01;
2568 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2569 tempah |= 0x02;
2570 }
2571 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2572 tempah ^= 0x05;
2573 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2574 tempah ^= 0x01;
2575 }
2576 }
2577
2578 if(SiS_Pr->ChipType < SIS_315H) {
2579
2580 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2581
2582 tempah = (tempah << 5) & 0xFF;
2583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2584 tempah = (tempah >> 5) & 0xFF;
2585
2586 } else {
2587
2588 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2589 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2590 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2591 tempah &= ~0x08;
2592
2593 }
2594
2595 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2596 tempah |= 0x10;
2597 }
2598
2599 tempah |= 0x80;
2600 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2601 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2602 }
2603
2604 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2605 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) {
2606 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2607 tempah |= 0x20;
2608 }
2609 }
2610 }
2611
2612 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2613
2614 tempah = 0x80;
2615 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2616 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2617 }
2618
2619 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2620
2621 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2622 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2623 tempah |= 0x40;
2624 }
2625 }
2626
2627 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2628
2629 } else { /* LVDS */
2630
2631 if(SiS_Pr->ChipType >= SIS_315H) {
2632
2633 #ifdef SIS315H
2634 /* LVDS can only be slave in 8bpp modes */
2635 tempah = 0x80;
2636 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2637 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2638 tempah |= 0x02;
2639 }
2640 }
2641
2642 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2643
2644 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2645
2646 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2647
2648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2649 #endif
2650
2651 } else {
2652
2653 #ifdef SIS300
2654 tempah = 0;
2655 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2656 tempah |= 0x02;
2657 }
2658 tempah <<= 5;
2659
2660 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2661
2662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2663 #endif
2664
2665 }
2666
2667 }
2668
2669 } /* LCDA */
2670
2671 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2672
2673 if(SiS_Pr->ChipType >= SIS_315H) {
2674
2675 #ifdef SIS315H
2676 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2677
2678 /* The following is nearly unpreditable and varies from machine
2679 * to machine. Especially the 301DH seems to be a real trouble
2680 * maker. Some BIOSes simply set the registers (like in the
2681 * NoLCD-if-statements here), some set them according to the
2682 * LCDA stuff. It is very likely that some machines are not
2683 * treated correctly in the following, very case-orientated
2684 * code. What do I do then...?
2685 */
2686
2687 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2688
2689 if(!(IS_SIS740)) {
2690 tempah = 0x04; /* For all bridges */
2691 tempbl = 0xfb;
2692 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2693 tempah = 0x00;
2694 if(SiS_IsDualEdge(SiS_Pr)) {
2695 tempbl = 0xff;
2696 }
2697 }
2698 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2699 }
2700
2701 /* The following two are responsible for eventually wrong colors
2702 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2703 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2704 * in a 650 box (Jake). What is the criteria?
2705 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2706 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2707 * chipset than the bridge revision.
2708 */
2709
2710 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2711 tempah = 0x30;
2712 tempbl = 0xc0;
2713 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2714 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2715 tempah = 0x00;
2716 tempbl = 0x00;
2717 }
2718 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2719 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2720 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2721 /* Fixes "TV-blue-bug" on 315+301 */
2722 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2723 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2724 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2725 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2726 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2727 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2728 tempah = 0x30; tempah2 = 0xc0;
2729 tempbl = 0xcf; tempbl2 = 0x3f;
2730 if(SiS_Pr->SiS_TVBlue == 0) {
2731 tempah = tempah2 = 0x00;
2732 } else if(SiS_Pr->SiS_TVBlue == -1) {
2733 /* Set on 651/M650, clear on 315/650 */
2734 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2735 tempah = tempah2 = 0x00;
2736 }
2737 }
2738 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2739 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2740 } else {
2741 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2742 tempbl = 0xcf; tempbl2 = 0x3f;
2743 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2744 tempah = tempah2 = 0x00;
2745 if(SiS_IsDualEdge(SiS_Pr)) {
2746 tempbl = tempbl2 = 0xff;
2747 }
2748 }
2749 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2750 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2751 }
2752
2753 if(IS_SIS740) {
2754 tempah = 0x80;
2755 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2756 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2757 } else {
2758 tempah = 0x00;
2759 tempbl = 0x7f;
2760 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2761 tempbl = 0xff;
2762 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2763 }
2764 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2765 }
2766
2767 #endif /* SIS315H */
2768
2769 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2770
2771 #ifdef SIS300
2772 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2773
2774 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2775 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2776 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2777 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2778 } else {
2779 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2780 }
2781 #endif
2782
2783 }
2784
2785 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2786 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2787 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2788 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2789 }
2790 }
2791
2792 } else { /* LVDS */
2793
2794 #ifdef SIS315H
2795 if(SiS_Pr->ChipType >= SIS_315H) {
2796
2797 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2798
2799 tempah = 0x04;
2800 tempbl = 0xfb;
2801 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2802 tempah = 0x00;
2803 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2804 }
2805 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2806
2807 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2808 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2809 }
2810
2811 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2812
2813 } else if(SiS_Pr->ChipType == SIS_550) {
2814
2815 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2816 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2817
2818 }
2819
2820 }
2821 #endif
2822
2823 }
2824
2825 }
2826
2827 /*********************************************/
2828 /* GET RESOLUTION DATA */
2829 /*********************************************/
2830
2831 unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2832 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2833 {
2834 if(ModeNo <= 0x13)
2835 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2836 else
2837 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2838 }
2839
2840 static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2841 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2842 {
2843 unsigned short xres, yres, modeflag=0, resindex;
2844
2845 if(SiS_Pr->UseCustomMode) {
2846 xres = SiS_Pr->CHDisplay;
2847 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2848 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2849 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2850 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2851 return;
2852 }
2853
2854 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2855
2856 if(ModeNo <= 0x13) {
2857 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2858 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2859 } else {
2860 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2861 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2862 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2863 }
2864
2865 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2866
2867 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2868 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2869 if(yres == 350) yres = 400;
2870 }
2871 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2872 if(ModeNo == 0x12) yres = 400;
2873 }
2874 }
2875
2876 if(modeflag & HalfDCLK) xres <<= 1;
2877 if(modeflag & DoubleScanMode) yres <<= 1;
2878
2879 }
2880
2881 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2882
2883 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2884 switch(SiS_Pr->SiS_LCDResInfo) {
2885 case Panel_1024x768:
2886 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2887 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2888 if(yres == 350) yres = 357;
2889 if(yres == 400) yres = 420;
2890 if(yres == 480) yres = 525;
2891 }
2892 }
2893 break;
2894 case Panel_1280x1024:
2895 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2896 /* BIOS bug - does this regardless of scaling */
2897 if(yres == 400) yres = 405;
2898 }
2899 if(yres == 350) yres = 360;
2900 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2901 if(yres == 360) yres = 375;
2902 }
2903 break;
2904 case Panel_1600x1200:
2905 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2906 if(yres == 1024) yres = 1056;
2907 }
2908 break;
2909 }
2910 }
2911
2912 } else {
2913
2914 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2915 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2916 if(xres == 720) xres = 640;
2917 }
2918 } else if(xres == 720) xres = 640;
2919
2920 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2921 yres = 400;
2922 if(SiS_Pr->ChipType >= SIS_315H) {
2923 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2924 } else {
2925 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2926 }
2927 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2928 }
2929
2930 }
2931 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2932 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2933 }
2934
2935 /*********************************************/
2936 /* GET CRT2 TIMING DATA */
2937 /*********************************************/
2938
2939 static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)2940 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2941 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2942 unsigned short *ResIndex)
2943 {
2944 unsigned short tempbx=0, tempal=0, resinfo=0;
2945
2946 if(ModeNo <= 0x13) {
2947 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2948 } else {
2949 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2950 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2951 }
2952
2953 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2954
2955 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2956
2957 tempbx = SiS_Pr->SiS_LCDResInfo;
2958 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2959
2960 /* patch index */
2961 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2962 if (resinfo == SIS_RI_1280x800) tempal = 9;
2963 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2964 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2965 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2966 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2967 if (resinfo == SIS_RI_1280x768) tempal = 9;
2968 }
2969
2970 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2971 /* Pass 1:1 only (center-screen handled outside) */
2972 /* This is never called for the panel's native resolution */
2973 /* since Pass1:1 will not be set in this case */
2974 tempbx = 100;
2975 if(ModeNo >= 0x13) {
2976 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2977 }
2978 }
2979
2980 #ifdef SIS315H
2981 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2982 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2983 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2984 tempbx = 200;
2985 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2986 }
2987 }
2988 }
2989 #endif
2990
2991 } else { /* TV */
2992
2993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2994 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2995 tempbx = 2;
2996 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2997 tempbx = 13;
2998 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2999 }
3000 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3001 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3002 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3003 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i) tempbx = 15;
3004 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p) tempbx = 16;
3005 else tempbx = 5;
3006 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3007 } else {
3008 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3009 else tempbx = 4;
3010 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3011 }
3012
3013 }
3014
3015 tempal &= 0x3F;
3016
3017 if(ModeNo > 0x13) {
3018 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3019 switch(resinfo) {
3020 case SIS_RI_720x480:
3021 tempal = 9;
3022 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 6;
3023 break;
3024 case SIS_RI_720x576:
3025 case SIS_RI_768x576:
3026 case SIS_RI_1024x576:
3027 tempal = 6;
3028 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3029 tempal = 8;
3030 if(resinfo == SIS_RI_1024x576) tempal = 10;
3031 }
3032 break;
3033 case SIS_RI_800x480:
3034 tempal = 4;
3035 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3036 break;
3037 case SIS_RI_512x384:
3038 case SIS_RI_1024x768:
3039 tempal = 7;
3040 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr625p)) {
3041 tempal = 8;
3042 }
3043 break;
3044 case SIS_RI_1280x720:
3045 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 11;
3046 break;
3047 }
3048 }
3049 }
3050
3051 *CRT2Index = tempbx;
3052 *ResIndex = tempal;
3053
3054 } else { /* LVDS, 301B-DH (if running on LCD) */
3055
3056 tempbx = 0;
3057 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3058
3059 tempbx = 90;
3060 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3061 tempbx = 92;
3062 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3063 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3064 }
3065 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3066 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3067 }
3068 if(tempbx != 99) {
3069 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3070 }
3071
3072 } else {
3073
3074 switch(SiS_Pr->SiS_LCDResInfo) {
3075 case Panel_640x480: tempbx = 12; break;
3076 case Panel_320x240_1: tempbx = 10; break;
3077 case Panel_320x240_2:
3078 case Panel_320x240_3: tempbx = 14; break;
3079 case Panel_800x600: tempbx = 16; break;
3080 case Panel_1024x600: tempbx = 18; break;
3081 case Panel_1152x768:
3082 case Panel_1024x768: tempbx = 20; break;
3083 case Panel_1280x768: tempbx = 22; break;
3084 case Panel_1280x1024: tempbx = 24; break;
3085 case Panel_1400x1050: tempbx = 26; break;
3086 case Panel_1600x1200: tempbx = 28; break;
3087 #ifdef SIS300
3088 case Panel_Barco1366: tempbx = 80; break;
3089 #endif
3090 }
3091
3092 switch(SiS_Pr->SiS_LCDResInfo) {
3093 case Panel_320x240_1:
3094 case Panel_320x240_2:
3095 case Panel_320x240_3:
3096 case Panel_640x480:
3097 break;
3098 default:
3099 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3100 }
3101
3102 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3103
3104 #ifdef SIS300
3105 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3106 tempbx = 82;
3107 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3108 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3109 tempbx = 84;
3110 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3111 }
3112 #endif
3113
3114 }
3115
3116 (*CRT2Index) = tempbx;
3117 (*ResIndex) = tempal & 0x1F;
3118 }
3119 }
3120
3121 static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3122 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3123 unsigned short RefreshRateTableIndex)
3124 {
3125 unsigned short tempax=0, tempbx=0, index, dotclock;
3126 unsigned short temp1=0, modeflag=0, tempcx=0;
3127
3128 SiS_Pr->SiS_RVBHCMAX = 1;
3129 SiS_Pr->SiS_RVBHCFACT = 1;
3130
3131 if(ModeNo <= 0x13) {
3132
3133 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3134 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3135
3136 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3137 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3138 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3139
3140 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3141
3142 } else {
3143
3144 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3145 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3146
3147 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3148 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3149 tempax &= 0x03FF;
3150 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3151 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3152 tempcx &= 0x0100;
3153 tempcx <<= 2;
3154 tempbx |= tempcx;
3155 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3156
3157 dotclock = 8;
3158
3159 }
3160
3161 if(temp1 & 0x01) tempbx |= 0x0100;
3162 if(temp1 & 0x20) tempbx |= 0x0200;
3163
3164 tempax += 5;
3165 tempax *= dotclock;
3166 if(modeflag & HalfDCLK) tempax <<= 1;
3167
3168 tempbx++;
3169
3170 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3171 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3172 }
3173
3174 static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3175 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3176 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3177 {
3178 unsigned short ResIndex;
3179
3180 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3181 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3182 if(SiS_Pr->UseCustomMode) {
3183 ResIndex = SiS_Pr->CHTotal;
3184 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3185 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3186 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3187 } else {
3188 if(ModeNo < 0x13) {
3189 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3190 } else {
3191 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3192 }
3193 if(ResIndex == 0x09) {
3194 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3195 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3196 }
3197 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3198 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3199 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3200 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3201 }
3202 } else {
3203 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3204 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3205 }
3206 } else {
3207 /* This handles custom modes and custom panels */
3208 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3209 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3210 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3211 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3212 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3213 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3214 }
3215 }
3216
3217 static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3218 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3219 unsigned short RefreshRateTableIndex)
3220 {
3221 unsigned short CRT2Index, ResIndex, backup;
3222 const struct SiS_LVDSData *LVDSData = NULL;
3223
3224 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3225
3226 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3227 SiS_Pr->SiS_RVBHCMAX = 1;
3228 SiS_Pr->SiS_RVBHCFACT = 1;
3229 SiS_Pr->SiS_NewFlickerMode = 0;
3230 SiS_Pr->SiS_RVBHRS = 50;
3231 SiS_Pr->SiS_RY1COE = 0;
3232 SiS_Pr->SiS_RY2COE = 0;
3233 SiS_Pr->SiS_RY3COE = 0;
3234 SiS_Pr->SiS_RY4COE = 0;
3235 SiS_Pr->SiS_RVBHRS2 = 0;
3236 }
3237
3238 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3239
3240 #ifdef SIS315H
3241 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3242 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3243 #endif
3244
3245 } else {
3246
3247 /* 301BDH needs LVDS Data */
3248 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3249 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3250 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3251 }
3252
3253 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3254 &CRT2Index, &ResIndex);
3255
3256 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3257
3258 switch(CRT2Index) {
3259 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3260 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3261 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3262 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3263 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3264 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3265 #ifdef SIS300
3266 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3267 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3268 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3269 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3270 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3271 #endif
3272 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3273 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3274 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3275 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3276 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3277 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3278 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3279 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3280 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3281 }
3282
3283 if(LVDSData) {
3284 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3285 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3286 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3287 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3288 } else {
3289 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3290 }
3291
3292 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3293 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3294 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3295 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3296 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3297 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3298 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3299 #ifdef SIS300
3300 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3301 if(ResIndex < 0x08) {
3302 SiS_Pr->SiS_HDE = 1280;
3303 SiS_Pr->SiS_VDE = 1024;
3304 }
3305 }
3306 #endif
3307 }
3308 }
3309 }
3310 }
3311
3312 static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3313 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3314 unsigned short RefreshRateTableIndex)
3315 {
3316 unsigned char *ROMAddr = NULL;
3317 unsigned short tempax, tempbx, modeflag, romptr=0;
3318 unsigned short resinfo, CRT2Index, ResIndex;
3319 const struct SiS_LCDData *LCDPtr = NULL;
3320 const struct SiS_TVData *TVPtr = NULL;
3321 #ifdef SIS315H
3322 short resinfo661;
3323 #endif
3324
3325 if(ModeNo <= 0x13) {
3326 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3327 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3328 } else if(SiS_Pr->UseCustomMode) {
3329 modeflag = SiS_Pr->CModeFlag;
3330 resinfo = 0;
3331 } else {
3332 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3333 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3334 #ifdef SIS315H
3335 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3336 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3337 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3338 (resinfo661 >= 0) &&
3339 (SiS_Pr->SiS_NeedRomModeData) ) {
3340 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3341 if((romptr = (SISGETROMW(21)))) {
3342 romptr += (resinfo661 * 10);
3343 ROMAddr = SiS_Pr->VirtualRomBase;
3344 }
3345 }
3346 }
3347 #endif
3348 }
3349
3350 SiS_Pr->SiS_NewFlickerMode = 0;
3351 SiS_Pr->SiS_RVBHRS = 50;
3352 SiS_Pr->SiS_RY1COE = 0;
3353 SiS_Pr->SiS_RY2COE = 0;
3354 SiS_Pr->SiS_RY3COE = 0;
3355 SiS_Pr->SiS_RY4COE = 0;
3356 SiS_Pr->SiS_RVBHRS2 = 0;
3357
3358 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3359
3360 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3361
3362 if(SiS_Pr->UseCustomMode) {
3363
3364 SiS_Pr->SiS_RVBHCMAX = 1;
3365 SiS_Pr->SiS_RVBHCFACT = 1;
3366 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3367 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3368
3369 tempax = SiS_Pr->CHTotal;
3370 if(modeflag & HalfDCLK) tempax <<= 1;
3371 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3372 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3373
3374 } else {
3375
3376 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3377
3378 }
3379
3380 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3381
3382 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3383 &CRT2Index,&ResIndex);
3384
3385 switch(CRT2Index) {
3386 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3387 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3388 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3389 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3390 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3391 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3392 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3393 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3394 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3395 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3396 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3397 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3398 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3399 case 15: TVPtr = SiS_Pr->SiS_Ext625iData; break;
3400 case 16: TVPtr = SiS_Pr->SiS_Ext625pData; break;
3401 case 20: TVPtr = SiS_Pr->SiS_St625iData; break;
3402 case 21: TVPtr = SiS_Pr->SiS_St625pData; break;
3403 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3404 }
3405
3406 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3407 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3408 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3409 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3410 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3411 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3412 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3413 if(modeflag & HalfDCLK) {
3414 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3415 if(SiS_Pr->SiS_RVBHRS2) {
3416 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3417 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3418 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3419 else SiS_Pr->SiS_RVBHRS2 += tempax;
3420 }
3421 } else {
3422 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3423 }
3424 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3425
3426 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3427
3428 if((resinfo == SIS_RI_960x540) ||
3429 (resinfo == SIS_RI_960x600) ||
3430 (resinfo == SIS_RI_1024x768) ||
3431 (resinfo == SIS_RI_1280x1024) ||
3432 (resinfo == SIS_RI_1280x720)) {
3433 SiS_Pr->SiS_NewFlickerMode = 0x40;
3434 }
3435
3436 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3437
3438 SiS_Pr->SiS_HT = ExtHiTVHT;
3439 SiS_Pr->SiS_VT = ExtHiTVVT;
3440 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3441 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3442 SiS_Pr->SiS_HT = StHiTVHT;
3443 SiS_Pr->SiS_VT = StHiTVVT;
3444 }
3445 }
3446
3447 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3448
3449 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3450 SiS_Pr->SiS_HT = 1650;
3451 SiS_Pr->SiS_VT = 750;
3452 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3453 SiS_Pr->SiS_HT = NTSCHT;
3454 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3455 SiS_Pr->SiS_VT = NTSCVT;
3456 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) {
3457 SiS_Pr->SiS_HT = NTSCHT;
3458 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3459 SiS_Pr->SiS_VT = NTSCVT;
3460 } else {
3461 SiS_Pr->SiS_HT = PALHT;
3462 SiS_Pr->SiS_VT = PALVT;
3463 }
3464
3465 } else {
3466
3467 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3468 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3469 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3470 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3471
3472 if(modeflag & HalfDCLK) {
3473 SiS_Pr->SiS_RY1COE = 0x00;
3474 SiS_Pr->SiS_RY2COE = 0xf4;
3475 SiS_Pr->SiS_RY3COE = 0x10;
3476 SiS_Pr->SiS_RY4COE = 0x38;
3477 }
3478
3479 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3480 SiS_Pr->SiS_HT = NTSCHT;
3481 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3482 SiS_Pr->SiS_VT = NTSCVT;
3483 } else {
3484 SiS_Pr->SiS_HT = PALHT;
3485 SiS_Pr->SiS_VT = PALVT;
3486 }
3487
3488 }
3489
3490 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3491
3492 SiS_Pr->SiS_RVBHCMAX = 1;
3493 SiS_Pr->SiS_RVBHCFACT = 1;
3494
3495 if(SiS_Pr->UseCustomMode) {
3496
3497 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3498 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3499
3500 tempax = SiS_Pr->CHTotal;
3501 if(modeflag & HalfDCLK) tempax <<= 1;
3502 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3503 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3504
3505 } else {
3506
3507 BOOLEAN gotit = FALSE;
3508
3509 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3510
3511 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3512 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3513 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3514 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3515 gotit = TRUE;
3516
3517 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3518
3519 #ifdef SIS315H
3520 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3521 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3522 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3523 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3524 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3525 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3526 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3527 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3528 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3529 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3530 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3531 else SiS_Pr->SiS_RVBHRS2 += tempax;
3532 }
3533 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3534 else {
3535 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3536 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3537 SiS_Pr->SiS_RVBHCMAX = 1;
3538 SiS_Pr->SiS_RVBHCFACT = 1;
3539 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3540 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3541 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3542 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3543 SiS_Pr->SiS_RVBHRS2 = 0;
3544 gotit = TRUE;
3545 }
3546 #endif
3547
3548 }
3549
3550 if(!gotit) {
3551
3552 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3553 &CRT2Index,&ResIndex);
3554
3555 switch(CRT2Index) {
3556 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3557 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3558 case Panel_1280x720 :
3559 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3560 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3561 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3562 case Panel_1280x800 :
3563 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3564 case Panel_1280x800_2 :
3565 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3566 case Panel_1280x854 :
3567 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3568 case Panel_1280x960 :
3569 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3570 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3571 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3572 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3573 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3574 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3575 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3576 case Panel_1680x1050 :
3577 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3578 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3579 #ifdef SIS315H
3580 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3581 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3582 #endif
3583 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3584 }
3585
3586 #ifdef SIS_XORG_XF86
3587 #ifdef TWDEBUG
3588 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3589 #endif
3590 #endif
3591
3592 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3593 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3594 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3595 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3596 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3597 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3598
3599 }
3600
3601 tempax = SiS_Pr->PanelXRes;
3602 tempbx = SiS_Pr->PanelYRes;
3603
3604 switch(SiS_Pr->SiS_LCDResInfo) {
3605 case Panel_1024x768:
3606 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3607 if(SiS_Pr->ChipType < SIS_315H) {
3608 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3609 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3610 }
3611 } else {
3612 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3613 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3614 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3615 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3616 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3617 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3618 }
3619 break;
3620 case Panel_1280x960:
3621 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3622 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3623 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3624 break;
3625 case Panel_1280x1024:
3626 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3627 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3628 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3629 break;
3630 case Panel_1600x1200:
3631 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3632 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3633 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3634 }
3635 break;
3636 }
3637
3638 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3639 tempax = SiS_Pr->SiS_VGAHDE;
3640 tempbx = SiS_Pr->SiS_VGAVDE;
3641 }
3642
3643 SiS_Pr->SiS_HDE = tempax;
3644 SiS_Pr->SiS_VDE = tempbx;
3645 }
3646 }
3647 }
3648
3649 static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3650 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3651 unsigned short RefreshRateTableIndex)
3652 {
3653
3654 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3655
3656 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3657 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3658 } else {
3659 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3660 /* Need LVDS Data for LCD on 301B-DH */
3661 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3662 } else {
3663 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3664 }
3665 }
3666
3667 } else {
3668
3669 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3670
3671 }
3672 }
3673
3674 /*********************************************/
3675 /* GET LVDS DES (SKEW) DATA */
3676 /*********************************************/
3677
3678 static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3679 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3680 {
3681 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3682
3683 #ifdef SIS300
3684 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3685
3686 if(SiS_Pr->ChipType < SIS_315H) {
3687 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3688 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3689 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3690 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3691 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3692 }
3693 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3694 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3695 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3696 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3697 }
3698 }
3699 }
3700 }
3701 }
3702 #endif
3703 return PanelDesPtr;
3704 }
3705
3706 static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3707 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3708 unsigned short RefreshRateTableIndex)
3709 {
3710 unsigned short modeflag, ResIndex;
3711 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3712
3713 SiS_Pr->SiS_LCDHDES = 0;
3714 SiS_Pr->SiS_LCDVDES = 0;
3715
3716 /* Some special cases */
3717 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3718
3719 /* Trumpion */
3720 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3721 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3722 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3723 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3724 }
3725 }
3726 return;
3727 }
3728
3729 /* 640x480 on LVDS */
3730 if(SiS_Pr->ChipType < SIS_315H) {
3731 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3732 SiS_Pr->SiS_LCDHDES = 8;
3733 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3734 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3735 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3736 return;
3737 }
3738 }
3739
3740 } /* LCD */
3741
3742 if( (SiS_Pr->UseCustomMode) ||
3743 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3744 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3745 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3746 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3747 return;
3748 }
3749
3750 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3751 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3752
3753 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3754
3755 #ifdef SIS315H
3756 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3757 /* non-pass 1:1 only, see above */
3758 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3759 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3760 }
3761 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3762 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3763 }
3764 }
3765 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3766 switch(SiS_Pr->SiS_CustomT) {
3767 case CUT_UNIWILL1024:
3768 case CUT_UNIWILL10242:
3769 case CUT_CLEVO1400:
3770 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3771 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3772 }
3773 break;
3774 }
3775 switch(SiS_Pr->SiS_LCDResInfo) {
3776 case Panel_1280x1024:
3777 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3778 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3779 }
3780 break;
3781 case Panel_1280x800: /* Verified for Averatec 6240 */
3782 case Panel_1280x800_2: /* Verified for Asus A4L */
3783 case Panel_1280x854: /* Not verified yet FIXME */
3784 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3785 break;
3786 }
3787 }
3788 #endif
3789
3790 } else {
3791
3792 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3793
3794 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3795 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3796 }
3797
3798 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3799
3800 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3801 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3802
3803 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3804
3805 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3806 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3807 }
3808 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3809 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3810 } else {
3811 if(SiS_Pr->ChipType < SIS_315H) {
3812 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3813 } else {
3814 switch(SiS_Pr->SiS_LCDResInfo) {
3815 case Panel_800x600:
3816 case Panel_1024x768:
3817 case Panel_1280x1024:
3818 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3819 break;
3820 case Panel_1400x1050:
3821 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3822 break;
3823 }
3824 }
3825 }
3826
3827 } else {
3828
3829 if(SiS_Pr->ChipType < SIS_315H) {
3830 #ifdef SIS300
3831 switch(SiS_Pr->SiS_LCDResInfo) {
3832 case Panel_800x600:
3833 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3834 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3835 } else {
3836 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3837 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3838 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3839 else SiS_Pr->SiS_LCDVDES -= 4;
3840 }
3841 break;
3842 case Panel_1024x768:
3843 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3844 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3845 } else {
3846 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3847 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3848 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3849 }
3850 break;
3851 case Panel_1024x600:
3852 default:
3853 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3854 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3855 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3856 } else {
3857 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3858 }
3859 break;
3860 }
3861
3862 switch(SiS_Pr->SiS_LCDTypeInfo) {
3863 case 1:
3864 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3865 break;
3866 case 3: /* 640x480 only? */
3867 SiS_Pr->SiS_LCDHDES = 8;
3868 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3869 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3870 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3871 break;
3872 }
3873 #endif
3874 } else {
3875 #ifdef SIS315H
3876 switch(SiS_Pr->SiS_LCDResInfo) {
3877 case Panel_1024x768:
3878 case Panel_1280x1024:
3879 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3880 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3881 }
3882 break;
3883 case Panel_320x240_1:
3884 case Panel_320x240_2:
3885 case Panel_320x240_3:
3886 SiS_Pr->SiS_LCDVDES = 524;
3887 break;
3888 }
3889 #endif
3890 }
3891 }
3892
3893 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3894 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3895 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3896 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3897 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3898 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3899 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3900 if(SiS_Pr->ChipType < SIS_315H) {
3901 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3902 } else {
3903 #ifdef SIS315H
3904 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3905 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3906 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3907 if(!(modeflag & HalfDCLK)) {
3908 SiS_Pr->SiS_LCDHDES = 320;
3909 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3910 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3911 }
3912 #endif
3913 }
3914 }
3915 }
3916 }
3917 }
3918 }
3919 }
3920
3921 /*********************************************/
3922 /* DISABLE VIDEO BRIDGE */
3923 /*********************************************/
3924
3925 #ifdef SIS315H
3926 static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)3927 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3928 {
3929 int ret = 0;
3930 #ifdef SET_PWD
3931 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3932 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3933 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3934 unsigned short temp;
3935
3936 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3937 (romptr) &&
3938 (SiS_Pr->SiS_PWDOffset) ) {
3939 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3940 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3941 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3942 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3943 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3944 temp = 0x00;
3945 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3946 temp = 0x80;
3947 ret = 1;
3948 }
3949 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3950 #ifdef SIS_XORG_XF86
3951 #ifdef TWDEBUG
3952 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3953 #endif
3954 #endif
3955 }
3956 #endif
3957 return ret;
3958 }
3959 #endif
3960
3961 /* NEVER use any variables (VBInfo), this will be called
3962 * from outside the context of modeswitch!
3963 * MUST call getVBType before calling this
3964 */
3965 void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)3966 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3967 {
3968 #ifdef SIS315H
3969 unsigned short tempah, pushax=0, modenum;
3970 #endif
3971 unsigned short temp=0;
3972
3973 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3974
3975 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3976
3977 if(SiS_Pr->ChipType < SIS_315H) {
3978
3979 #ifdef SIS300 /* 300 series */
3980
3981 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3982 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3983 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3984 } else {
3985 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3986 }
3987 SiS_PanelDelay(SiS_Pr, 3);
3988 }
3989 if(SiS_Is301B(SiS_Pr)) {
3990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3991 SiS_ShortDelay(SiS_Pr,1);
3992 }
3993 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3994 SiS_DisplayOff(SiS_Pr);
3995 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3996 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3997 SiS_UnLockCRT2(SiS_Pr);
3998 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3999 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4000 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4001 }
4002 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4003 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4004 SiS_PanelDelay(SiS_Pr, 2);
4005 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4006 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4007 } else {
4008 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4009 }
4010 }
4011
4012 #endif /* SIS300 */
4013
4014 } else {
4015
4016 #ifdef SIS315H /* 315 series */
4017
4018 int didpwd = 0;
4019 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4020 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
4021
4022 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4023
4024 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4025
4026 #ifdef SET_EMI
4027 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4028 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4029 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4030 }
4031 }
4032 #endif
4033
4034 didpwd = SiS_HandlePWD(SiS_Pr);
4035
4036 if( (modenum <= 0x13) ||
4037 (SiS_IsVAMode(SiS_Pr)) ||
4038 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4039 if(!didpwd) {
4040 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4041 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4042 } else {
4043 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4044 }
4045 }
4046
4047 if(!custom1) {
4048 SiS_DDC2Delay(SiS_Pr,0xff00);
4049 SiS_DDC2Delay(SiS_Pr,0xe000);
4050 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4051 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4052 if(IS_SIS740) {
4053 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4054 }
4055 SiS_PanelDelay(SiS_Pr, 3);
4056 }
4057
4058 }
4059
4060 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4061 /* if(SiS_Pr->ChipType < SIS_340) {*/
4062 tempah = 0xef;
4063 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4064 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4065 /*}*/
4066 }
4067
4068 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4069 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4070 }
4071
4072 tempah = 0x3f;
4073 if(SiS_IsDualEdge(SiS_Pr)) {
4074 tempah = 0x7f;
4075 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4076 }
4077 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4078
4079 if((SiS_IsVAMode(SiS_Pr)) ||
4080 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4081
4082 SiS_DisplayOff(SiS_Pr);
4083 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4084 SiS_PanelDelay(SiS_Pr, 2);
4085 }
4086 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4087 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4088
4089 }
4090
4091 if((!(SiS_IsVAMode(SiS_Pr))) ||
4092 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4093
4094 if(!(SiS_IsDualEdge(SiS_Pr))) {
4095 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4096 SiS_DisplayOff(SiS_Pr);
4097 }
4098 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4099
4100 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4101 SiS_PanelDelay(SiS_Pr, 2);
4102 }
4103
4104 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4105 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4107 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4108 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4109
4110 }
4111
4112 if(SiS_IsNotM650orLater(SiS_Pr)) {
4113 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4114 }
4115
4116 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4117
4118 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4119 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4120 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4121
4122 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4123 if(!didpwd) {
4124 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4125 }
4126 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4127 }
4128
4129 if(!custom1) {
4130 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4131 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4132 if(SiS_IsVAorLCD(SiS_Pr)) {
4133 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4134 }
4135 }
4136 }
4137
4138 }
4139
4140 #endif /* SIS315H */
4141
4142 }
4143
4144 } else { /* ============ For 301 ================ */
4145
4146 if(SiS_Pr->ChipType < SIS_315H) {
4147 #ifdef SIS300
4148 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4149 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4150 SiS_PanelDelay(SiS_Pr, 3);
4151 }
4152 #endif
4153 }
4154
4155 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4156 SiS_DisplayOff(SiS_Pr);
4157
4158 if(SiS_Pr->ChipType >= SIS_315H) {
4159 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4160 }
4161
4162 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4163
4164 if(SiS_Pr->ChipType >= SIS_315H) {
4165 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4166 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4167 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4168 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4169 } else {
4170 #ifdef SIS300
4171 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4172 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4173 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4174 SiS_PanelDelay(SiS_Pr, 2);
4175 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4176 }
4177 #endif
4178 }
4179
4180 }
4181
4182 } else { /* ============ For LVDS =============*/
4183
4184 if(SiS_Pr->ChipType < SIS_315H) {
4185
4186 #ifdef SIS300 /* 300 series */
4187
4188 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4189 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4190 }
4191
4192 if(SiS_Pr->ChipType == SIS_730) {
4193 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4194 SiS_WaitVBRetrace(SiS_Pr);
4195 }
4196 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4197 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4198 SiS_PanelDelay(SiS_Pr, 3);
4199 }
4200 } else {
4201 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4202 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4203 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4204 SiS_WaitVBRetrace(SiS_Pr);
4205 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4206 SiS_DisplayOff(SiS_Pr);
4207 }
4208 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4209 SiS_PanelDelay(SiS_Pr, 3);
4210 }
4211 }
4212 }
4213 }
4214
4215 SiS_DisplayOff(SiS_Pr);
4216
4217 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4218
4219 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4220 SiS_UnLockCRT2(SiS_Pr);
4221 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4222 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4223
4224 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4225 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4226 SiS_PanelDelay(SiS_Pr, 2);
4227 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4228 }
4229
4230 #endif /* SIS300 */
4231
4232 } else {
4233
4234 #ifdef SIS315H /* 315 series */
4235
4236 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4237 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4238 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4239 /* } */
4240 }
4241
4242 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4243
4244 if(SiS_Pr->ChipType == SIS_740) {
4245 temp = SiS_GetCH701x(SiS_Pr,0x61);
4246 if(temp < 1) {
4247 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4248 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4249 }
4250
4251 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4252 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4253 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4254 }
4255 }
4256
4257 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4258 (SiS_IsVAMode(SiS_Pr)) ) {
4259 SiS_Chrontel701xBLOff(SiS_Pr);
4260 SiS_Chrontel701xOff(SiS_Pr);
4261 }
4262
4263 if(SiS_Pr->ChipType != SIS_740) {
4264 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4265 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4266 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4267 }
4268 }
4269
4270 }
4271
4272 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4273 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4274 SiS_PanelDelay(SiS_Pr, 3);
4275 }
4276
4277 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4278 (!(SiS_IsDualEdge(SiS_Pr))) ||
4279 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4280 SiS_DisplayOff(SiS_Pr);
4281 }
4282
4283 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4284 (!(SiS_IsDualEdge(SiS_Pr))) ||
4285 (!(SiS_IsVAMode(SiS_Pr))) ) {
4286 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4287 }
4288
4289 if(SiS_Pr->ChipType == SIS_740) {
4290 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4291 }
4292
4293 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4294
4295 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4296 (!(SiS_IsDualEdge(SiS_Pr))) ||
4297 (!(SiS_IsVAMode(SiS_Pr))) ) {
4298 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4299 }
4300
4301 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4302 if(SiS_CRT2IsLCD(SiS_Pr)) {
4303 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4304 if(SiS_Pr->ChipType == SIS_550) {
4305 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4306 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4307 }
4308 }
4309 } else {
4310 if(SiS_Pr->ChipType == SIS_740) {
4311 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4312 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4313 }
4314 } else if(SiS_IsVAMode(SiS_Pr)) {
4315 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4316 }
4317 }
4318
4319 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4320 if(SiS_IsDualEdge(SiS_Pr)) {
4321 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4322 } else {
4323 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4324 }
4325 }
4326
4327 SiS_UnLockCRT2(SiS_Pr);
4328
4329 if(SiS_Pr->ChipType == SIS_550) {
4330 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4331 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4332 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4333 (!(SiS_IsDualEdge(SiS_Pr))) ||
4334 (!(SiS_IsVAMode(SiS_Pr))) ) {
4335 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4336 }
4337
4338 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4339 if(SiS_CRT2IsLCD(SiS_Pr)) {
4340 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4341 SiS_PanelDelay(SiS_Pr, 2);
4342 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4343 }
4344 }
4345 }
4346
4347 #endif /* SIS315H */
4348
4349 } /* 315 series */
4350
4351 } /* LVDS */
4352
4353 }
4354
4355 /*********************************************/
4356 /* ENABLE VIDEO BRIDGE */
4357 /*********************************************/
4358
4359 /* NEVER use any variables (VBInfo), this will be called
4360 * from outside the context of a mode switch!
4361 * MUST call getVBType before calling this
4362 */
4363 #ifdef SIS_LINUX_KERNEL
4364 static
4365 #endif
4366 void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4367 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4368 {
4369 unsigned short temp=0, tempah;
4370 #ifdef SIS315H
4371 unsigned short temp1, pushax=0;
4372 BOOLEAN delaylong = FALSE;
4373 #endif
4374
4375 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4376
4377 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4378
4379 if(SiS_Pr->ChipType < SIS_315H) {
4380
4381 #ifdef SIS300 /* 300 series */
4382
4383 if(SiS_CRT2IsLCD(SiS_Pr)) {
4384 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4385 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4386 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4387 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4388 }
4389 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4390 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4391 SiS_PanelDelay(SiS_Pr, 0);
4392 }
4393 }
4394 }
4395
4396 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4397 (SiS_CRT2IsLCD(SiS_Pr))) {
4398
4399 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4400 SiS_DisplayOn(SiS_Pr);
4401 SiS_UnLockCRT2(SiS_Pr);
4402 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4403 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4404 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4405 } else {
4406 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4407 }
4408 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4409 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4410 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4411 SiS_PanelDelay(SiS_Pr, 1);
4412 }
4413 SiS_WaitVBRetrace(SiS_Pr);
4414 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4415 }
4416 }
4417
4418 } else {
4419
4420 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4421 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4422 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4423 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4424 }
4425 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4426 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4427 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4428 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4429 SiS_DisplayOn(SiS_Pr);
4430 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4431 if(SiS_CRT2IsLCD(SiS_Pr)) {
4432 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4433 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4434 SiS_PanelDelay(SiS_Pr, 1);
4435 }
4436 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4437 }
4438 }
4439 }
4440
4441 }
4442
4443
4444 #endif /* SIS300 */
4445
4446 } else {
4447
4448 #ifdef SIS315H /* 315 series */
4449
4450 #ifdef SET_EMI
4451 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4452 int didpwd = 0;
4453 /* unsigned short emidelay=0; */
4454 #endif
4455
4456 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4457 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4458 #ifdef SET_EMI
4459 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4460 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4461 }
4462 #endif
4463 }
4464
4465 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4466 /*if(SiS_Pr->ChipType < SIS_340) { */
4467 tempah = 0x10;
4468 if(SiS_LCDAEnabled(SiS_Pr)) {
4469 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4470 else tempah = 0x08;
4471 }
4472 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4473 /*}*/
4474 }
4475
4476 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4477
4478 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4479 SiS_DisplayOff(SiS_Pr);
4480 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4481 if(IS_SIS740) {
4482 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4483 }
4484
4485 didpwd = SiS_HandlePWD(SiS_Pr);
4486
4487 if(SiS_IsVAorLCD(SiS_Pr)) {
4488 if(!didpwd) {
4489 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4490 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4491 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4492 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4493 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4494 SiS_GenericDelay(SiS_Pr, 17664);
4495 }
4496 }
4497 } else {
4498 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4499 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4500 SiS_GenericDelay(SiS_Pr, 17664);
4501 }
4502 }
4503 }
4504
4505 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4506 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4507 delaylong = TRUE;
4508 }
4509
4510 }
4511
4512 if(!(SiS_IsVAMode(SiS_Pr))) {
4513
4514 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4515 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4516 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4517 if(!(tempah & SetCRT2ToRAMDAC)) {
4518 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4519 }
4520 }
4521 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4522
4523 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4524
4525 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4526 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4527
4528 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4529 SiS_PanelDelay(SiS_Pr, 2);
4530 }
4531
4532 } else {
4533
4534 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4535
4536 }
4537
4538 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4539 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4540
4541 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4542 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4543 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4544 /* Enable "LVDS PLL power on" (even on 301C) */
4545 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4546 /* Enable "LVDS Driver Power on" (even on 301C) */
4547 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4548 }
4549 }
4550
4551 tempah = 0xc0;
4552 if(SiS_IsDualEdge(SiS_Pr)) {
4553 tempah = 0x80;
4554 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4555 }
4556 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4557
4558 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4559
4560 SiS_PanelDelay(SiS_Pr, 2);
4561
4562 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4563 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4564
4565 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4566 #ifdef SET_EMI
4567 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4568 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4569 SiS_GenericDelay(SiS_Pr, 2048);
4570 }
4571 #endif
4572 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4573
4574 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4575 #ifdef SET_EMI
4576 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4577
4578 if(SiS_Pr->SiS_ROMNew) {
4579 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4580 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4581 if(romptr) {
4582 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4583 SiS_Pr->EMI_30 = 0;
4584 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4585 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4586 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4587 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4588 /* emidelay = SISGETROMW((romptr + 0x22)); */
4589 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4590 }
4591 }
4592
4593 /* (P4_30|0x40) */
4594 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4595 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4596 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4597 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4598 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4599 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4600 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4601 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4602 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4603
4604 if(SiS_Pr->HaveEMI) {
4605 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4606 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4607 } else {
4608 r30 = 0;
4609 }
4610
4611 /* EMI_30 is read at driver start; however, the BIOS sets this
4612 * (if it is used) only if the LCD is in use. In case we caught
4613 * the machine while on TV output, this bit is not set and we
4614 * don't know if it should be set - hence our detection is wrong.
4615 * Work-around this here:
4616 */
4617
4618 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4619 switch((cr36 & 0x0f)) {
4620 case 2:
4621 r30 |= 0x40;
4622 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4623 if(!SiS_Pr->HaveEMI) {
4624 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4625 if((cr36 & 0xf0) == 0x30) {
4626 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4627 }
4628 }
4629 break;
4630 case 3: /* 1280x1024 */
4631 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4632 if(!SiS_Pr->HaveEMI) {
4633 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4634 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4635 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4636 }
4637 }
4638 break;
4639 case 9: /* 1400x1050 */
4640 r30 |= 0x40;
4641 if(!SiS_Pr->HaveEMI) {
4642 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4643 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4644 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4645 }
4646 }
4647 break;
4648 case 11: /* 1600x1200 - unknown */
4649 r30 |= 0x40;
4650 if(!SiS_Pr->HaveEMI) {
4651 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4652 }
4653 }
4654 }
4655
4656 /* BIOS values don't work so well sometimes */
4657 if(!SiS_Pr->OverruleEMI) {
4658 #ifdef COMPAL_HACK
4659 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4660 if((cr36 & 0x0f) == 0x09) {
4661 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4662 }
4663 }
4664 #endif
4665 #ifdef COMPAQ_HACK
4666 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4667 if((cr36 & 0x0f) == 0x03) {
4668 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4669 }
4670 }
4671 #endif
4672 #ifdef ASUS_HACK
4673 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4674 if((cr36 & 0x0f) == 0x02) {
4675 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4676 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4677 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4678 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4679 }
4680 }
4681 #endif
4682 }
4683
4684 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4685 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4686 SiS_GenericDelay(SiS_Pr, 2048);
4687 }
4688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4691 #endif /* SET_EMI */
4692
4693 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4694
4695 #ifdef SET_EMI
4696 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4697 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4698 if(r30 & 0x40) {
4699 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4700 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4701 if(delaylong) {
4702 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4703 delaylong = FALSE;
4704 }
4705 SiS_WaitVBRetrace(SiS_Pr);
4706 SiS_WaitVBRetrace(SiS_Pr);
4707 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4708 SiS_GenericDelay(SiS_Pr, 1280);
4709 }
4710 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4711 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4712 }
4713 }
4714 #endif
4715 }
4716 }
4717
4718 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4719 if(SiS_IsVAorLCD(SiS_Pr)) {
4720 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4721 if(delaylong) {
4722 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4723 }
4724 SiS_WaitVBRetrace(SiS_Pr);
4725 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4726 SiS_GenericDelay(SiS_Pr, 2048);
4727 SiS_WaitVBRetrace(SiS_Pr);
4728 }
4729 if(!didpwd) {
4730 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4731 } else {
4732 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4733 }
4734 }
4735 }
4736
4737 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4738 SiS_DisplayOn(SiS_Pr);
4739 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4740
4741 }
4742
4743 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4744 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4745 }
4746
4747 #endif /* SIS315H */
4748
4749 }
4750
4751 } else { /* ============ For 301 ================ */
4752
4753 if(SiS_Pr->ChipType < SIS_315H) {
4754 if(SiS_CRT2IsLCD(SiS_Pr)) {
4755 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4756 SiS_PanelDelay(SiS_Pr, 0);
4757 }
4758 }
4759
4760 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4761 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4762 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4763 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4764 }
4765 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4766
4767 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4768
4769 if(SiS_Pr->ChipType >= SIS_315H) {
4770 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4771 if(!(temp & 0x80)) {
4772 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4773 }
4774 }
4775
4776 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4777
4778 SiS_VBLongWait(SiS_Pr);
4779 SiS_DisplayOn(SiS_Pr);
4780 if(SiS_Pr->ChipType >= SIS_315H) {
4781 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4782 }
4783 SiS_VBLongWait(SiS_Pr);
4784
4785 if(SiS_Pr->ChipType < SIS_315H) {
4786 if(SiS_CRT2IsLCD(SiS_Pr)) {
4787 SiS_PanelDelay(SiS_Pr, 1);
4788 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4789 }
4790 }
4791
4792 }
4793
4794 } else { /* =================== For LVDS ================== */
4795
4796 if(SiS_Pr->ChipType < SIS_315H) {
4797
4798 #ifdef SIS300 /* 300 series */
4799
4800 if(SiS_CRT2IsLCD(SiS_Pr)) {
4801 if(SiS_Pr->ChipType == SIS_730) {
4802 SiS_PanelDelay(SiS_Pr, 1);
4803 SiS_PanelDelay(SiS_Pr, 1);
4804 SiS_PanelDelay(SiS_Pr, 1);
4805 }
4806 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4807 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4808 SiS_PanelDelay(SiS_Pr, 0);
4809 }
4810 }
4811
4812 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4813 SiS_DisplayOn(SiS_Pr);
4814 SiS_UnLockCRT2(SiS_Pr);
4815 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4816 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4817 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4818 } else {
4819 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4820 }
4821
4822 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4823 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4824 SiS_WaitVBRetrace(SiS_Pr);
4825 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4826 }
4827 }
4828
4829 if(SiS_CRT2IsLCD(SiS_Pr)) {
4830 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4831 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4832 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4833 SiS_PanelDelay(SiS_Pr, 1);
4834 SiS_PanelDelay(SiS_Pr, 1);
4835 }
4836 SiS_WaitVBRetrace(SiS_Pr);
4837 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4838 }
4839 }
4840 }
4841
4842 #endif /* SIS300 */
4843
4844 } else {
4845
4846 #ifdef SIS315H /* 315 series */
4847
4848 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4849 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4850 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4851 /*}*/
4852 }
4853
4854 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4855 if(SiS_CRT2IsLCD(SiS_Pr)) {
4856 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4857 SiS_PanelDelay(SiS_Pr, 0);
4858 }
4859 }
4860
4861 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4862 SiS_UnLockCRT2(SiS_Pr);
4863
4864 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4865
4866 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4867 temp = SiS_GetCH701x(SiS_Pr,0x66);
4868 temp &= 0x20;
4869 SiS_Chrontel701xBLOff(SiS_Pr);
4870 }
4871
4872 if(SiS_Pr->ChipType != SIS_550) {
4873 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4874 }
4875
4876 if(SiS_Pr->ChipType == SIS_740) {
4877 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4878 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4879 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4880 }
4881 }
4882 }
4883
4884 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4885 if(!(temp1 & 0x80)) {
4886 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4887 }
4888
4889 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4890 if(temp) {
4891 SiS_Chrontel701xBLOn(SiS_Pr);
4892 }
4893 }
4894
4895 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4896 if(SiS_CRT2IsLCD(SiS_Pr)) {
4897 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4898 if(SiS_Pr->ChipType == SIS_550) {
4899 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4900 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4901 }
4902 }
4903 } else if(SiS_IsVAMode(SiS_Pr)) {
4904 if(SiS_Pr->ChipType != SIS_740) {
4905 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4906 }
4907 }
4908
4909 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4910 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4911 }
4912
4913 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4914 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4915 SiS_Chrontel701xOn(SiS_Pr);
4916 }
4917 if( (SiS_IsVAMode(SiS_Pr)) ||
4918 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4919 SiS_ChrontelDoSomething1(SiS_Pr);
4920 }
4921 }
4922
4923 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4924 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4925 if( (SiS_IsVAMode(SiS_Pr)) ||
4926 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4927 SiS_Chrontel701xBLOn(SiS_Pr);
4928 SiS_ChrontelInitTVVSync(SiS_Pr);
4929 }
4930 }
4931 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4932 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4933 if(SiS_CRT2IsLCD(SiS_Pr)) {
4934 SiS_PanelDelay(SiS_Pr, 1);
4935 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4936 }
4937 }
4938 }
4939
4940 #endif /* SIS315H */
4941
4942 } /* 310 series */
4943
4944 } /* LVDS */
4945
4946 }
4947
4948 /*********************************************/
4949 /* SET PART 1 REGISTER GROUP */
4950 /*********************************************/
4951
4952 /* Set CRT2 OFFSET / PITCH */
4953 static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)4954 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4955 unsigned short RRTI)
4956 {
4957 unsigned short offset;
4958 unsigned char temp;
4959
4960 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4961
4962 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4963
4964 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4965 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4966
4967 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4968 if(offset & 0x07) temp++;
4969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4970 }
4971
4972 /* Set CRT2 sync and PanelLink mode */
4973 static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)4974 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4975 {
4976 unsigned short tempah=0, tempbl, infoflag;
4977
4978 tempbl = 0xC0;
4979
4980 if(SiS_Pr->UseCustomMode) {
4981 infoflag = SiS_Pr->CInfoFlag;
4982 } else {
4983 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4984 }
4985
4986 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4987
4988 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4989 tempah = 0;
4990 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4991 tempah = SiS_Pr->SiS_LCDInfo;
4992 } else tempah = infoflag >> 8;
4993 tempah &= 0xC0;
4994 tempah |= 0x20;
4995 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4996 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4997 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4998 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4999 tempah |= 0xf0;
5000 }
5001 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5002 (SiS_Pr->SiS_IF_DEF_DSTN) ||
5003 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5004 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5005 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5006 tempah |= 0x30;
5007 }
5008 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5009 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5010 tempah &= ~0xc0;
5011 }
5012 }
5013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5014 if(SiS_Pr->ChipType >= SIS_315H) {
5015 tempah >>= 3;
5016 tempah &= 0x18;
5017 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5018 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5019 } else {
5020 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5021 }
5022 } else {
5023 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5024 }
5025
5026 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5027
5028 if(SiS_Pr->ChipType < SIS_315H) {
5029
5030 #ifdef SIS300 /* ---- 300 series --- */
5031
5032 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
5033
5034 tempah = infoflag >> 8;
5035 tempbl = 0;
5036 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5037 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5038 tempah = SiS_Pr->SiS_LCDInfo;
5039 tempbl = (tempah >> 6) & 0x03;
5040 }
5041 }
5042 tempah &= 0xC0;
5043 tempah |= 0x20;
5044 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5045 tempah |= 0xc0;
5046 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5047 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5048 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5049 }
5050
5051 } else { /* 630 - 301 */
5052
5053 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5054 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5055 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5056
5057 }
5058
5059 #endif /* SIS300 */
5060
5061 } else {
5062
5063 #ifdef SIS315H /* ------- 315 series ------ */
5064
5065 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5066
5067 tempbl = 0;
5068 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5069 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5070 tempah = infoflag >> 8;
5071 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5072 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5073 }
5074 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5075 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5076 tempah = infoflag >> 8;
5077 tempbl = 0x03;
5078 } else {
5079 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5080 tempbl = (tempah >> 6) & 0x03;
5081 tempbl |= 0x08;
5082 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5083 }
5084 tempah &= 0xC0;
5085 tempah |= 0x20;
5086 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5087 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5088 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5089 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5090 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5091 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5092 }
5093 }
5094
5095 } else { /* 315 - TMDS */
5096
5097 tempah = tempbl = infoflag >> 8;
5098 if(!SiS_Pr->UseCustomMode) {
5099 tempbl = 0;
5100 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5101 if(ModeNo <= 0x13) {
5102 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5103 }
5104 }
5105 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5106 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5107 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5108 tempah = SiS_Pr->SiS_LCDInfo;
5109 tempbl = (tempah >> 6) & 0x03;
5110 }
5111 }
5112 }
5113 }
5114 tempah &= 0xC0;
5115 tempah |= 0x20;
5116 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5117 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5118 /* Imitate BIOS bug */
5119 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5120 }
5121 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5122 tempah >>= 3;
5123 tempah &= 0x18;
5124 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5125 } else {
5126 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5127 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5128 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5129 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5130 }
5131 }
5132 }
5133
5134 }
5135 #endif /* SIS315H */
5136 }
5137 }
5138 }
5139
5140 /* Set CRT2 FIFO on 300/540/630/730 */
5141 #ifdef SIS300
5142 static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5143 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5144 {
5145 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5146 unsigned short temp, index, modeidindex, refreshratetableindex;
5147 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5148 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5149 unsigned int data, pci50, pciA0;
5150 static const unsigned char colortharray[] = {
5151 1, 1, 2, 2, 3, 4
5152 };
5153
5154 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5155
5156 if(!SiS_Pr->CRT1UsesCustomMode) {
5157
5158 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5159 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5160 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5161 SiS_Pr->SiS_SelectCRT2Rate = 0;
5162 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5163
5164 if(CRT1ModeNo >= 0x13) {
5165 /* Get VCLK */
5166 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5167 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5168
5169 /* Get colordepth */
5170 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5171 if(!colorth) colorth++;
5172 }
5173
5174 } else {
5175
5176 CRT1ModeNo = 0xfe;
5177
5178 /* Get VCLK */
5179 VCLK = SiS_Pr->CSRClock_CRT1;
5180
5181 /* Get color depth */
5182 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5183
5184 }
5185
5186 if(CRT1ModeNo >= 0x13) {
5187 /* Get MCLK */
5188 if(SiS_Pr->ChipType == SIS_300) {
5189 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5190 } else {
5191 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5192 }
5193 index &= 0x07;
5194 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5195
5196 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5197 if(!temp) temp++;
5198 temp <<= 2;
5199
5200 data2 = temp - ((colorth * VCLK) / MCLK);
5201
5202 temp = (28 * 16) % data2;
5203 data2 = (28 * 16) / data2;
5204 if(temp) data2++;
5205
5206 if(SiS_Pr->ChipType == SIS_300) {
5207
5208 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5209 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5210
5211 } else {
5212
5213 #ifdef SIS_LINUX_KERNEL
5214 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5215 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5216 #else
5217 pci50 = sis_pci_read_host_bridge_u32(0x50);
5218 pciA0 = sis_pci_read_host_bridge_u32(0xA0);
5219 #endif
5220
5221 if(SiS_Pr->ChipType == SIS_730) {
5222
5223 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5224 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5225
5226 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5227 index = 0; /* -- do it like the BIOS anyway... */
5228
5229 } else {
5230
5231 pci50 >>= 24;
5232 pciA0 >>= 24;
5233
5234 index = (pci50 >> 1) & 0x07;
5235
5236 if(pci50 & 0x01) index += 6;
5237 if(!(pciA0 & 0x01)) index += 24;
5238
5239 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5240
5241 }
5242
5243 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5244 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5245
5246 }
5247
5248 data += data2; /* CRT1 Request Period */
5249
5250 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5251 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5252
5253 if(!SiS_Pr->UseCustomMode) {
5254
5255 CRT2ModeNo = ModeNo;
5256 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5257
5258 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5259
5260 /* Get VCLK */
5261 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5262 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5263
5264 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5265 if(SiS_Pr->SiS_UseROM) {
5266 if(ROMAddr[0x220] & 0x01) {
5267 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5268 }
5269 }
5270 }
5271
5272 } else {
5273
5274 /* Get VCLK */
5275 CRT2ModeNo = 0xfe;
5276 VCLK = SiS_Pr->CSRClock;
5277
5278 }
5279
5280 /* Get colordepth */
5281 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5282 if(!colorth) colorth++;
5283
5284 data = data * VCLK * colorth;
5285 temp = data % (MCLK << 4);
5286 data = data / (MCLK << 4);
5287 if(temp) data++;
5288
5289 if(data < 6) data = 6;
5290 else if(data > 0x14) data = 0x14;
5291
5292 if(SiS_Pr->ChipType == SIS_300) {
5293 temp = 0x16;
5294 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5295 temp = 0x13;
5296 } else {
5297 temp = 0x16;
5298 if(( (SiS_Pr->ChipType == SIS_630) ||
5299 (SiS_Pr->ChipType == SIS_730) ) &&
5300 (SiS_Pr->ChipRevision >= 0x30))
5301 temp = 0x1b;
5302 }
5303 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5304
5305 if((SiS_Pr->ChipType == SIS_630) &&
5306 (SiS_Pr->ChipRevision >= 0x30)) {
5307 if(data > 0x13) data = 0x13;
5308 }
5309 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5310
5311 } else { /* If mode <= 0x13, we just restore everything */
5312
5313 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5314 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5315
5316 }
5317 }
5318 #endif
5319
5320 /* Set CRT2 FIFO on 315/330 series */
5321 #ifdef SIS315H
5322 static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5323 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5324 {
5325 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5326 if( (SiS_Pr->ChipType == SIS_760) &&
5327 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5328 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5329 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5330 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5331 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5332 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5333 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5334 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5335 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5336 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5337 } else {
5338 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5339 }
5340
5341 }
5342 #endif
5343
5344 static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5345 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5346 {
5347 unsigned int tempax,tempbx;
5348
5349 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5350 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5351 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5352 return (unsigned short)tempax;
5353 }
5354
5355 /* Set Part 1 / SiS bridge slave mode */
5356 static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5357 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5358 unsigned short RefreshRateTableIndex)
5359 {
5360 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5361 static const unsigned short CRTranslation[] = {
5362 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5363 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5364 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5365 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5366 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5367 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5368 };
5369
5370 if(ModeNo <= 0x13) {
5371 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5372 } else if(SiS_Pr->UseCustomMode) {
5373 modeflag = SiS_Pr->CModeFlag;
5374 xres = SiS_Pr->CHDisplay;
5375 } else {
5376 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5377 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5378 }
5379
5380 /* The following is only done if bridge is in slave mode: */
5381
5382 if(SiS_Pr->ChipType >= SIS_315H) {
5383 if(xres >= 1600) { /* BIOS: == 1600 */
5384 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5385 }
5386 }
5387
5388 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5389
5390 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5391 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5392
5393 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5394 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5395 SiS_Pr->CHBlankStart += 16;
5396 }
5397
5398 SiS_Pr->CHBlankEnd = 32;
5399 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5400 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5401 }
5402
5403 temp = SiS_Pr->SiS_VGAHT - 96;
5404 if(!(modeflag & HalfDCLK)) temp -= 32;
5405 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5406 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5407 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5408 temp -= 3;
5409 temp <<= 3;
5410 } else {
5411 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5412 }
5413 SiS_Pr->CHSyncStart = temp;
5414
5415 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5416
5417 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5418
5419 VGAVDE = SiS_Pr->SiS_VGAVDE;
5420 if (VGAVDE == 357) VGAVDE = 350;
5421 else if(VGAVDE == 360) VGAVDE = 350;
5422 else if(VGAVDE == 375) VGAVDE = 350;
5423 else if(VGAVDE == 405) VGAVDE = 400;
5424 else if(VGAVDE == 420) VGAVDE = 400;
5425 else if(VGAVDE == 525) VGAVDE = 480;
5426 else if(VGAVDE == 1056) VGAVDE = 1024;
5427 SiS_Pr->CVDisplay = VGAVDE;
5428
5429 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5430
5431 SiS_Pr->CVBlankEnd = 1;
5432 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5433
5434 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5435 SiS_Pr->CVSyncStart = VGAVDE + temp;
5436
5437 temp >>= 3;
5438 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5439
5440 SiS_CalcCRRegisters(SiS_Pr, 0);
5441 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5442
5443 for(i = 0; i <= 7; i++) {
5444 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5445 }
5446 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5447 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5448 }
5449 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5450 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5451 }
5452 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5453 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5454 }
5455
5456 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5457 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5458
5459 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5460 if(modeflag & DoubleScanMode) temp |= 0x80;
5461 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5462
5463 temp = 0;
5464 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5465 if(modeflag & HalfDCLK) temp |= 0x08;
5466 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5467
5468 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5469 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5470
5471 temp = 0;
5472 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5473 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5474 }
5475 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5476
5477 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5478 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5479
5480 #ifdef SIS_XORG_XF86
5481 #ifdef TWDEBUG
5482 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5483 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5484 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5485 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5486
5487 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5488 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5489 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5490 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5491 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5492 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5493 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5494 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5495 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5496 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5497 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5498 #endif
5499 #endif
5500 }
5501
5502 /* Setup panel link
5503 * This is used for LVDS, LCDA and Chrontel TV output
5504 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5505 */
5506 static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5507 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5508 unsigned short RefreshRateTableIndex)
5509 {
5510 unsigned short modeflag, resinfo = 0;
5511 unsigned short push2, tempax, tempbx, tempcx, temp;
5512 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5513 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5514 BOOLEAN lvds550 = FALSE;
5515 #ifdef SIS300
5516 unsigned short crt2crtc = 0;
5517 #endif
5518 #ifdef SIS315H
5519 unsigned short pushcx;
5520 #endif
5521
5522 if(ModeNo <= 0x13) {
5523 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5524 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5525 #ifdef SIS300
5526 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5527 #endif
5528 } else if(SiS_Pr->UseCustomMode) {
5529 modeflag = SiS_Pr->CModeFlag;
5530 } else {
5531 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5532 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5533 #ifdef SIS300
5534 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5535 #endif
5536 }
5537
5538 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5539 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5540 islvds = TRUE;
5541 }
5542
5543 if(SiS_Pr->ChipType == SIS_550 &&
5544 SiS_Pr->SiS_IF_DEF_LVDS &&
5545 !SiS_Pr->SiS_IF_DEF_FSTN &&
5546 !SiS_Pr->SiS_IF_DEF_DSTN) {
5547 lvds550 = TRUE;
5548 }
5549
5550 /* is really sis if sis bridge, but not 301B-DH */
5551 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5552 issis = TRUE;
5553 }
5554
5555 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5556 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) {
5557 chkdclkfirst = TRUE;
5558 }
5559 }
5560
5561 #ifdef SIS315H
5562 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5563 if(IS_SIS330) {
5564 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5565 } else if(IS_SIS740) {
5566 if(islvds) {
5567 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5568 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5569 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5570 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5571 }
5572 } else {
5573 if(islvds) {
5574 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5575 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5576 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5577 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5578 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5579 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5580 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5581 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5582 }
5583 }
5584 }
5585 }
5586 }
5587 #endif
5588
5589 /* Horizontal */
5590
5591 tempax = SiS_Pr->SiS_LCDHDES;
5592 if(islvds) {
5593 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5594 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN && !lvds550) {
5595 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5596 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5597 tempax -= 8;
5598 }
5599 }
5600 }
5601 }
5602
5603 temp = (tempax & 0x0007);
5604 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5605 temp = (tempax >> 3) & 0x00FF;
5606 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5607
5608 tempbx = SiS_Pr->SiS_HDE;
5609 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5610 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5611 tempbx = SiS_Pr->PanelXRes;
5612 }
5613 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5614 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5615 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5616 tempbx >>= 1;
5617 }
5618 }
5619
5620 tempax += tempbx;
5621 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5622
5623 temp = tempax;
5624 if(temp & 0x07) temp += 8;
5625 temp >>= 3;
5626 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5627
5628 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5629
5630 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5631 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5632 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5633 }
5634 }
5635
5636 tempcx += tempax;
5637 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5638
5639 temp = (tempcx >> 3) & 0x00FF;
5640 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5641 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5642 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5643 switch(ModeNo) {
5644 case 0x04:
5645 case 0x05:
5646 case 0x0d: temp = 0x56; break;
5647 case 0x10: temp = 0x60; break;
5648 case 0x13: temp = 0x5f; break;
5649 case 0x40:
5650 case 0x41:
5651 case 0x4f:
5652 case 0x43:
5653 case 0x44:
5654 case 0x62:
5655 case 0x56:
5656 case 0x53:
5657 case 0x5d:
5658 case 0x5e: temp = 0x54; break;
5659 }
5660 }
5661 }
5662 }
5663 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5664
5665 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5666 temp += 2;
5667 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5668 temp += 8;
5669 if(SiS_Pr->PanelHRE != 999) {
5670 temp = tempcx + SiS_Pr->PanelHRE;
5671 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5672 temp >>= 3;
5673 }
5674 }
5675 } else {
5676 temp += 10;
5677 }
5678
5679 temp &= 0x1F;
5680 temp |= ((tempcx & 0x07) << 5);
5681 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5682
5683 /* Vertical */
5684
5685 tempax = SiS_Pr->SiS_VGAVDE;
5686 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5687 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5688 tempax = SiS_Pr->PanelYRes;
5689 }
5690 }
5691
5692 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5693 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5694
5695 push2 = tempbx;
5696
5697 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5698 if((SiS_Pr->ChipType < SIS_315H) || lvds550) {
5699 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5700 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5701 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5702 }
5703 }
5704 }
5705 if(islvds) tempcx >>= 1;
5706 else tempcx >>= 2;
5707
5708 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5709 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5710 (SiS_Pr->PanelVRS != 999) ) {
5711 tempcx = SiS_Pr->PanelVRS;
5712 tempbx += tempcx;
5713 if(issis || lvds550) tempbx++;
5714 } else {
5715 tempbx += tempcx;
5716 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5717 else if(issis || lvds550) tempbx++;
5718 }
5719
5720 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5721
5722 temp = tempbx & 0x00FF;
5723 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5724 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5725 if(ModeNo == 0x10) temp = 0xa9;
5726 }
5727 }
5728 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5729
5730 tempcx >>= 3;
5731 tempcx++;
5732
5733 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5734 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5735 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5736 }
5737 }
5738
5739 tempcx += tempbx;
5740 temp = tempcx & 0x000F;
5741 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5742
5743 temp = ((tempbx >> 8) & 0x07) << 3;
5744 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN || lvds550) {
5745 if(SiS_Pr->SiS_HDE != 640) {
5746 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5747 }
5748 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5749 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5750 tempbx = 0x87;
5751 if((SiS_Pr->ChipType >= SIS_315H) ||
5752 (SiS_Pr->ChipRevision >= 0x30)) {
5753 tempbx = 0x07;
5754 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5755 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5756 }
5757 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5758 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5759 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5760 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5761 } else {
5762 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5763 }
5764 }
5765 }
5766 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5767
5768 tempbx = push2; /* BPLVDEE */
5769
5770 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5771
5772 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5773 switch(SiS_Pr->SiS_LCDResInfo) {
5774 case Panel_640x480:
5775 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5776 tempcx = SiS_Pr->SiS_VGAVDE;
5777 break;
5778 case Panel_800x600:
5779 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5780 if(resinfo == SIS_RI_800x600) tempcx++;
5781 }
5782 break;
5783 case Panel_1024x600:
5784 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5785 if(resinfo == SIS_RI_1024x600) tempcx++;
5786 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5787 if(resinfo == SIS_RI_800x600) tempcx++;
5788 }
5789 }
5790 break;
5791 case Panel_1024x768:
5792 if(SiS_Pr->ChipType < SIS_315H) {
5793 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5794 if(resinfo == SIS_RI_1024x768) tempcx++;
5795 }
5796 }
5797 break;
5798 }
5799 }
5800
5801 temp = ((tempbx >> 8) & 0x07) << 3;
5802 temp |= ((tempcx >> 8) & 0x07);
5803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5804 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5805 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5806
5807 /* Vertical scaling */
5808
5809 if(SiS_Pr->ChipType < SIS_315H) {
5810
5811 #ifdef SIS300 /* 300 series */
5812 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5813 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5814 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5815 if(temp) tempeax++;
5816
5817 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5818
5819 temp = (unsigned short)(tempeax & 0x00FF);
5820 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5821 tempvcfact = temp;
5822 #endif /* SIS300 */
5823
5824 } else {
5825
5826 #ifdef SIS315H /* 315 series */
5827 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5828 tempebx = SiS_Pr->SiS_VDE;
5829 temp = (tempeax % tempebx);
5830 tempeax = tempeax / tempebx;
5831 if(temp) tempeax++;
5832 tempvcfact = tempeax;
5833
5834 temp = (unsigned short)(tempeax & 0x00FF);
5835 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5836 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5838 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5839 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5840 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5841
5842 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5843 temp = (unsigned short)(tempeax & 0x00FF);
5844 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5845 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5846 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5847 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5848 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5849 temp = 0;
5850 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5851 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5852 }
5853 #endif
5854
5855 }
5856
5857 /* Horizontal scaling */
5858
5859 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5860 if(chkdclkfirst) {
5861 if(modeflag & HalfDCLK) tempeax >>= 1;
5862 }
5863 tempebx = tempeax << 16;
5864 if(SiS_Pr->SiS_HDE == tempeax) {
5865 tempecx = 0xFFFF;
5866 } else {
5867 tempecx = tempebx / SiS_Pr->SiS_HDE;
5868 if(SiS_Pr->ChipType >= SIS_315H) {
5869 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5870 }
5871 }
5872
5873 if(SiS_Pr->ChipType >= SIS_315H) {
5874 tempeax = (tempebx / tempecx) - 1;
5875 } else {
5876 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5877 }
5878 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5879 temp = (unsigned short)(tempecx & 0x00FF);
5880 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5881
5882 if(SiS_Pr->ChipType >= SIS_315H) {
5883 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5884 tempbx = (unsigned short)(tempeax & 0xFFFF);
5885 } else {
5886 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5887 tempbx = tempvcfact & 0x3f;
5888 if(tempbx == 0) tempbx = 64;
5889 tempeax /= tempbx;
5890 tempbx = (unsigned short)(tempeax & 0xFFFF);
5891 }
5892 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5893 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5894 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5895 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5896 }
5897
5898 temp = ((tempbx >> 8) & 0x07) << 3;
5899 temp = temp | ((tempecx >> 8) & 0x07);
5900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5902
5903 tempecx >>= 16; /* BPLHCFACT */
5904 if(!chkdclkfirst) {
5905 if(modeflag & HalfDCLK) tempecx >>= 1;
5906 }
5907 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5909 temp = (unsigned short)(tempecx & 0x00FF);
5910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5911
5912 #ifdef SIS315H
5913 if(SiS_Pr->ChipType >= SIS_315H) {
5914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5915 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5917 }
5918 } else {
5919 if(islvds) {
5920 if(SiS_Pr->ChipType == SIS_740) {
5921 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5922 } else {
5923 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5924 }
5925 }
5926 }
5927 }
5928 #endif
5929
5930 #ifdef SIS300
5931 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5932 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5933 unsigned char *trumpdata;
5934 int i, j = crt2crtc;
5935 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5936 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5937 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5938
5939 if(SiS_Pr->SiS_UseROM) {
5940 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5941 } else {
5942 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5943 trumpdata = &SiS300_TrumpionData[j][0];
5944 }
5945
5946 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5947 for(i=0; i<5; i++) {
5948 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5949 }
5950 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5951 if(ModeNo == 0x13) {
5952 for(i=0; i<4; i++) {
5953 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5954 }
5955 } else if(ModeNo == 0x10) {
5956 for(i=0; i<4; i++) {
5957 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5958 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5959 }
5960 }
5961 }
5962 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5963 }
5964 #endif
5965
5966 #ifdef SIS315H
5967 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5975 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5976 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5977 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5978 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5979 tempax += 64;
5980 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5981 temp = (tempax >> 8) << 3;
5982 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5983 tempax += 32; /* Blpe = lBlps+32 */
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5985 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5986 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5987
5988 tempax = SiS_Pr->SiS_VDE;
5989 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5990 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5991 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5992 tempax >>= 1;
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5994 temp = (tempax >> 8) << 3;
5995 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5996
5997 tempeax = SiS_Pr->SiS_HDE;
5998 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5999 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6000 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6001 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6002 temp = tempeax & 0x7f;
6003 tempeax >>= 7;
6004 if(temp) tempeax++;
6005 temp = tempeax & 0x3f;
6006 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6007 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6008 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6009 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6010 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6011
6012 tempax = SiS_Pr->SiS_HDE;
6013 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6014 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6015 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6016 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6017 pushcx = tempax;
6018 temp = tempax & 0x00FF;
6019 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6020 temp = ((tempax & 0xFF00) >> 8) << 3;
6021 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6022
6023 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6024 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6025 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6026 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6027 tempeax = tempax * pushcx;
6028 temp = tempeax & 0xFF;
6029 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6030 temp = (tempeax & 0xFF00) >> 8;
6031 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6032 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6033 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6034 temp = ((tempeax & 0x01000000) >> 24) << 7;
6035 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6036
6037 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6038 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6039 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6040 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6041 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6042
6043 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6044 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6045 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6046 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6047 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6048 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6049 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6050 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6051 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6052 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6053 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6054 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6059 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6060 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6061 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6062 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6063 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6064 }
6065 }
6066 #endif /* SIS315H */
6067 }
6068
6069 /* Set Part 1 */
6070 static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6071 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6072 unsigned short RefreshRateTableIndex)
6073 {
6074 #if defined(SIS300) || defined(SIS315H)
6075 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6076 #endif
6077 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6078 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0, lvds550=0;
6079 #ifdef SIS315H
6080 unsigned short tempbl=0;
6081 #endif
6082
6083 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6084 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6085 return;
6086 }
6087
6088 if(ModeNo <= 0x13) {
6089 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6090 } else if(SiS_Pr->UseCustomMode) {
6091 modeflag = SiS_Pr->CModeFlag;
6092 } else {
6093 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6094 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6095 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6096 }
6097
6098 if(SiS_Pr->ChipType == SIS_550 &&
6099 SiS_Pr->SiS_IF_DEF_LVDS &&
6100 !SiS_Pr->SiS_IF_DEF_DSTN &&
6101 !SiS_Pr->SiS_IF_DEF_FSTN) {
6102 lvds550 = 1;
6103 }
6104
6105 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6106
6107 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6108 (!lvds550) &&
6109 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6110 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6111
6112 if(SiS_Pr->ChipType < SIS_315H ) {
6113 #ifdef SIS300
6114 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6115 #endif
6116 } else {
6117 #ifdef SIS315H
6118 SiS_SetCRT2FIFO_310(SiS_Pr);
6119 #endif
6120 }
6121
6122 /* 1. Horizontal setup */
6123
6124 if(SiS_Pr->ChipType < SIS_315H) {
6125
6126 #ifdef SIS300 /* ------------- 300 series --------------*/
6127
6128 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6130
6131 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6132 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6133
6134 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6135 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6136
6137 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6138 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6139 tempbx = pushbx + tempcx;
6140 tempcx <<= 1;
6141 tempcx += tempbx;
6142
6143 bridgeadd = 12;
6144
6145 #endif /* SIS300 */
6146
6147 } else {
6148
6149 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6150
6151 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6152 if(modeflag & HalfDCLK) {
6153 if((SiS_Pr->SiS_VBType & VB_SISVB) || lvds550) {
6154 tempcx >>= 1;
6155 } else {
6156 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6157 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6158 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6159 tempcx = SiS_Pr->SiS_HT - tempax;
6160 }
6161 }
6162 }
6163 tempcx--;
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6165 temp = (tempcx >> 4) & 0xF0;
6166 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6167
6168 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6169 tempbx = SiS_Pr->SiS_VGAHDE;
6170 tempcx -= tempbx;
6171 tempcx >>= 2;
6172 if(modeflag & HalfDCLK) {
6173 tempbx >>= 1;
6174 tempcx >>= 1;
6175 }
6176 tempbx += 16;
6177
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6179
6180 pushbx = tempbx;
6181 if(!lvds550) tempcx >>= 1;
6182 tempbx += tempcx;
6183 tempcx += tempbx;
6184 if(lvds550) tempcx += 20;
6185
6186 bridgeadd = 16;
6187
6188 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6189 if(SiS_Pr->ChipType >= SIS_661) {
6190 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6191 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6192 if(resinfo == SIS_RI_1280x1024) {
6193 tempcx = (tempcx & 0xff00) | 0x30;
6194 } else if(resinfo == SIS_RI_1600x1200) {
6195 tempcx = (tempcx & 0xff00) | 0xff;
6196 }
6197 }
6198 }
6199 }
6200
6201 #endif /* SIS315H */
6202
6203 } /* 315/330 series */
6204
6205 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6206
6207 if(SiS_Pr->UseCustomMode) {
6208 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6209 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6210 tempax = SiS_Pr->SiS_VGAHT;
6211 if(modeflag & HalfDCLK) tempax >>= 1;
6212 tempax--;
6213 if(tempcx > tempax) tempcx = tempax;
6214 }
6215
6216 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6217 unsigned char cr4, cr14, cr5, cr15;
6218 if(SiS_Pr->UseCustomMode) {
6219 cr4 = SiS_Pr->CCRT1CRTC[4];
6220 cr14 = SiS_Pr->CCRT1CRTC[14];
6221 cr5 = SiS_Pr->CCRT1CRTC[5];
6222 cr15 = SiS_Pr->CCRT1CRTC[15];
6223 } else {
6224 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6225 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6226 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6227 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6228 }
6229 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6230 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6231 tempcx &= 0x00FF;
6232 tempcx |= (tempbx & 0xFF00);
6233 tempbx += bridgeadd;
6234 tempcx += bridgeadd;
6235 tempax = SiS_Pr->SiS_VGAHT;
6236 if(modeflag & HalfDCLK) tempax >>= 1;
6237 tempax--;
6238 if(tempcx > tempax) tempcx = tempax;
6239 }
6240
6241 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6242 tempbx = 1040;
6243 tempcx = 1044; /* HWCursor bug! */
6244 }
6245
6246 }
6247
6248 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6249
6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6251
6252 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6254
6255 /* 2. Vertical setup */
6256
6257 tempcx = SiS_Pr->SiS_VGAVT - 1;
6258 temp = tempcx & 0x00FF;
6259 if((SiS_Pr->ChipType < SIS_661) && !lvds550) {
6260 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6261 if(SiS_Pr->ChipType < SIS_315H) {
6262 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6263 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6264 temp--;
6265 }
6266 }
6267 } else {
6268 temp--;
6269 }
6270 } else if(SiS_Pr->ChipType >= SIS_315H) {
6271 temp--;
6272 }
6273 }
6274 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6275
6276 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6278
6279 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6281
6282 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661) && !lvds550) {
6283 tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
6284 tempbx = SiS_Pr->SiS_VGAVDE + tempcx;
6285 if(tempcx < 4) tempcx = 4;
6286 tempcx = (tempcx >> 2) + tempbx + 1;
6287 } else {
6288 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6289 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6290 }
6291
6292 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6293 if(SiS_Pr->UseCustomMode) {
6294 tempbx = SiS_Pr->CVSyncStart;
6295 tempcx = SiS_Pr->CVSyncEnd;
6296 }
6297 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6298 unsigned char cr8, cr7, cr13;
6299 if(SiS_Pr->UseCustomMode) {
6300 cr8 = SiS_Pr->CCRT1CRTC[8];
6301 cr7 = SiS_Pr->CCRT1CRTC[7];
6302 cr13 = SiS_Pr->CCRT1CRTC[13];
6303 tempcx = SiS_Pr->CCRT1CRTC[9];
6304 } else {
6305 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6306 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6307 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6308 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6309 }
6310 tempbx = cr8;
6311 if(cr7 & 0x04) tempbx |= 0x0100;
6312 if(cr7 & 0x80) tempbx |= 0x0200;
6313 if(cr13 & 0x08) tempbx |= 0x0400;
6314 }
6315 }
6316 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6317
6318 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6319 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6320
6321 /* 3. Panel delay compensation */
6322
6323 if(SiS_Pr->ChipType < SIS_315H) {
6324
6325 #ifdef SIS300 /* ---------- 300 series -------------- */
6326
6327 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6328 temp = 0x20;
6329 if(SiS_Pr->ChipType == SIS_300) {
6330 temp = 0x10;
6331 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6332 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6333 }
6334 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6335 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6336 }
6337 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6338 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6339 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6340 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6341 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6342 else temp = 0x20;
6343 }
6344 if(SiS_Pr->SiS_UseROM) {
6345 if(ROMAddr[0x220] & 0x80) {
6346 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6347 temp = ROMAddr[0x221];
6348 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6349 temp = ROMAddr[0x222];
6350 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6351 temp = ROMAddr[0x223];
6352 else
6353 temp = ROMAddr[0x224];
6354 }
6355 }
6356 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6357 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6358 }
6359
6360 } else {
6361 temp = 0x20;
6362 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6363 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6364 }
6365 if(SiS_Pr->SiS_UseROM) {
6366 if(ROMAddr[0x220] & 0x80) {
6367 temp = ROMAddr[0x220];
6368 }
6369 }
6370 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6371 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6372 }
6373 }
6374
6375 temp &= 0x3c;
6376
6377 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6378
6379 #endif /* SIS300 */
6380
6381 } else {
6382
6383 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6384
6385 if(SiS_Pr->ChipType < SIS_661) {
6386
6387 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6388
6389 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6390 else temp = 0x00;
6391
6392 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6393 tempbl = 0xF0;
6394 if(SiS_Pr->ChipType == SIS_650) {
6395 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6396 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6397 }
6398 }
6399
6400 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN || lvds550) {
6401 temp = 0x08;
6402 tempbl = 0;
6403 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6404 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6405 }
6406 }
6407
6408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6409 }
6410
6411 } /* < 661 */
6412
6413 tempax = 0;
6414 if(modeflag & DoubleScanMode) tempax |= 0x80;
6415 if(modeflag & HalfDCLK) tempax |= 0x40;
6416 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6417
6418 #endif /* SIS315H */
6419
6420 }
6421
6422 } /* Slavemode */
6423
6424 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6425 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6426 /* For 301BDH with LCD, we set up the Panel Link */
6427 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6428 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6429 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6430 }
6431 } else {
6432 if(SiS_Pr->ChipType < SIS_315H) {
6433 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6434 } else {
6435 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6436 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6437 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6438 }
6439 } else {
6440 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6441 }
6442 }
6443 }
6444 }
6445
6446 /*********************************************/
6447 /* SET PART 2 REGISTER GROUP */
6448 /*********************************************/
6449
6450 #ifdef SIS315H
6451 static BOOLEAN
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6452 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6453 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6454 unsigned short *ResIndex)
6455 {
6456
6457 if(SiS_Pr->ChipType < SIS_315H) return FALSE;
6458
6459 if(ModeNo <= 0x13)
6460 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6461 else
6462 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6463
6464 (*ResIndex) &= 0x3f;
6465 (*CRT2Index) = 0;
6466
6467 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6468 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6469 (*CRT2Index) = 200;
6470 }
6471 }
6472
6473 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6474 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6475 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6476 }
6477 }
6478 return (((*CRT2Index) != 0));
6479 }
6480 #endif
6481
6482 #ifdef SIS300
6483 static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6484 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6485 {
6486 unsigned short tempcx;
6487 static const unsigned char atable[] = {
6488 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6489 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6490 };
6491
6492 if(!SiS_Pr->UseCustomMode) {
6493 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6494 (SiS_Pr->ChipType == SIS_730) ) &&
6495 (SiS_Pr->ChipRevision > 2) ) &&
6496 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6497 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6498 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6499 if(ModeNo == 0x13) {
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6501 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6503 } else if((crt2crtc & 0x3F) == 4) {
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6505 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6509 }
6510 }
6511
6512 if(SiS_Pr->ChipType < SIS_315H) {
6513 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6514 crt2crtc &= 0x1f;
6515 tempcx = 0;
6516 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6517 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6518 tempcx += 7;
6519 }
6520 }
6521 tempcx += crt2crtc;
6522 if(crt2crtc >= 4) {
6523 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6524 }
6525
6526 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6527 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6528 if(crt2crtc == 4) {
6529 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6530 }
6531 }
6532 }
6533 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6534 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6535 }
6536 }
6537 }
6538 }
6539
6540 /* For ECS A907. Highly preliminary. */
6541 static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6542 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6543 unsigned short ModeNo)
6544 {
6545 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6546 unsigned short crt2crtc, resindex;
6547 int i, j;
6548
6549 if(SiS_Pr->ChipType != SIS_300) return;
6550 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6551 if(SiS_Pr->UseCustomMode) return;
6552
6553 if(ModeNo <= 0x13) {
6554 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6555 } else {
6556 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6557 }
6558
6559 resindex = crt2crtc & 0x3F;
6560 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6561 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6562
6563 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6564 if(ModeNo > 0x13) {
6565 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6566 resindex = 4;
6567 }
6568
6569 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6570 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6571 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6572 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6573 }
6574 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6575 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6576 }
6577 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6578 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6579 }
6580 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6581 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6582 }
6583 #endif
6584
6585 static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6586 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6587 {
6588 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6589 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
6590 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p)) return;
6591
6592 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6593 if(SiS_Pr->SiS_TVMode & TVSetHiVi960540) {
6594 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6595 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x47);
6596 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0xea);
6597 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x00);
6598 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0e);
6599 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x00);
6600 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0xe6);
6601 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x90);
6602 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x09);
6603 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x03);
6604 }
6605 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
6606 #ifndef OLD1280720P
6607 if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
6608 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
6609 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x23);
6610 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x1c);
6611 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,0x10);
6612 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,0x0b);
6613 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,0x10);
6614 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x2c);
6615 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x68);
6616 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xc0,0x01);
6617 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xf8,0x05);
6618 }
6619 #endif
6620 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
6621 if(SiS_Pr->SiS_TVMode & TVSet525p1024) {
6622 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x77);
6623 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,0x13);
6624 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2b,0x78);
6625 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2c,0x04);
6626 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x42,0x14);
6627 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x73);
6628 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,0xaf);
6629 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1e,0x71);
6630 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,0xbb);
6631 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,0xb5);
6632 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x26,0xdc);
6633 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,0x3c);
6634 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x45,0x11);
6635 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,0x00);
6636 }
6637 } else if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6638 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6639 static const unsigned char specialtv[] = {
6640 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6641 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6642 0x58,0xe4,0x73,0xda,0x13
6643 };
6644 int i, j;
6645 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6646 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6647 }
6648 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6649 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6650 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6651 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6652 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6653 } else {
6654 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6655 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6656 }
6657 }
6658 }
6659 } else {
6660 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6661 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6662 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6663 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6664 } else {
6665 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6666 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6667 }
6668 }
6669 }
6670
6671 static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6672 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6673 {
6674 unsigned short temp;
6675
6676 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6677 if(SiS_Pr->SiS_VGAVDE == 525) {
6678 temp = 0xc3;
6679 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6680 temp++;
6681 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6682 }
6683 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6684 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6685 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6686 temp = 0x4d;
6687 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6688 temp++;
6689 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6690 }
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6692 }
6693 }
6694
6695 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6696 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6697 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6698 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6699 /* Not always for LV, see SetGrp2 */
6700 }
6701 temp = 1;
6702 if(ModeNo <= 0x13) temp = 3;
6703 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6704 }
6705 }
6706 }
6707
6708 static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6709 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6710 unsigned short RefreshRateTableIndex)
6711 {
6712 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6713 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6714 unsigned int longtemp, PhaseIndex;
6715 BOOLEAN newtvphase;
6716 const unsigned char *TimingPoint;
6717 #ifdef SIS315H
6718 unsigned short resindex, CRT2Index;
6719 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6720
6721 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6722 #endif
6723
6724 if(ModeNo <= 0x13) {
6725 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6726 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6727 } else if(SiS_Pr->UseCustomMode) {
6728 modeflag = SiS_Pr->CModeFlag;
6729 crt2crtc = 0;
6730 } else {
6731 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6732 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6733 }
6734
6735 temp = 0;
6736 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6737 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6738 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6740
6741 if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming)) temp |= 0x10;
6742
6743 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6744
6745 PhaseIndex = 0x01; /* SiS_PALPhase */
6746 TimingPoint = SiS_Pr->SiS_PALTiming;
6747
6748 newtvphase = FALSE;
6749 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6750 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6751 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6752 newtvphase = TRUE;
6753 }
6754
6755 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6756
6757 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6758 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6759 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6760 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6761 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6762 }
6763 }
6764
6765 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6766
6767 i = 0;
6768 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6769 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6770 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625i) i = 3;
6771 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr625p) i = 4;
6772
6773 TimingPoint = &SiS_YPbPrTable[i][0];
6774
6775 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6776
6777 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6778
6779 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6780
6781 } else {
6782
6783 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6784 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6785 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6786
6787 }
6788
6789 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6790 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6791 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6792 }
6793
6794 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6795 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6796 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6797 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6798 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6799 } else {
6800 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6801 }
6802 }
6803
6804 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6805 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6806 }
6807
6808 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6809 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6810 }
6811 for(i = 0x39; i <= 0x45; i++, j++) {
6812 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6813 }
6814
6815 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6816 if(SiS_Pr->SiS_ModeType != ModeText) {
6817 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6818 }
6819 }
6820
6821 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6822
6823 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6824 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6827
6828 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6829 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6830 else if(SiS_Pr->SiS_TVMode & TVSetPALTiming) tempax = 520;
6831 else tempax = 440; /* NTSC, YPbPr 525 */
6832
6833 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_VDE <= tempax)) {
6834
6835 tempax -= SiS_Pr->SiS_VDE;
6836 tempax >>= 1;
6837 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) {
6838 tempax >>= 1;
6839 }
6840 tempax &= 0x00ff;
6841
6842 temp = tempax + (unsigned short)TimingPoint[0];
6843 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6844
6845 temp = tempax + (unsigned short)TimingPoint[1];
6846 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6847 }
6848
6849 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6850 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6851 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6852 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6853 } else {
6854 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6855 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6856 }
6857 }
6858
6859 tempcx = SiS_Pr->SiS_HT;
6860 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6861 tempcx--;
6862 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6863 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6864 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6865
6866 tempcx = SiS_Pr->SiS_HT >> 1;
6867 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6868 tempcx += 7;
6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6870 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6871
6872 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6873 tempbx += tempcx;
6874 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6875 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6876
6877 tempbx += 8;
6878 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6879 tempbx -= 4;
6880 tempcx = tempbx;
6881 }
6882 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6883
6884 j += 2;
6885 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6886 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6887 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6888
6889 tempcx += 8;
6890 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6891 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6892
6893 tempcx = SiS_Pr->SiS_HT >> 1;
6894 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6895 j += 2;
6896 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6897 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6898
6899 tempcx -= 11;
6900 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6901 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6902 }
6903 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6904
6905 tempbx = SiS_Pr->SiS_VDE;
6906 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6907 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6908 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6909 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6910 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6911 (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) {
6912 tempbx >>= 1;
6913 if(SiS_Pr->ChipType >= SIS_315H) {
6914 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6915 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6916 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6917 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6918 if(crt2crtc == 4) tempbx++;
6919 }
6920 }
6921 }
6922 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6924 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6925 }
6926 if(!(SiS_Pr->SiS_TVMode & TVSetPALTiming)) {
6927 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6928 }
6929 }
6930 }
6931 tempbx -= 2;
6932 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6933
6934 temp = (tempcx >> 8) & 0x0F;
6935 temp |= ((tempbx >> 2) & 0xC0);
6936 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6937 temp |= 0x10;
6938 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6939 }
6940 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6941
6942 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6943 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6944 }
6945
6946 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6947 tempbx = SiS_Pr->SiS_VDE;
6948 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6949 (!(SiS_Pr->SiS_TVMode & TVSetYPbPrProg)) ) {
6950 tempbx >>= 1;
6951 }
6952 tempbx -= 3;
6953 temp = ((tempbx >> 3) & 0x60) | 0x18;
6954 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6955 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6956
6957 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6958 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6959 }
6960 }
6961
6962 tempax = tempbx = tempcx = 0;
6963 if(!(modeflag & HalfDCLK)) {
6964 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6965 tempbx |= 0x20;
6966 }
6967 }
6968
6969 tempch = tempcl = 1;
6970 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6971 if(SiS_Pr->SiS_VGAHDE >= 960) {
6972 if(!(modeflag & HalfDCLK)) {
6973 tempcl = 32;
6974 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6975 tempch = 20;
6976 tempbx &= ~0x20;
6977 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6978 tempch = 25;
6979 } else {
6980 tempch = 25; /* OK */
6981 }
6982 }
6983 }
6984 }
6985
6986 if(!(tempbx & 0x20)) {
6987 if(modeflag & HalfDCLK) tempcl <<= 1;
6988 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6989 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6990 tempax = longtemp / SiS_Pr->SiS_HDE;
6991 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6992 tempbx |= ((tempax >> 8) & 0x1F);
6993 tempcx = tempax >> 13;
6994 }
6995
6996 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6997 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6998
6999 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7000
7001 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,(tempcx & 0x07));
7002
7003 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) {
7004 tempbx = 0x0382;
7005 tempcx = 0x007e;
7006 } else {
7007 tempbx = 0x0369;
7008 tempcx = 0x0061;
7009 }
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7011 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7012 temp = (tempcx & 0x0300) >> 6;
7013 temp |= ((tempbx >> 8) & 0x03);
7014 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7015 temp |= 0x10;
7016 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp |= 0x20;
7017 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7018 }
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7020
7021 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7022 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7023
7024 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7025
7026 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7027 temp = 0;
7028 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7029 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7030 }
7031
7032 }
7033
7034 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7035 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7036 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7037 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7038 }
7039 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7040 }
7041
7042 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7043 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7044 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7045 }
7046 }
7047
7048 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7049
7050 /* From here: Part2 LCD setup */
7051
7052 tempbx = SiS_Pr->SiS_HDE;
7053 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7054 tempbx--; /* RHACTE = HDE - 1 */
7055 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7056 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7057
7058 temp = 0x01;
7059 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7060 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7061 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7062 temp = 0x02;
7063 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7064 temp = 0x01;
7065 }
7066 }
7067 }
7068 }
7069 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7070
7071 tempbx = SiS_Pr->SiS_VDE - 1;
7072 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7073 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7074
7075 tempcx = SiS_Pr->SiS_VT - 1;
7076 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7077 temp = (tempcx >> 3) & 0xE0;
7078 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7079 /* Enable dithering; only do this for 32bpp mode */
7080 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7081 temp |= 0x10;
7082 }
7083 }
7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7085
7086 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7087 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7088
7089 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7090 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7091
7092 #ifdef SIS315H
7093 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7094 &CRT2Index, &resindex)) {
7095 switch(CRT2Index) {
7096 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7097 default:
7098 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7099 }
7100
7101 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7102 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7103 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7104 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7105 }
7106 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7107 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7108 }
7109 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7110 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7111 }
7112 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7113 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7114
7115 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7116
7117 } else {
7118 #endif
7119
7120 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7121 /* Clevo dual-link 1024x768 */
7122 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7123 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7124
7125 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7126 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7127 tempbx = SiS_Pr->SiS_VDE - 1;
7128 tempcx = SiS_Pr->SiS_VT - 1;
7129 } else {
7130 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7131 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7132 }
7133 } else {
7134 tempbx = SiS_Pr->PanelYRes;
7135 tempcx = SiS_Pr->SiS_VT;
7136 tempax = 1;
7137 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7138 tempax = SiS_Pr->PanelYRes;
7139 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7140 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7141 tempax = tempcx = 0;
7142 } else {
7143 tempax -= SiS_Pr->SiS_VDE;
7144 }
7145 tempax >>= 1;
7146 }
7147 tempcx -= tempax; /* lcdvdes */
7148 tempbx -= tempax; /* lcdvdee */
7149 }
7150
7151 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7152
7153 #ifdef SIS_XORG_XF86
7154 #ifdef TWDEBUG
7155 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7156 #endif
7157 #endif
7158
7159 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7160 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7161
7162 temp = (tempbx >> 5) & 0x38;
7163 temp |= ((tempcx >> 8) & 0x07);
7164 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7165
7166 tempax = SiS_Pr->SiS_VDE;
7167 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7168 tempax = SiS_Pr->PanelYRes;
7169 }
7170 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7171 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7172 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7173 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7174 }
7175 }
7176
7177 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7178 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7179 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7180 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7181 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7182 if(tempax % 4) { tempax >>= 2; tempax++; }
7183 else { tempax >>= 2; }
7184 tempbx -= (tempax - 1);
7185 } else {
7186 tempbx -= 10;
7187 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7188 }
7189 }
7190 }
7191 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7192 tempbx++;
7193 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7194 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7195 tempbx = 770;
7196 tempcx = 3;
7197 }
7198 }
7199 }
7200
7201 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7202
7203 if(SiS_Pr->UseCustomMode) {
7204 tempbx = SiS_Pr->CVSyncStart;
7205 }
7206
7207 #ifdef SIS_XORG_XF86
7208 #ifdef TWDEBUG
7209 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7210 #endif
7211 #endif
7212
7213 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7214
7215 temp = (tempbx >> 4) & 0xF0;
7216 tempbx += (tempcx + 1);
7217 temp |= (tempbx & 0x0F);
7218
7219 if(SiS_Pr->UseCustomMode) {
7220 temp &= 0xf0;
7221 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7222 }
7223
7224 #ifdef SIS_XORG_XF86
7225 #ifdef TWDEBUG
7226 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7227 #endif
7228 #endif
7229
7230 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7231
7232 #ifdef SIS300
7233 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7234 #endif
7235
7236 bridgeoffset = 7;
7237 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7238 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7239 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7240 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7241 /* Higher bridgeoffset shifts to the LEFT */
7242
7243 temp = 0;
7244 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7245 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7246 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7247 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7248 }
7249 }
7250 temp += bridgeoffset;
7251 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7252 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7253
7254 tempcx = SiS_Pr->SiS_HT;
7255 tempax = tempbx = SiS_Pr->SiS_HDE;
7256 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7257 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7258 tempax = SiS_Pr->PanelXRes;
7259 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7260 }
7261 }
7262 if(SiS_IsDualLink(SiS_Pr)) {
7263 tempcx >>= 1;
7264 tempbx >>= 1;
7265 tempax >>= 1;
7266 }
7267
7268 #ifdef SIS_XORG_XF86
7269 #ifdef TWDEBUG
7270 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7271 #endif
7272 #endif
7273
7274 tempbx += bridgeoffset;
7275
7276 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7277 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7278
7279 tempcx = (tempcx - tempax) >> 2;
7280
7281 tempbx += tempcx;
7282 push2 = tempbx;
7283
7284 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7285 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7286 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7287 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7288 }
7289 }
7290 }
7291
7292 if(SiS_Pr->UseCustomMode) {
7293 tempbx = SiS_Pr->CHSyncStart;
7294 if(modeflag & HalfDCLK) tempbx <<= 1;
7295 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7296 tempbx += bridgeoffset;
7297 }
7298
7299 #ifdef SIS_XORG_XF86
7300 #ifdef TWDEBUG
7301 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7302 #endif
7303 #endif
7304
7305 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7306 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7307
7308 tempbx = push2;
7309
7310 tempcx <<= 1;
7311 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7312 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7313 }
7314 tempbx += tempcx;
7315
7316 if(SiS_Pr->UseCustomMode) {
7317 tempbx = SiS_Pr->CHSyncEnd;
7318 if(modeflag & HalfDCLK) tempbx <<= 1;
7319 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7320 tempbx += bridgeoffset;
7321 }
7322
7323 #ifdef SIS_XORG_XF86
7324 #ifdef TWDEBUG
7325 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7326 #endif
7327 #endif
7328
7329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7330
7331 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7332
7333 #ifdef SIS300
7334 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7335 #endif
7336 #ifdef SIS315H
7337 } /* CRT2-LCD from table */
7338 #endif
7339 }
7340
7341 /*********************************************/
7342 /* SET PART 3 REGISTER GROUP */
7343 /*********************************************/
7344
7345 static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7346 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7347 {
7348 unsigned short i;
7349 const unsigned char *tempdi;
7350
7351 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7352
7353 #ifndef SIS_CP
7354 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7355 #else
7356 SIS_CP_INIT301_CP
7357 #endif
7358
7359 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) {
7360 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7361 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7362 } else {
7363 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7364 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7365 }
7366
7367 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7368 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7369 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7370 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7371 }
7372
7373 tempdi = NULL;
7374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7375 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7376 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7377 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7378 }
7379 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7380 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr625i))) {
7381 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)
7382 tempdi = SiS_HiTVGroup3_2;
7383 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)
7384 tempdi = SiS_HiTVGroup3_1;
7385 }
7386 }
7387 if(tempdi) {
7388 for(i=0; i<=0x3E; i++) {
7389 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7390 }
7391 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7392 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7393 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7394 }
7395 }
7396 }
7397
7398 #ifdef SIS_CP
7399 SIS_CP_INIT301_CP2
7400 #endif
7401 }
7402
7403 /*********************************************/
7404 /* SET PART 4 REGISTER GROUP */
7405 /*********************************************/
7406
7407 #ifdef SIS315H
7408 #if 0
7409 static void
7410 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7411 {
7412 unsigned short temp, temp1, temp2;
7413
7414 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7415 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7416 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7417 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7418 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7419 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7420 temp = (unsigned short)((int)(temp) + shift);
7421 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7422 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7423 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7424 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7425 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7426 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7427 }
7428 #endif
7429
7430 static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7431 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7432 {
7433 unsigned short temp, temp1;
7434 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7435
7436 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7437 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7438
7439 if(SiS_Pr->ChipType >= XGI_20) return;
7440
7441 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7442 if(!(ROMAddr[0x61] & 0x04)) return;
7443 }
7444
7445 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7446 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7447 if(!(temp & 0x01)) {
7448 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7449 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7450 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7451 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7452 }
7453 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7454 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7455 else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr625p)) temp = 0x0002;
7456 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7457 else temp = 0x0402;
7458 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7459 temp1 = 0;
7460 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7461 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7462 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7463 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7464 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7465 if(ModeNo > 0x13) {
7466 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7467 }
7468 } else {
7469 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7470 if(temp1 == 0x01) temp |= 0x01;
7471 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7472 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7473 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7474 if(ModeNo > 0x13) {
7475 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7476 }
7477 }
7478
7479 #if 0
7480 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7481 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7482 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7483 if(resinfo == SIS_RI_1024x768) {
7484 SiS_ShiftXPos(SiS_Pr, 97);
7485 } else {
7486 SiS_ShiftXPos(SiS_Pr, 111);
7487 }
7488 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7489 SiS_ShiftXPos(SiS_Pr, 136);
7490 }
7491 }
7492 }
7493 #endif
7494
7495 }
7496
7497 }
7498 #endif
7499
7500 static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7501 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7502 unsigned short RefreshRateTableIndex)
7503 {
7504 unsigned short vclkindex, temp, reg1, reg2;
7505
7506 if(SiS_Pr->UseCustomMode) {
7507 reg1 = SiS_Pr->CSR2B;
7508 reg2 = SiS_Pr->CSR2C;
7509 } else {
7510 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7511 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7512 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7513 }
7514
7515 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7516 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7517 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7518 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7519 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7520 } else {
7521 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7522 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7523 }
7524 } else {
7525 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7526 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7527 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7528 }
7529 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7530 temp = 0x08;
7531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7532 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7533 }
7534
7535 static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7536 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7537 {
7538 if(SiS_Pr->ChipType >= SIS_315H) {
7539 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7540 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7541 (SiS_IsVAMode(SiS_Pr))) {
7542 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7543 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7544 } else {
7545 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7546 }
7547 }
7548 }
7549 }
7550 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7551 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7552 #ifdef SET_EMI
7553 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7554 #endif
7555 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7556 }
7557 }
7558
7559 static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7560 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7561 unsigned short RefreshRateTableIndex)
7562 {
7563 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7564 unsigned int tempebx, tempeax, templong;
7565
7566 if(ModeNo <= 0x13) {
7567 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7568 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7569 } else if(SiS_Pr->UseCustomMode) {
7570 modeflag = SiS_Pr->CModeFlag;
7571 resinfo = 0;
7572 } else {
7573 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7574 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7575 }
7576
7577 if(SiS_Pr->ChipType >= SIS_315H) {
7578 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7580 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7581 }
7582 }
7583 }
7584
7585 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7586 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7587 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7588 }
7589 }
7590
7591 if(SiS_Pr->ChipType >= SIS_315H) {
7592 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7593 SiS_SetDualLinkEtc(SiS_Pr);
7594 return;
7595 }
7596 }
7597
7598 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7599
7600 tempbx = SiS_Pr->SiS_RVBHCMAX;
7601 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7602
7603 temp = (tempbx >> 1) & 0x80;
7604
7605 tempcx = SiS_Pr->SiS_VGAHT - 1;
7606 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7607
7608 temp |= ((tempcx >> 5) & 0x78);
7609
7610 tempcx = SiS_Pr->SiS_VGAVT - 1;
7611 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7612 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7613
7614 temp |= ((tempcx >> 8) & 0x07);
7615 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7616
7617 tempbx = SiS_Pr->SiS_VGAHDE;
7618 if(modeflag & HalfDCLK) tempbx >>= 1;
7619 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7620
7621 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7622 temp = 0;
7623 if(tempbx > 800) temp = 0x60;
7624 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7625 temp = 0;
7626 if(tempbx > 1024) temp = 0xC0;
7627 else if(tempbx >= 960) temp = 0xA0;
7628 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) {
7629 temp = 0;
7630 if(tempbx >= 1280) temp = 0x40;
7631 else if(tempbx >= 1024) temp = 0x20;
7632 } else {
7633 temp = 0x80;
7634 if(tempbx >= 1024) temp = 0xA0;
7635 }
7636
7637 temp |= SiS_Pr->Init_P4_0E;
7638
7639 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7640 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7641 temp &= 0xf0;
7642 temp |= 0x0A;
7643 }
7644 }
7645
7646 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7647
7648 tempeax = SiS_Pr->SiS_VGAVDE;
7649 tempebx = SiS_Pr->SiS_VDE;
7650 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7651 if(!(temp & 0xE0)) tempebx >>= 1;
7652 }
7653
7654 tempcx = SiS_Pr->SiS_RVBHRS;
7655 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7656 tempcx >>= 8;
7657 tempcx |= 0x40;
7658
7659 if(tempeax <= tempebx) {
7660 tempcx ^= 0x40;
7661 } else {
7662 tempeax -= tempebx;
7663 }
7664
7665 tempeax *= (256 * 1024);
7666 templong = tempeax % tempebx;
7667 tempeax /= tempebx;
7668 if(templong) tempeax++;
7669
7670 temp = (unsigned short)(tempeax & 0x000000FF);
7671 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7672 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7673 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7674 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7675 temp |= (tempcx & 0x4F);
7676 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7677
7678 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7679
7680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7681
7682 /* Calc Linebuffer max address and set/clear decimode */
7683 tempbx = 0;
7684 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7685 tempax = SiS_Pr->SiS_VGAHDE;
7686 if(modeflag & HalfDCLK) tempax >>= 1;
7687 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7688 if(tempax > 800) {
7689 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7690 tempax -= 800;
7691 } else {
7692 tempbx = 0x08;
7693 if(tempax == 960) tempax *= 25; /* Correct */
7694 else if(tempax == 1024) tempax *= 25;
7695 else tempax *= 20;
7696 temp = tempax % 32;
7697 tempax /= 32;
7698 if(temp) tempax++;
7699 tempax++;
7700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7701 if(resinfo == SIS_RI_1024x768 ||
7702 resinfo == SIS_RI_1024x576 ||
7703 resinfo == SIS_RI_1280x1024 ||
7704 resinfo == SIS_RI_1280x720) {
7705 /* Otherwise white line or garbage at right edge */
7706 tempax = (tempax & 0xff00) | 0x20;
7707 } else if(resinfo == SIS_RI_960x540) {
7708 tempax = (tempax & 0xff00) | 0xed;
7709 }
7710 }
7711 }
7712 }
7713 tempax--;
7714 temp = ((tempax >> 4) & 0x30) | tempbx;
7715 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7716 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7717
7718 temp = 0x0036; tempbx = 0xD0;
7719 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7720 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7721 }
7722 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7723 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 |
7724 TVSetHiVision |
7725 TVSetYPbPrProg))) {
7726 temp |= 0x01;
7727 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7728 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7729 temp &= ~0x01;
7730 }
7731 }
7732 }
7733 }
7734 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7735
7736 tempbx = SiS_Pr->SiS_HT >> 1;
7737 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7738 tempbx -= 2;
7739 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7740 temp = (tempbx >> 5) & 0x38;
7741 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7742
7743 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7744 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7745 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7746 /* LCD-too-dark-error-source, see FinalizeLCD() */
7747 }
7748 }
7749
7750 SiS_SetDualLinkEtc(SiS_Pr);
7751
7752 } /* 301B */
7753
7754 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7755 }
7756
7757 /*********************************************/
7758 /* SET PART 5 REGISTER GROUP */
7759 /*********************************************/
7760
7761 static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7762 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7763 {
7764
7765 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7766
7767 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7768 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7769 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7770 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7771 }
7772 }
7773 }
7774
7775 /*********************************************/
7776 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7777 /*********************************************/
7778
7779 static BOOLEAN
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7780 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7781 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7782 unsigned short *DisplayType)
7783 {
7784 unsigned short modeflag = 0;
7785 BOOLEAN checkhd = TRUE;
7786
7787 /* Pass 1:1 not supported here */
7788
7789 if(ModeNo <= 0x13) {
7790 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7791 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7792 } else {
7793 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7794 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7795 }
7796
7797 (*ResIndex) &= 0x3F;
7798
7799 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7800
7801 (*DisplayType) = 80;
7802 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7803 (*DisplayType) = 82;
7804 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7805 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7806 }
7807 }
7808 if((*DisplayType) != 84) {
7809 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7810 }
7811
7812 } else {
7813
7814 (*DisplayType = 0);
7815 switch(SiS_Pr->SiS_LCDResInfo) {
7816 case Panel_320x240_1: (*DisplayType) = 50;
7817 checkhd = FALSE;
7818 break;
7819 case Panel_320x240_2: (*DisplayType) = 14;
7820 break;
7821 case Panel_320x240_3: (*DisplayType) = 18;
7822 break;
7823 case Panel_640x480: (*DisplayType) = 10;
7824 break;
7825 case Panel_1024x600: (*DisplayType) = 26;
7826 break;
7827 default: return TRUE;
7828 }
7829
7830 if(checkhd) {
7831 if(modeflag & HalfDCLK) (*DisplayType)++;
7832 }
7833
7834 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7835 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7836 }
7837
7838 }
7839
7840 return TRUE;
7841 }
7842
7843 static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7844 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7845 unsigned short RefreshRateTableIndex)
7846 {
7847 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7848 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr = NULL;
7849 static const unsigned short CRIdx[] = {
7850 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7851 0x07, 0x10, 0x11, 0x15, 0x16
7852 };
7853
7854 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7855 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7856 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7857 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7858 return;
7859
7860 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7861 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7862 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7863 }
7864 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7865 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7866 } else return;
7867
7868 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7869
7870 if(SiS_Pr->ChipType < SIS_315H) {
7871 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7872 }
7873
7874 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7875 &ResIndex, &DisplayType))) {
7876 return;
7877 }
7878
7879 switch(DisplayType) {
7880 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7881 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7882 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7883 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7884 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7885 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7886 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7887 #if 0 /* Works better with calculated numbers */
7888 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7889 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7890 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7891 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7892 #endif
7893 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7894 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7895 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7896 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7897 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7898 }
7899
7900 if(LVDSCRT1Ptr) {
7901
7902 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7903
7904 for(i = 0; i <= 10; i++) {
7905 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7906 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7907 }
7908
7909 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7910 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7911 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7912 }
7913
7914 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7915 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7916
7917 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7918 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7919
7920 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7921 if(modeflag & DoubleScanMode) tempah |= 0x80;
7922 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7923
7924 } else {
7925
7926 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7927
7928 }
7929 }
7930
7931 /*********************************************/
7932 /* SET CRT2 ECLK */
7933 /*********************************************/
7934
7935 static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7936 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7937 unsigned short RefreshRateTableIndex)
7938 {
7939 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7940 unsigned short clkbase, vclkindex = 0;
7941 unsigned char sr2b, sr2c;
7942
7943 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7944 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7945 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7946 RefreshRateTableIndex--;
7947 }
7948 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7949 RefreshRateTableIndex);
7950 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7951 } else {
7952 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7953 RefreshRateTableIndex);
7954 }
7955
7956 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7957 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7958
7959 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7960 if(SiS_Pr->SiS_UseROM) {
7961 if(ROMAddr[0x220] & 0x01) {
7962 sr2b = ROMAddr[0x227];
7963 sr2c = ROMAddr[0x228];
7964 }
7965 }
7966 }
7967
7968 clkbase = 0x02B;
7969 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7970 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7971 clkbase += 3;
7972 }
7973 }
7974
7975 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7976 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7977 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7978 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7979 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7980 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7981 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7982 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7983 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7984 }
7985
7986 /*********************************************/
7987 /* SET UP CHRONTEL CHIPS */
7988 /*********************************************/
7989
7990 static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7991 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7992 unsigned short RefreshRateTableIndex)
7993 {
7994 unsigned short TVType, resindex;
7995 const struct SiS_CHTVRegData *CHTVRegData = NULL;
7996
7997 if(ModeNo <= 0x13)
7998 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7999 else
8000 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8001
8002 resindex &= 0x3F;
8003
8004 TVType = 0;
8005 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8006 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8007 TVType += 2;
8008 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8009 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8010 }
8011 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8012 TVType = 4;
8013 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8014 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8015 TVType = 6;
8016 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8017 }
8018 }
8019
8020 switch(TVType) {
8021 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8022 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8023 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8024 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8025 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8026 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8027 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8028 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8029 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8030 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8031 }
8032
8033
8034 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8035
8036 #ifdef SIS300
8037
8038 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8039
8040 /* We don't support modes >800x600 */
8041 if (resindex > 5) return;
8042
8043 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8044 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8045 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8046 } else {
8047 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8048 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8049 }
8050
8051 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8052 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8053 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8054 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8055 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8056
8057 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8058 minimum text enhancement (S3-2=10),
8059 maximum flicker filter for Chroma channel (S5-4=10)
8060 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8061 */
8062 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8063
8064 /* Set video bandwidth
8065 High bandwith Luma composite video filter(S0=1)
8066 low bandwith Luma S-video filter (S2-1=00)
8067 disable peak filter in S-video channel (S3=0)
8068 high bandwidth Chroma Filter (S5-4=11)
8069 =00110001=0x31
8070 */
8071 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8072
8073 /* Register 0x3D does not exist in non-macrovision register map
8074 (Maybe this is a macrovision register?)
8075 */
8076 #ifndef SIS_CP
8077 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8078 #endif
8079
8080 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8081 all other bits a read-only. Macrovision?
8082 */
8083 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8084
8085 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8086 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8087 */
8088 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8089
8090 /* Clear DSEN
8091 */
8092 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8093
8094 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8095 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8096 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8097 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8098 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8099 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8100 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8101 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8102 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8103 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8104 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8105 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8106 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8107 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8108 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8109 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8110 }
8111 } else {
8112 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8113 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8114 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8115 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8116 #if 0
8117 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8118 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8119 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8120 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8121 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8122 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8123 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8124 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8125 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8126 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8127 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8128 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8129 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8130 }
8131 }
8132 } else { /* ---- PAL ---- */
8133 /* We don't play around with FSCI in PAL mode */
8134 if(resindex == 0x04) {
8135 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8136 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8137 } else {
8138 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8139 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8140 }
8141 }
8142
8143 #endif /* 300 */
8144
8145 } else {
8146
8147 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8148
8149 #ifdef SIS315H
8150
8151 unsigned short temp;
8152
8153 /* We don't support modes >1024x768 */
8154 if (resindex > 6) return;
8155
8156 temp = CHTVRegData[resindex].Reg[0];
8157 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8158 SiS_SetCH701x(SiS_Pr,0x00,temp);
8159
8160 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8161 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8162 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8163 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8164 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8165 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8166
8167 temp = CHTVRegData[resindex].Reg[7];
8168 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8169 SiS_SetCH701x(SiS_Pr,0x07,temp);
8170
8171 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8172 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8173 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8174 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8175 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8176 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8177 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8178 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8179
8180 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8181 /* D1 should be set for PAL, PAL-N and NTSC-J,
8182 but I won't do that for PAL unless somebody
8183 tells me to do so. Since the BIOS uses
8184 non-default CIV values and blacklevels,
8185 this might be compensated anyway.
8186 */
8187 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8188 SiS_SetCH701x(SiS_Pr,0x21,temp);
8189
8190 #endif /* 315 */
8191
8192 }
8193
8194 #ifdef SIS_CP
8195 SIS_CP_INIT301_CP3
8196 #endif
8197
8198 }
8199
8200 #ifdef SIS315H /* ----------- 315 series only ---------- */
8201
8202 void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8203 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8204 {
8205 unsigned short temp;
8206
8207 /* Enable Chrontel 7019 LCD panel backlight */
8208 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8209 if(SiS_Pr->ChipType == SIS_740) {
8210 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8211 } else {
8212 temp = SiS_GetCH701x(SiS_Pr,0x66);
8213 temp |= 0x20;
8214 SiS_SetCH701x(SiS_Pr,0x66,temp);
8215 }
8216 }
8217 }
8218
8219 void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8220 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8221 {
8222 unsigned short temp;
8223
8224 /* Disable Chrontel 7019 LCD panel backlight */
8225 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8226 temp = SiS_GetCH701x(SiS_Pr,0x66);
8227 temp &= 0xDF;
8228 SiS_SetCH701x(SiS_Pr,0x66,temp);
8229 }
8230 }
8231
8232 static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8233 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8234 {
8235 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8236 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8237 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8238 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8239 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8240 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8241 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8242 const unsigned char *tableptr = NULL;
8243 int i;
8244
8245 /* Set up Power up/down timing */
8246
8247 if(SiS_Pr->ChipType == SIS_740) {
8248 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8249 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8250 else tableptr = table1024_740;
8251 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8252 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8253 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8254 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8255 else tableptr = table1400_740;
8256 } else return;
8257 } else {
8258 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8259 tableptr = table1024_650;
8260 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8261 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8262 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8263 tableptr = table1400_650;
8264 } else return;
8265 }
8266
8267 for(i=0; i<5; i++) {
8268 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8269 }
8270 }
8271
8272 static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8273 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8274 {
8275 const unsigned char *tableptr = NULL;
8276 unsigned short tempbh;
8277 int i;
8278 static const unsigned char regtable[] = {
8279 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8280 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8281 };
8282 static const unsigned char table1024_740[] = {
8283 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8284 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8285 };
8286 static const unsigned char table1280_740[] = {
8287 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8288 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8289 };
8290 static const unsigned char table1400_740[] = {
8291 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8292 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8293 };
8294 static const unsigned char table1600_740[] = {
8295 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8296 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8297 };
8298 static const unsigned char table1024_650[] = {
8299 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8300 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8301 };
8302 static const unsigned char table1280_650[] = {
8303 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8304 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8305 };
8306 static const unsigned char table1400_650[] = {
8307 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8308 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8309 };
8310 static const unsigned char table1600_650[] = {
8311 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8312 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8313 };
8314
8315 if(SiS_Pr->ChipType == SIS_740) {
8316 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8317 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8318 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8319 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8320 else return;
8321 } else {
8322 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8323 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8324 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8325 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8326 else return;
8327 }
8328
8329 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8330 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8331 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8332 if(tempbh == 0xc8) {
8333 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8334 } else if(tempbh == 0xdb) {
8335 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8336 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8337 } else if(tempbh == 0xde) {
8338 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8339 }
8340 }
8341
8342 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8343 else tempbh = 0x0c;
8344
8345 for(i = 0; i < tempbh; i++) {
8346 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8347 }
8348 SiS_ChrontelPowerSequencing(SiS_Pr);
8349 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8350 tempbh |= 0xc0;
8351 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8352
8353 if(SiS_Pr->ChipType == SIS_740) {
8354 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8355 tempbh &= 0xfb;
8356 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8357 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8358 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8359 tempbh |= 0x40;
8360 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8361 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8362 tempbh &= 0x3f;
8363 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8364 }
8365 }
8366
8367 static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8368 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8369 {
8370 unsigned char temp, temp1;
8371
8372 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8373 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8374 temp = SiS_GetCH701x(SiS_Pr,0x47);
8375 temp &= 0x7f; /* Use external VSYNC */
8376 SiS_SetCH701x(SiS_Pr,0x47,temp);
8377 SiS_LongDelay(SiS_Pr, 3);
8378 temp = SiS_GetCH701x(SiS_Pr,0x47);
8379 temp |= 0x80; /* Use internal VSYNC */
8380 SiS_SetCH701x(SiS_Pr,0x47,temp);
8381 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8382 }
8383
8384 static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8385 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8386 {
8387 unsigned short temp;
8388
8389 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8390 if(SiS_Pr->ChipType == SIS_740) {
8391 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8392 temp |= 0x04; /* Invert XCLK phase */
8393 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8394 }
8395 if(SiS_IsYPbPr(SiS_Pr)) {
8396 temp = SiS_GetCH701x(SiS_Pr,0x01);
8397 temp &= 0x3f;
8398 temp |= 0x80; /* Enable YPrPb (HDTV) */
8399 SiS_SetCH701x(SiS_Pr,0x01,temp);
8400 }
8401 if(SiS_IsChScart(SiS_Pr)) {
8402 temp = SiS_GetCH701x(SiS_Pr,0x01);
8403 temp &= 0x3f;
8404 temp |= 0xc0; /* Enable SCART + CVBS */
8405 SiS_SetCH701x(SiS_Pr,0x01,temp);
8406 }
8407 if(SiS_Pr->ChipType == SIS_740) {
8408 SiS_ChrontelResetVSync(SiS_Pr);
8409 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8410 } else {
8411 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8412 temp = SiS_GetCH701x(SiS_Pr,0x49);
8413 if(SiS_IsYPbPr(SiS_Pr)) {
8414 temp = SiS_GetCH701x(SiS_Pr,0x73);
8415 temp |= 0x60;
8416 SiS_SetCH701x(SiS_Pr,0x73,temp);
8417 }
8418 temp = SiS_GetCH701x(SiS_Pr,0x47);
8419 temp &= 0x7f;
8420 SiS_SetCH701x(SiS_Pr,0x47,temp);
8421 SiS_LongDelay(SiS_Pr, 2);
8422 temp = SiS_GetCH701x(SiS_Pr,0x47);
8423 temp |= 0x80;
8424 SiS_SetCH701x(SiS_Pr,0x47,temp);
8425 }
8426 }
8427 }
8428
8429 static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8430 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8431 {
8432 unsigned short temp;
8433
8434 /* Complete power down of LVDS */
8435 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8436 if(SiS_Pr->ChipType == SIS_740) {
8437 SiS_LongDelay(SiS_Pr, 1);
8438 SiS_GenericDelay(SiS_Pr, 5887);
8439 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8440 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8441 } else {
8442 SiS_LongDelay(SiS_Pr, 2);
8443 temp = SiS_GetCH701x(SiS_Pr,0x76);
8444 temp &= 0xfc;
8445 SiS_SetCH701x(SiS_Pr,0x76,temp);
8446 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8447 }
8448 }
8449 }
8450
8451 static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8452 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8453 {
8454 unsigned short temp;
8455
8456 if(SiS_Pr->ChipType == SIS_740) {
8457
8458 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8459 temp &= 0x01;
8460 if(!temp) {
8461
8462 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8463 temp = SiS_GetCH701x(SiS_Pr,0x49);
8464 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8465 }
8466
8467 /* Reset Chrontel 7019 datapath */
8468 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8469 SiS_LongDelay(SiS_Pr, 1);
8470 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8471
8472 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8473 SiS_ChrontelResetVSync(SiS_Pr);
8474 SiS_SetCH701x(SiS_Pr,0x49,temp);
8475 }
8476
8477 } else {
8478
8479 /* Clear/set/clear GPIO */
8480 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8481 temp &= 0xef;
8482 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8483 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8484 temp |= 0x10;
8485 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8486 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8487 temp &= 0xef;
8488 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8489 temp = SiS_GetCH701x(SiS_Pr,0x61);
8490 if(!temp) {
8491 SiS_SetCH701xForLCD(SiS_Pr);
8492 }
8493 }
8494
8495 } else { /* 650 */
8496 /* Reset Chrontel 7019 datapath */
8497 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8498 SiS_LongDelay(SiS_Pr, 1);
8499 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8500 }
8501 }
8502
8503 static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8504 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8505 {
8506 unsigned short temp;
8507
8508 if(SiS_Pr->ChipType == SIS_740) {
8509
8510 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8511 SiS_ChrontelResetVSync(SiS_Pr);
8512 }
8513
8514 } else {
8515
8516 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8517 temp = SiS_GetCH701x(SiS_Pr,0x49);
8518 temp &= 1;
8519 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8520 temp = SiS_GetCH701x(SiS_Pr,0x47);
8521 temp &= 0x70;
8522 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8523 SiS_LongDelay(SiS_Pr, 3);
8524 temp = SiS_GetCH701x(SiS_Pr,0x47);
8525 temp |= 0x80;
8526 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8527 }
8528
8529 }
8530 }
8531
8532 static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8533 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8534 {
8535 unsigned short temp,temp1;
8536
8537 if(SiS_Pr->ChipType == SIS_740) {
8538
8539 temp = SiS_GetCH701x(SiS_Pr,0x61);
8540 if(temp < 1) {
8541 temp++;
8542 SiS_SetCH701x(SiS_Pr,0x61,temp);
8543 }
8544 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8545 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8546 SiS_LongDelay(SiS_Pr, 1);
8547 SiS_GenericDelay(SiS_Pr, 5887);
8548
8549 } else { /* 650 */
8550
8551 temp1 = 0;
8552 temp = SiS_GetCH701x(SiS_Pr,0x61);
8553 if(temp < 2) {
8554 temp++;
8555 SiS_SetCH701x(SiS_Pr,0x61,temp);
8556 temp1 = 1;
8557 }
8558 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8559 temp = SiS_GetCH701x(SiS_Pr,0x66);
8560 temp |= 0x5f;
8561 SiS_SetCH701x(SiS_Pr,0x66,temp);
8562 if(ModeNo > 0x13) {
8563 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8564 SiS_GenericDelay(SiS_Pr, 1023);
8565 } else {
8566 SiS_GenericDelay(SiS_Pr, 767);
8567 }
8568 } else {
8569 if(!temp1)
8570 SiS_GenericDelay(SiS_Pr, 767);
8571 }
8572 temp = SiS_GetCH701x(SiS_Pr,0x76);
8573 temp |= 0x03;
8574 SiS_SetCH701x(SiS_Pr,0x76,temp);
8575 temp = SiS_GetCH701x(SiS_Pr,0x66);
8576 temp &= 0x7f;
8577 SiS_SetCH701x(SiS_Pr,0x66,temp);
8578 SiS_LongDelay(SiS_Pr, 1);
8579
8580 }
8581 }
8582
8583 static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8584 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8585 {
8586 unsigned short temp,tempcl,tempch;
8587
8588 SiS_LongDelay(SiS_Pr, 1);
8589 tempcl = 3;
8590 tempch = 0;
8591
8592 do {
8593 temp = SiS_GetCH701x(SiS_Pr,0x66);
8594 temp &= 0x04; /* PLL stable? -> bail out */
8595 if(temp == 0x04) break;
8596
8597 if(SiS_Pr->ChipType == SIS_740) {
8598 /* Power down LVDS output, PLL normal operation */
8599 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8600 }
8601
8602 SiS_SetCH701xForLCD(SiS_Pr);
8603
8604 if(tempcl == 0) {
8605 if(tempch == 3) break;
8606 SiS_ChrontelResetDB(SiS_Pr);
8607 tempcl = 3;
8608 tempch++;
8609 }
8610 tempcl--;
8611 temp = SiS_GetCH701x(SiS_Pr,0x76);
8612 temp &= 0xfb; /* Reset PLL */
8613 SiS_SetCH701x(SiS_Pr,0x76,temp);
8614 SiS_LongDelay(SiS_Pr, 2);
8615 temp = SiS_GetCH701x(SiS_Pr,0x76);
8616 temp |= 0x04; /* PLL normal operation */
8617 SiS_SetCH701x(SiS_Pr,0x76,temp);
8618 if(SiS_Pr->ChipType == SIS_740) {
8619 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8620 } else {
8621 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8622 }
8623 SiS_LongDelay(SiS_Pr, 2);
8624 } while(0);
8625
8626 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8627 }
8628
8629 static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8630 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8631 {
8632 unsigned short temp;
8633
8634 temp = SiS_GetCH701x(SiS_Pr,0x03);
8635 temp |= 0x80; /* Set datapath 1 to TV */
8636 temp &= 0xbf; /* Set datapath 2 to LVDS */
8637 SiS_SetCH701x(SiS_Pr,0x03,temp);
8638
8639 if(SiS_Pr->ChipType == SIS_740) {
8640
8641 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8642 temp &= 0xfb; /* Normal XCLK phase */
8643 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8644
8645 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8646
8647 temp = SiS_GetCH701x(SiS_Pr,0x64);
8648 temp |= 0x40; /* ? Bit not defined */
8649 SiS_SetCH701x(SiS_Pr,0x64,temp);
8650
8651 temp = SiS_GetCH701x(SiS_Pr,0x03);
8652 temp &= 0x3f; /* D1 input to both LVDS and TV */
8653 SiS_SetCH701x(SiS_Pr,0x03,temp);
8654
8655 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8656 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8657 SiS_LongDelay(SiS_Pr, 1);
8658 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8659 SiS_ChrontelResetDB(SiS_Pr);
8660 SiS_ChrontelDoSomething2(SiS_Pr);
8661 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8662 } else {
8663 temp = SiS_GetCH701x(SiS_Pr,0x66);
8664 if(temp != 0x45) {
8665 SiS_ChrontelResetDB(SiS_Pr);
8666 SiS_ChrontelDoSomething2(SiS_Pr);
8667 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8668 }
8669 }
8670
8671 } else { /* 650 */
8672
8673 SiS_ChrontelResetDB(SiS_Pr);
8674 SiS_ChrontelDoSomething2(SiS_Pr);
8675 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8676 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8677 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8678
8679 }
8680
8681 }
8682 #endif /* 315 series */
8683
8684 /*********************************************/
8685 /* MAIN: SET CRT2 REGISTER GROUP */
8686 /*********************************************/
8687
8688 BOOLEAN
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8689 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8690 {
8691 #ifdef SIS300
8692 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8693 #endif
8694 unsigned short ModeIdIndex, RefreshRateTableIndex;
8695
8696 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8697
8698 if(!SiS_Pr->UseCustomMode) {
8699 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8700 } else {
8701 ModeIdIndex = 0;
8702 }
8703
8704 /* Used for shifting CR33 */
8705 SiS_Pr->SiS_SelectCRT2Rate = 4;
8706
8707 SiS_UnLockCRT2(SiS_Pr);
8708
8709 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8710
8711 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8712
8713 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8714 SiS_DisableBridge(SiS_Pr);
8715 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8716 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8717 }
8718 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8719 }
8720
8721 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8722 SiS_LockCRT2(SiS_Pr);
8723 SiS_DisplayOn(SiS_Pr);
8724 return TRUE;
8725 }
8726
8727 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8728
8729 /* Set up Panel Link for LVDS and LCDA */
8730 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8731 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8732 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8733 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8734 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8735 }
8736
8737 #ifdef SIS_XORG_XF86
8738 #ifdef TWDEBUG
8739 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8740 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8741 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8742 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8743 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8744 #endif
8745 #endif
8746
8747 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8748 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8749 }
8750
8751 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8752
8753 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8754
8755 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8756 #ifdef SIS315H
8757 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8758 #endif
8759 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8760 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8761 #ifdef SIS315H
8762 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8763 #endif
8764 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8765
8766 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8767
8768 /* For 301BDH (Panel link initialization): */
8769 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8770
8771 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8772 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8773 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8774 }
8775 }
8776 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8777 }
8778 }
8779
8780 } else {
8781
8782 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8783
8784 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8785
8786 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8787
8788 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8789 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8790 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8791 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8792 #ifdef SIS315H
8793 SiS_SetCH701xForLCD(SiS_Pr);
8794 #endif
8795 }
8796 }
8797 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8798 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8799 }
8800 }
8801 }
8802
8803 }
8804
8805 #ifdef SIS300
8806 if(SiS_Pr->ChipType < SIS_315H) {
8807 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8808 if(SiS_Pr->SiS_UseOEM) {
8809 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8810 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8811 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8812 }
8813 } else {
8814 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8815 }
8816 }
8817 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8818 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8819 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8820 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8821 }
8822 SiS_DisplayOn(SiS_Pr);
8823 }
8824 }
8825 }
8826 #endif
8827
8828 #ifdef SIS315H
8829 if(SiS_Pr->ChipType >= SIS_315H) {
8830 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8831 if(SiS_Pr->ChipType < SIS_661) {
8832 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8833 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8834 } else {
8835 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8836 }
8837 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8838 }
8839 }
8840 #endif
8841
8842 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8843 SiS_EnableBridge(SiS_Pr);
8844 }
8845
8846 SiS_DisplayOn(SiS_Pr);
8847
8848 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8850 /* Disable LCD panel when using TV */
8851 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8852 } else {
8853 /* Disable TV when using LCD */
8854 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8855 }
8856 }
8857
8858 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8859 SiS_LockCRT2(SiS_Pr);
8860 }
8861
8862 return TRUE;
8863 }
8864
8865
8866 /*********************************************/
8867 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8868 /*********************************************/
8869
8870 void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)8871 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
8872 {
8873 /* Switch on LCD backlight on SiS30xLV */
8874 SiS_DDC2Delay(SiS_Pr,0xff00);
8875 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8876 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8877 SiS_WaitVBRetrace(SiS_Pr);
8878 }
8879 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8880 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8881 }
8882 }
8883
8884 void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)8885 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
8886 {
8887 /* Switch off LCD backlight on SiS30xLV */
8888 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8889 SiS_DDC2Delay(SiS_Pr,0xff00);
8890 }
8891
8892 /*********************************************/
8893 /* DDC RELATED FUNCTIONS */
8894 /*********************************************/
8895
8896 static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)8897 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
8898 {
8899 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8900 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8901 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8902 SiS_Pr->SiS_DDC_NData &= 0x0f;
8903 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8904 }
8905 }
8906
8907 #ifdef SIS300
8908 static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8909 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8910 {
8911 int i, j, num;
8912 unsigned short tempah,temp;
8913 unsigned char *mydataptr;
8914
8915 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8916 mydataptr = dataptr;
8917 num = *mydataptr++;
8918 if(!num) return mydataptr;
8919 if(i) {
8920 SiS_SetStop(SiS_Pr);
8921 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
8922 }
8923 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8924 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8925 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8926 if(temp) continue; /* (ERROR: no ack) */
8927 tempah = *mydataptr++;
8928 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8929 if(temp) continue; /* (ERROR: no ack) */
8930 for(j=0; j<num; j++) {
8931 tempah = *mydataptr++;
8932 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8933 if(temp) break;
8934 }
8935 if(temp) continue;
8936 if(SiS_SetStop(SiS_Pr)) continue;
8937 return mydataptr;
8938 }
8939 return NULL;
8940 }
8941
8942 static BOOLEAN
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)8943 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
8944 {
8945 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8946 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8947 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8948 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8949 SiS_SetupDDCN(SiS_Pr);
8950
8951 SiS_SetSwitchDDC2(SiS_Pr);
8952
8953 while(*dataptr) {
8954 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8955 if(!dataptr) return FALSE;
8956 }
8957 #ifdef SIS_XORG_XF86
8958 #ifdef TWDEBUG
8959 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8960 #endif
8961 #endif
8962 return TRUE;
8963 }
8964 #endif
8965
8966 /* The Chrontel 700x is connected to the 630/730 via
8967 * the 630/730's DDC/I2C port.
8968 *
8969 * On 630(S)T chipset, the index changed from 0x11 to
8970 * 0x0a, possibly for working around the DDC problems
8971 */
8972
8973 static BOOLEAN
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)8974 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
8975 {
8976 unsigned short temp, i;
8977
8978 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8979 if(i) {
8980 SiS_SetStop(SiS_Pr);
8981 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
8982 }
8983 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8984 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
8985 if(temp) continue; /* (ERROR: no ack) */
8986 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
8987 if(temp) continue; /* (ERROR: no ack) */
8988 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
8989 if(temp) continue; /* (ERROR: no ack) */
8990 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8991 SiS_Pr->SiS_ChrontelInit = 1;
8992 return TRUE;
8993 }
8994 return FALSE;
8995 }
8996
8997 /* Write to Chrontel 700x */
8998 void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)8999 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9000 {
9001 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9002
9003 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9004
9005 if(!(SiS_Pr->SiS_ChrontelInit)) {
9006 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9007 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9008 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9009 SiS_SetupDDCN(SiS_Pr);
9010 }
9011
9012 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9013 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9014 SiS_Pr->SiS_DDC_Index = 0x0a;
9015 SiS_Pr->SiS_DDC_Data = 0x80;
9016 SiS_Pr->SiS_DDC_Clk = 0x40;
9017 SiS_SetupDDCN(SiS_Pr);
9018
9019 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9020 }
9021 }
9022
9023 /* Write to Chrontel 701x */
9024 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9025 void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9026 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9027 {
9028 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9029 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9030 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9031 SiS_SetupDDCN(SiS_Pr);
9032 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9033 SiS_SetChReg(SiS_Pr, reg, val, 0);
9034 }
9035
9036 #ifdef SIS_LINUX_KERNEL
9037 static
9038 #endif
9039 void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9040 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9041 {
9042 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9043 SiS_SetCH700x(SiS_Pr, reg, val);
9044 else
9045 SiS_SetCH701x(SiS_Pr, reg, val);
9046 }
9047
9048 static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)9049 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9050 {
9051 unsigned short tempah, temp, i;
9052
9053 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9054 if(i) {
9055 SiS_SetStop(SiS_Pr);
9056 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9057 }
9058 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9059 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9060 if(temp) continue; /* (ERROR: no ack) */
9061 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9062 if(temp) continue; /* (ERROR: no ack) */
9063 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9064 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9065 if(temp) continue; /* (ERROR: no ack) */
9066 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9067 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9068 SiS_Pr->SiS_ChrontelInit = 1;
9069 return tempah;
9070 }
9071 return 0xFFFF;
9072 }
9073
9074 /* Read from Chrontel 700x */
9075 /* Parameter is [Register no (S7-S0)] */
9076 unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9077 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9078 {
9079 unsigned short result;
9080
9081 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9082
9083 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9084
9085 if(!(SiS_Pr->SiS_ChrontelInit)) {
9086 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9087 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9088 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9089 SiS_SetupDDCN(SiS_Pr);
9090 }
9091
9092 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9093
9094 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9095 (!SiS_Pr->SiS_ChrontelInit) ) {
9096
9097 SiS_Pr->SiS_DDC_Index = 0x0a;
9098 SiS_Pr->SiS_DDC_Data = 0x80;
9099 SiS_Pr->SiS_DDC_Clk = 0x40;
9100 SiS_SetupDDCN(SiS_Pr);
9101
9102 result = SiS_GetChReg(SiS_Pr,0x80);
9103 }
9104 return result;
9105 }
9106
9107 /* Read from Chrontel 701x */
9108 /* Parameter is [Register no (S7-S0)] */
9109 unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9110 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9111 {
9112 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9113 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9114 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9115 SiS_SetupDDCN(SiS_Pr);
9116 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9117
9118 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9119
9120 return SiS_GetChReg(SiS_Pr,0);
9121 }
9122
9123 /* Read from Chrontel 70xx */
9124 /* Parameter is [Register no (S7-S0)] */
9125 #ifdef SIS_LINUX_KERNEL
9126 static
9127 #endif
9128 unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)9129 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9130 {
9131 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9132 return SiS_GetCH700x(SiS_Pr, tempbx);
9133 else
9134 return SiS_GetCH701x(SiS_Pr, tempbx);
9135 }
9136
9137 void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)9138 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9139 unsigned char myor, unsigned short myand)
9140 {
9141 unsigned short tempbl;
9142
9143 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9144 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9145 }
9146
9147 /* Our own DDC functions */
9148 #ifndef SIS_XORG_XF86
9149 static
9150 #endif
9151 unsigned short
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,BOOLEAN checkcr32,unsigned int VBFlags2)9152 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9153 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
9154 unsigned int VBFlags2)
9155 {
9156 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9157 unsigned char flag, cr32;
9158 unsigned short temp = 0, myadaptnum = adaptnum;
9159
9160 if(adaptnum != 0) {
9161 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9162 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9163 }
9164
9165 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9166
9167 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9168
9169 SiS_Pr->SiS_DDC_SecAddr = 0;
9170 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9171 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9172 SiS_Pr->SiS_DDC_Index = 0x11;
9173 flag = 0xff;
9174
9175 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9176
9177 #if 0
9178 if(VBFlags2 & VB2_SISBRIDGE) {
9179 if(myadaptnum == 0) {
9180 if(!(cr32 & 0x20)) {
9181 myadaptnum = 2;
9182 if(!(cr32 & 0x10)) {
9183 myadaptnum = 1;
9184 if(!(cr32 & 0x08)) {
9185 myadaptnum = 0;
9186 }
9187 }
9188 }
9189 }
9190 }
9191 #endif
9192
9193 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9194
9195 if(myadaptnum != 0) {
9196 flag = 0;
9197 if(VBFlags2 & VB2_SISBRIDGE) {
9198 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9199 SiS_Pr->SiS_DDC_Index = 0x0f;
9200 }
9201 }
9202
9203 if(!(VBFlags2 & VB2_301)) {
9204 if((cr32 & 0x80) && (checkcr32)) {
9205 if(myadaptnum >= 1) {
9206 if(!(cr32 & 0x08)) {
9207 myadaptnum = 1;
9208 if(!(cr32 & 0x10)) return 0xFFFF;
9209 }
9210 }
9211 }
9212 }
9213
9214 temp = 4 - (myadaptnum * 2);
9215 if(flag) temp = 0;
9216
9217 } else { /* 315/330 series */
9218
9219 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9220
9221 if(VBFlags2 & VB2_SISBRIDGE) {
9222 if(myadaptnum == 2) {
9223 myadaptnum = 1;
9224 }
9225 }
9226
9227 if(myadaptnum == 1) {
9228 flag = 0;
9229 if(VBFlags2 & VB2_SISBRIDGE) {
9230 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9231 SiS_Pr->SiS_DDC_Index = 0x0f;
9232 }
9233 }
9234
9235 if((cr32 & 0x80) && (checkcr32)) {
9236 if(myadaptnum >= 1) {
9237 if(!(cr32 & 0x08)) {
9238 myadaptnum = 1;
9239 if(!(cr32 & 0x10)) return 0xFFFF;
9240 }
9241 }
9242 }
9243
9244 temp = myadaptnum;
9245 if(myadaptnum == 1) {
9246 temp = 0;
9247 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9248 }
9249
9250 if(flag) temp = 0;
9251 }
9252
9253 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9254 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9255
9256 SiS_SetupDDCN(SiS_Pr);
9257
9258 #ifdef SIS_XORG_XF86
9259 #ifdef TWDEBUG
9260 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9261 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9262 #endif
9263 #endif
9264 return 0;
9265 }
9266
9267 static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9268 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9269 {
9270 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9271 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9272 return 0xFFFF;
9273 }
9274 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9275 return 0xFFFF;
9276 }
9277 return 0;
9278 }
9279
9280 static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9281 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9282 {
9283 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9284 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9285 return 0xFFFF;
9286 }
9287 return 0;
9288 }
9289
9290 static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9291 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9292 {
9293 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9294 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9295 return 0;
9296 }
9297
9298 static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9299 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9300 {
9301 SiS_SetSCLKLow(SiS_Pr);
9302 if(yesno) {
9303 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9304 SiS_Pr->SiS_DDC_Index,
9305 SiS_Pr->SiS_DDC_NData,
9306 SiS_Pr->SiS_DDC_Data);
9307 } else {
9308 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9309 SiS_Pr->SiS_DDC_Index,
9310 SiS_Pr->SiS_DDC_NData,
9311 0);
9312 }
9313 SiS_SetSCLKHigh(SiS_Pr);
9314 }
9315
9316 static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9317 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9318 {
9319 unsigned char mask, value;
9320 unsigned short temp, ret=0;
9321 BOOLEAN failed = FALSE;
9322
9323 SiS_SetSwitchDDC2(SiS_Pr);
9324 if(SiS_PrepareDDC(SiS_Pr)) {
9325 SiS_SetStop(SiS_Pr);
9326 #ifdef SIS_XORG_XF86
9327 #ifdef TWDEBUG
9328 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9329 #endif
9330 #endif
9331 return 0xFFFF;
9332 }
9333 mask = 0xf0;
9334 value = 0x20;
9335 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9336 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9337 SiS_SendACK(SiS_Pr, 0);
9338 if(temp == 0) {
9339 mask = 0xff;
9340 value = 0xff;
9341 } else {
9342 failed = TRUE;
9343 ret = 0xFFFF;
9344 #ifdef SIS_XORG_XF86
9345 #ifdef TWDEBUG
9346 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9347 #endif
9348 #endif
9349 }
9350 }
9351 if(failed == FALSE) {
9352 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9353 SiS_SendACK(SiS_Pr, 1);
9354 temp &= mask;
9355 if(temp == value) ret = 0;
9356 else {
9357 ret = 0xFFFF;
9358 #ifdef SIS_XORG_XF86
9359 #ifdef TWDEBUG
9360 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9361 #endif
9362 #endif
9363 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9364 if(temp == 0x30) ret = 0;
9365 }
9366 }
9367 }
9368 SiS_SetStop(SiS_Pr);
9369 return ret;
9370 }
9371
9372 #ifndef SIS_XORG_XF86
9373 static
9374 #endif
9375 unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9376 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9377 {
9378 unsigned short flag;
9379
9380 flag = 0x180;
9381 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9382 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9383 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9384 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9385 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9386 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9387 if(!(flag & 0x1a)) flag = 0;
9388 return flag;
9389 }
9390
9391 #ifndef SIS_XORG_XF86
9392 static
9393 #endif
9394 unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9395 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9396 {
9397 unsigned short flag, length, i;
9398 unsigned char chksum,gotcha;
9399
9400 if(DDCdatatype > 4) return 0xFFFF;
9401
9402 flag = 0;
9403 SiS_SetSwitchDDC2(SiS_Pr);
9404 if(!(SiS_PrepareDDC(SiS_Pr))) {
9405 length = 127;
9406 if(DDCdatatype != 1) length = 255;
9407 chksum = 0;
9408 gotcha = 0;
9409 for(i=0; i<length; i++) {
9410 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9411 chksum += buffer[i];
9412 gotcha |= buffer[i];
9413 SiS_SendACK(SiS_Pr, 0);
9414 }
9415 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9416 chksum += buffer[i];
9417 SiS_SendACK(SiS_Pr, 1);
9418 if(gotcha) flag = (unsigned short)chksum;
9419 else flag = 0xFFFF;
9420 } else {
9421 flag = 0xFFFF;
9422 }
9423 SiS_SetStop(SiS_Pr);
9424 return flag;
9425 }
9426
9427 /* Our private DDC functions
9428
9429 It complies somewhat with the corresponding VESA function
9430 in arguments and return values.
9431
9432 Since this is probably called before the mode is changed,
9433 we use our pre-detected pSiS-values instead of SiS_Pr as
9434 regards chipset and video bridge type.
9435
9436 Arguments:
9437 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9438 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9439 LCDA is CRT1, but DDC is read from CRT2 port.
9440 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9441 buffer: ptr to 256 data bytes which will be filled with read data.
9442
9443 Returns 0xFFFF if error, otherwise
9444 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9445 if DDCdatatype = 0: Returns supported DDC modes
9446
9447 */
9448 unsigned short
SiS_HandleDDC(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,unsigned char * buffer,unsigned int VBFlags2)9449 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9450 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9451 unsigned int VBFlags2)
9452 {
9453 unsigned char sr1f, cr17=1;
9454 unsigned short result;
9455
9456 if(adaptnum > 2)
9457 return 0xFFFF;
9458
9459 if(DDCdatatype > 4)
9460 return 0xFFFF;
9461
9462 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9463 return 0xFFFF;
9464
9465 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
9466 return 0xFFFF;
9467
9468 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9469 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9470 if(VGAEngine == SIS_300_VGA) {
9471 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9472 if(!cr17) {
9473 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9474 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9475 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9476 }
9477 }
9478 if((sr1f) || (!cr17)) {
9479 SiS_WaitRetrace1(SiS_Pr);
9480 SiS_WaitRetrace1(SiS_Pr);
9481 SiS_WaitRetrace1(SiS_Pr);
9482 SiS_WaitRetrace1(SiS_Pr);
9483 }
9484
9485 if(DDCdatatype == 0) {
9486 result = SiS_ProbeDDC(SiS_Pr);
9487 } else {
9488 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9489 if((!result) && (DDCdatatype == 1)) {
9490 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9491 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9492 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9493 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9494 (buffer[0x12] == 1)) {
9495 if(!SiS_Pr->DDCPortMixup) {
9496 if(adaptnum == 1) {
9497 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9498 } else {
9499 if(buffer[0x14] & 0x80) result = 0xFFFE;
9500 }
9501 }
9502 }
9503 }
9504 }
9505 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9506 if(VGAEngine == SIS_300_VGA) {
9507 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9508 }
9509 return result;
9510 }
9511
9512 /* Generic I2C functions for Chrontel & DDC --------- */
9513
9514 static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9515 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9516 {
9517 SiS_SetSCLKHigh(SiS_Pr);
9518 SiS_WaitRetrace1(SiS_Pr);
9519
9520 SiS_SetSCLKLow(SiS_Pr);
9521 SiS_WaitRetrace1(SiS_Pr);
9522 }
9523
9524 unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9525 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9526 {
9527 SiS_WaitRetrace1(SiS_Pr);
9528 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9529 }
9530
9531 /* Set I2C start condition */
9532 /* This is done by a SD high-to-low transition while SC is high */
9533 static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9534 SiS_SetStart(struct SiS_Private *SiS_Pr)
9535 {
9536 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9537 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9538 SiS_Pr->SiS_DDC_Index,
9539 SiS_Pr->SiS_DDC_NData,
9540 SiS_Pr->SiS_DDC_Data); /* SD->high */
9541 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9542 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9543 SiS_Pr->SiS_DDC_Index,
9544 SiS_Pr->SiS_DDC_NData,
9545 0x00); /* SD->low = start condition */
9546 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9547 return 0;
9548 }
9549
9550 /* Set I2C stop condition */
9551 /* This is done by a SD low-to-high transition while SC is high */
9552 static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9553 SiS_SetStop(struct SiS_Private *SiS_Pr)
9554 {
9555 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9556 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9557 SiS_Pr->SiS_DDC_Index,
9558 SiS_Pr->SiS_DDC_NData,
9559 0x00); /* SD->low */
9560 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9561 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9562 SiS_Pr->SiS_DDC_Index,
9563 SiS_Pr->SiS_DDC_NData,
9564 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9565 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9566 return 0;
9567 }
9568
9569 /* Write 8 bits of data */
9570 static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9571 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9572 {
9573 unsigned short i,flag,temp;
9574
9575 flag = 0x80;
9576 for(i = 0; i < 8; i++) {
9577 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9578 if(tempax & flag) {
9579 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9580 SiS_Pr->SiS_DDC_Index,
9581 SiS_Pr->SiS_DDC_NData,
9582 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9583 } else {
9584 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9585 SiS_Pr->SiS_DDC_Index,
9586 SiS_Pr->SiS_DDC_NData,
9587 0x00); /* Write bit (0) to SD */
9588 }
9589 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9590 flag >>= 1;
9591 }
9592 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9593 return temp;
9594 }
9595
9596 static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9597 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9598 {
9599 unsigned short i, temp, getdata;
9600
9601 getdata = 0;
9602 for(i = 0; i < 8; i++) {
9603 getdata <<= 1;
9604 SiS_SetSCLKLow(SiS_Pr);
9605 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9606 SiS_Pr->SiS_DDC_Index,
9607 SiS_Pr->SiS_DDC_NData,
9608 SiS_Pr->SiS_DDC_Data);
9609 SiS_SetSCLKHigh(SiS_Pr);
9610 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9611 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9612 }
9613 return getdata;
9614 }
9615
9616 static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9617 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9618 {
9619 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9620 SiS_Pr->SiS_DDC_Index,
9621 SiS_Pr->SiS_DDC_NClk,
9622 0x00); /* SetSCLKLow() */
9623 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9624 return 0;
9625 }
9626
9627 static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9628 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9629 {
9630 unsigned short temp, watchdog=1000;
9631
9632 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9633 SiS_Pr->SiS_DDC_Index,
9634 SiS_Pr->SiS_DDC_NClk,
9635 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9636 do {
9637 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9638 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9639 if (!watchdog) {
9640 #ifdef SIS_XORG_XF86
9641 #ifdef TWDEBUG
9642 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
9643 #endif
9644 #endif
9645 return 0xFFFF;
9646 }
9647 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9648 return 0;
9649 }
9650
9651 /* Check I2C acknowledge */
9652 /* Returns 0 if ack ok, non-0 if ack not ok */
9653 static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9654 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9655 {
9656 unsigned short tempah;
9657
9658 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9659 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9660 SiS_Pr->SiS_DDC_Index,
9661 SiS_Pr->SiS_DDC_NData,
9662 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9663 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9664 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9665 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9666 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9667 return 0;
9668 }
9669
9670 /* End of I2C functions ----------------------- */
9671
9672
9673 /* =============== SiS 315/330 O.E.M. ================= */
9674
9675 #ifdef SIS315H
9676
9677 static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9678 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9679 {
9680 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9681 unsigned short romptr;
9682
9683 if(SiS_Pr->ChipType < SIS_330) {
9684 romptr = SISGETROMW(0x128);
9685 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9686 romptr = SISGETROMW(0x12a);
9687 } else {
9688 romptr = SISGETROMW(0x1a8);
9689 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9690 romptr = SISGETROMW(0x1aa);
9691 }
9692 return romptr;
9693 }
9694
9695 static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9696 GetLCDromptr(struct SiS_Private *SiS_Pr)
9697 {
9698 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9699 unsigned short romptr;
9700
9701 if(SiS_Pr->ChipType < SIS_330) {
9702 romptr = SISGETROMW(0x120);
9703 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9704 romptr = SISGETROMW(0x122);
9705 } else {
9706 romptr = SISGETROMW(0x1a0);
9707 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9708 romptr = SISGETROMW(0x1a2);
9709 }
9710 return romptr;
9711 }
9712
9713 static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9714 GetTVromptr(struct SiS_Private *SiS_Pr)
9715 {
9716 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9717 unsigned short romptr;
9718
9719 if(SiS_Pr->ChipType < SIS_330) {
9720 romptr = SISGETROMW(0x114);
9721 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9722 romptr = SISGETROMW(0x11a);
9723 } else {
9724 romptr = SISGETROMW(0x194);
9725 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9726 romptr = SISGETROMW(0x19a);
9727 }
9728 return romptr;
9729 }
9730
9731 static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9732 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9733 {
9734 unsigned short index;
9735
9736 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9737 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9738 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9739 index >>= 4;
9740 index *= 3;
9741 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9742 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9743 return index;
9744 }
9745 }
9746 }
9747
9748 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9749 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9750 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9751 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9752 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9753 } else {
9754 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9755 }
9756 index--;
9757 index *= 3;
9758 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9759 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9760 return index;
9761 }
9762
9763 static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9764 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9765 {
9766 unsigned short index;
9767
9768 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9769 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9770 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9771 return index;
9772 }
9773
9774 static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9775 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9776 {
9777 unsigned short index;
9778
9779 index = 0;
9780 if(SiS_Pr->SiS_TVMode & TVSetPALTiming) index = 1;
9781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9782
9783 index <<= 1;
9784
9785 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9786 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9787 index++;
9788 }
9789
9790 return index;
9791 }
9792
9793 static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9794 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9795 {
9796 unsigned short index = 0, temp = 0;
9797
9798 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9799 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9800 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9801 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9802 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9803 index = 4;
9804 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9805 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9806 }
9807
9808 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9809 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9810 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9811 index += addme;
9812 temp++;
9813 }
9814 temp += 0x0100;
9815 }
9816 return (unsigned int)(index | (temp << 16));
9817 }
9818
9819 static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9820 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9821 {
9822 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9823 }
9824
9825 #if 0
9826 static unsigned int
9827 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9828 {
9829 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9830 }
9831 #endif
9832
9833 static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9834 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9835 {
9836 int index = 0;
9837
9838 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr625i | TVSetYPbPr625p))
9839 return 0xffff;
9840
9841 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9842 if(SiS_Pr->SiS_ROMNew) {
9843 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9844 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9845 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9846 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9847 } else {
9848 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9849 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9850 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9851 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9852 }
9853
9854 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9855
9856 return index;
9857 }
9858
9859 static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9860 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9861 {
9862 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9863 unsigned short delay=0,index,myindex,temp,romptr=0;
9864 BOOLEAN dochiptest = TRUE;
9865
9866 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9867 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9868 } else {
9869 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9870 }
9871
9872 /* Find delay (from ROM, internal tables, PCI subsystem) */
9873
9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9875
9876 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9877 romptr = GetRAMDACromptr(SiS_Pr);
9878 }
9879 if(romptr) delay = ROMAddr[romptr];
9880 else {
9881 delay = 0x04;
9882 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9883 if(IS_SIS650) {
9884 delay = 0x0a;
9885 } else if(IS_SIS740) {
9886 delay = 0x00;
9887 } else if(SiS_Pr->ChipType < SIS_330) {
9888 delay = 0x0c;
9889 } else {
9890 delay = 0x0c;
9891 }
9892 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9893 delay = 0x00;
9894 }
9895 }
9896
9897 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9898
9899 BOOLEAN gotitfrompci = FALSE;
9900
9901 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9902
9903 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9904 if(SiS_Pr->PDC != -1) {
9905 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9906 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9907 return;
9908 }
9909 } else {
9910 if(SiS_Pr->PDCA != -1) {
9911 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9912 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
9913 return;
9914 }
9915 }
9916
9917 /* Custom Panel? */
9918
9919 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
9920 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9921 delay = 0x00;
9922 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
9923 delay = 0x20;
9924 }
9925 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
9926 } else {
9927 delay = 0x0c;
9928 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
9929 delay = 0x03;
9930 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9931 delay = 0x00;
9932 }
9933 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
9934 if(IS_SIS740) delay = 0x01;
9935 else delay = 0x03;
9936 }
9937 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
9938 }
9939 return;
9940 }
9941
9942 /* This is a piece of typical SiS crap: They code the OEM LCD
9943 * delay into the code, at no defined place in the BIOS.
9944 * We now have to start doing a PCI subsystem check here.
9945 */
9946
9947 switch(SiS_Pr->SiS_CustomT) {
9948 case CUT_COMPAQ1280:
9949 case CUT_COMPAQ12802:
9950 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
9951 gotitfrompci = TRUE;
9952 dochiptest = FALSE;
9953 delay = 0x03;
9954 }
9955 break;
9956 case CUT_CLEVO1400:
9957 case CUT_CLEVO14002:
9958 gotitfrompci = TRUE;
9959 dochiptest = FALSE;
9960 delay = 0x02;
9961 break;
9962 case CUT_CLEVO1024:
9963 case CUT_CLEVO10242:
9964 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
9965 gotitfrompci = TRUE;
9966 dochiptest = FALSE;
9967 delay = 0x33;
9968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
9969 delay &= 0x0f;
9970 }
9971 break;
9972 }
9973
9974 /* Could we find it through the PCI ID? If no, use ROM or table */
9975
9976 if(!gotitfrompci) {
9977
9978 index = GetLCDPtrIndexBIOS(SiS_Pr);
9979 myindex = GetLCDPtrIndex(SiS_Pr);
9980
9981 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9982
9983 if(SiS_IsNotM650orLater(SiS_Pr)) {
9984
9985 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9986 /* Always use the second pointer on 650; some BIOSes */
9987 /* still carry old 301 data at the first location */
9988 /* romptr = SISGETROMW(0x120); */
9989 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
9990 romptr = SISGETROMW(0x122);
9991 if(!romptr) return;
9992 delay = ROMAddr[(romptr + index)];
9993 } else {
9994 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
9995 }
9996
9997 } else {
9998
9999 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10000 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10001 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10002
10003 }
10004
10005 } else if(SiS_Pr->SiS_UseROM &&
10006 (!(SiS_Pr->SiS_ROMNew)) &&
10007 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10008 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10009 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
10010 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
10011 ((romptr = GetLCDromptr(SiS_Pr)))) {
10012
10013 /* Data for 1280x1024 wrong in 301B BIOS */
10014 /* Data for 1600x1200 wrong in 301C BIOS */
10015 delay = ROMAddr[(romptr + index)];
10016
10017 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10018
10019 if(IS_SIS740) delay = 0x03;
10020 else delay = 0x00;
10021
10022 } else {
10023
10024 delay = SiS310_LCDDelayCompensation_301[myindex];
10025 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10026 if(IS_SIS740) delay = 0x01;
10027 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10028 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10029 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10030 if(IS_SIS740) delay = 0x01; /* ? */
10031 else delay = 0x03;
10032 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10033 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10034 if(IS_SIS740) delay = 0x01;
10035 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10036 }
10037
10038 }
10039
10040 } /* got it from PCI */
10041
10042 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10043 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10044 dochiptest = FALSE;
10045 }
10046
10047 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10048
10049 index = GetTVPtrIndex(SiS_Pr);
10050
10051 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10052
10053 if(SiS_IsNotM650orLater(SiS_Pr)) {
10054
10055 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10056 /* Always use the second pointer on 650; some BIOSes */
10057 /* still carry old 301 data at the first location */
10058 /* romptr = SISGETROMW(0x114); */
10059 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10060 romptr = SISGETROMW(0x11a);
10061 if(!romptr) return;
10062 delay = ROMAddr[romptr + index];
10063
10064 } else {
10065
10066 delay = SiS310_TVDelayCompensation_301B[index];
10067
10068 }
10069
10070 } else {
10071
10072 switch(SiS_Pr->SiS_CustomT) {
10073 case CUT_COMPAQ1280:
10074 case CUT_COMPAQ12802:
10075 case CUT_CLEVO1400:
10076 case CUT_CLEVO14002:
10077 delay = 0x02;
10078 dochiptest = FALSE;
10079 break;
10080 case CUT_CLEVO1024:
10081 case CUT_CLEVO10242:
10082 delay = 0x03;
10083 dochiptest = FALSE;
10084 break;
10085 default:
10086 delay = SiS310_TVDelayCompensation_651301LV[index];
10087 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10088 delay = SiS310_TVDelayCompensation_651302LV[index];
10089 }
10090 }
10091 }
10092
10093 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10094
10095 romptr = GetTVromptr(SiS_Pr);
10096 if(!romptr) return;
10097 delay = ROMAddr[romptr + index];
10098
10099 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10100
10101 delay = SiS310_TVDelayCompensation_LVDS[index];
10102
10103 } else {
10104
10105 delay = SiS310_TVDelayCompensation_301[index];
10106 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10107 if(IS_SIS740) {
10108 delay = SiS310_TVDelayCompensation_740301B[index];
10109 /* LV: use 301 data? BIOS bug? */
10110 } else {
10111 delay = SiS310_TVDelayCompensation_301B[index];
10112 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10113 }
10114 }
10115
10116 }
10117
10118 if(SiS_LCDAEnabled(SiS_Pr)) {
10119 delay &= 0x0f;
10120 dochiptest = FALSE;
10121 }
10122
10123 } else return;
10124
10125 /* Write delay */
10126
10127 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10128
10129 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10130
10131 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10132 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10133 delay &= 0x0f;
10134 delay |= 0xb0;
10135 } else if(temp == 6) {
10136 delay &= 0x0f;
10137 delay |= 0xc0;
10138 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10139 delay = 0x35;
10140 }
10141 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10142
10143 } else {
10144
10145 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10146
10147 }
10148
10149 } else { /* LVDS */
10150
10151 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10152 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10153 } else {
10154 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10155 delay <<= 4;
10156 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10157 } else {
10158 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10159 }
10160 }
10161
10162 }
10163
10164 }
10165
10166 static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10167 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10168 {
10169 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10170 unsigned short index,temp,temp1,romptr=0;
10171
10172 if(SiS_Pr->SiS_TVMode & TVSetYPbPrProg) return;
10173
10174 if(ModeNo<=0x13)
10175 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10176 else
10177 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10178
10179 temp = GetTVPtrIndex(SiS_Pr);
10180 temp >>= 1; /* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */
10181 temp1 = temp;
10182
10183 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10184 if(SiS_Pr->ChipType >= SIS_661) {
10185 temp1 = GetOEMTVPtr661(SiS_Pr);
10186 if(temp1 != 0xffff) {
10187 temp1 >>= 1;
10188 romptr = SISGETROMW(0x260);
10189 if(SiS_Pr->ChipType >= SIS_760) {
10190 romptr = SISGETROMW(0x360);
10191 }
10192 }
10193 } else if(SiS_Pr->ChipType >= SIS_330) {
10194 romptr = SISGETROMW(0x192);
10195 } else {
10196 romptr = SISGETROMW(0x112);
10197 }
10198 }
10199
10200 if(romptr) {
10201 temp1 <<= 1;
10202 temp = ROMAddr[romptr + temp1 + index];
10203 } else {
10204 temp = SiS310_TVAntiFlick1[temp][index];
10205 }
10206 temp <<= 4;
10207
10208 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10209 }
10210
10211 static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10212 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10213 {
10214 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10215 unsigned short index,temp,temp1,romptr=0;
10216
10217 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr525, 1: PAL/YPbPr625, 2: HiTV */
10218
10219 if(ModeNo <= 0x13)
10220 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10221 else
10222 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10223
10224 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10225 if(SiS_Pr->ChipType >= SIS_661) {
10226 temp1 = GetOEMTVPtr661(SiS_Pr);
10227 if(temp1 != 0xffff) {
10228 temp1 >>= 1;
10229 romptr = SISGETROMW(0x26c);
10230 if(SiS_Pr->ChipType >= SIS_760) {
10231 romptr = SISGETROMW(0x36c);
10232 }
10233 }
10234 } else if(SiS_Pr->ChipType >= SIS_330) {
10235 romptr = SISGETROMW(0x1a4);
10236 } else {
10237 romptr = SISGETROMW(0x124);
10238 }
10239 }
10240
10241 if(romptr) {
10242 temp1 <<= 1;
10243 temp = ROMAddr[romptr + temp1 + index];
10244 } else {
10245 temp = SiS310_TVEdge1[temp][index];
10246 }
10247 temp <<= 5;
10248 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10249 }
10250
10251 static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10252 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10253 {
10254 unsigned short index, temp, i, j;
10255
10256 if(ModeNo <= 0x13) {
10257 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10258 } else {
10259 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10260 }
10261
10262 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10263
10264 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10265 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10266 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10267 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10268
10269 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10270 for(i=0x35, j=0; i<=0x38; i++, j++) {
10271 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10272 }
10273 for(i=0x48; i<=0x4A; i++, j++) {
10274 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10275 }
10276 } else {
10277 for(i=0x35, j=0; i<=0x38; i++, j++) {
10278 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10279 }
10280 }
10281 }
10282
10283 static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10284 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10285 {
10286 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10287 unsigned short index,temp,i,j,resinfo,romptr=0;
10288 unsigned int lindex;
10289
10290 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10291
10292 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10293 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10294
10295 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10296 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10297 lindex <<= 2;
10298 for(j=0, i=0x31; i<=0x34; i++, j++) {
10299 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10300 }
10301 return;
10302 }
10303
10304 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10305 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10306
10307 if(ModeNo<=0x13) {
10308 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10309 } else {
10310 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10311 }
10312
10313 temp = GetTVPtrIndex(SiS_Pr);
10314 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10315 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10316 */
10317 if(SiS_Pr->SiS_UseROM) {
10318 romptr = SISGETROMW(0x116);
10319 if(SiS_Pr->ChipType >= SIS_330) {
10320 romptr = SISGETROMW(0x196);
10321 }
10322 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10323 romptr = SISGETROMW(0x11c);
10324 if(SiS_Pr->ChipType >= SIS_330) {
10325 romptr = SISGETROMW(0x19c);
10326 }
10327 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10328 romptr = SISGETROMW(0x116);
10329 if(SiS_Pr->ChipType >= SIS_330) {
10330 romptr = SISGETROMW(0x196);
10331 }
10332 }
10333 }
10334 }
10335 if(romptr) {
10336 romptr += (temp << 2);
10337 for(j=0, i=0x31; i<=0x34; i++, j++) {
10338 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10339 }
10340 } else {
10341 index = temp % 2;
10342 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10343 for(j=0, i=0x31; i<=0x34; i++, j++) {
10344 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10345 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10346 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10347 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10348 else
10349 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10350 }
10351 }
10352
10353 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10354 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPrProg))) && (ModeNo > 0x13)) {
10355 if((resinfo == SIS_RI_640x480) ||
10356 (resinfo == SIS_RI_800x600)) {
10357 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10358 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10359 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10360 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10361 } else if(resinfo == SIS_RI_1024x768) {
10362 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10363 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10364 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10365 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10366 }
10367 }
10368 }
10369 }
10370
10371 static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10372 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10373 unsigned short ModeIdIndex, unsigned short RTI)
10374 {
10375 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10376 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10377
10378 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10379 return;
10380
10381 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10382 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10383
10384 if(SiS_Pr->SiS_ROMNew) {
10385 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10386 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10387 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10388 index = 25;
10389 if(SiS_Pr->UseCustomMode) {
10390 index = SiS_Pr->CSRClock;
10391 } else if(ModeNo > 0x13) {
10392 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10393 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10394 }
10395 if(index < 25) index = 25;
10396 index = ((index / 25) - 1) << 1;
10397 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10398 index++;
10399 }
10400 romptr = SISGETROMW(0x104);
10401 delay = ROMAddr[romptr + index];
10402 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10403 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10404 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10405 } else {
10406 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10407 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10408 }
10409 return;
10410 }
10411 }
10412
10413 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10414
10415 if(SiS_Pr->UseCustomMode) delay = 0x04;
10416 else if(ModeNo <= 0x13) delay = 0x04;
10417 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10418 delay |= (delay << 8);
10419
10420 if(SiS_Pr->ChipType >= XGI_20) {
10421
10422 delay = 0x0606;
10423
10424 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10425 delay = 0x0404;
10426 if(SiS_Pr->SiS_XGIROM) {
10427 index = GetTVPtrIndex(SiS_Pr);
10428 if((romptr = SISGETROMW(0x35e))) {
10429 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10430 delay |= (delay << 8);
10431 }
10432 }
10433
10434 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10435 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10436 delay -= 0x0404;
10437 }
10438 }
10439 }
10440
10441 } else if(SiS_Pr->ChipType >= SIS_340) {
10442
10443 delay = 0x0606;
10444 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10445 delay = 0x0404;
10446 }
10447 /* TODO (eventually) */
10448
10449 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10450
10451 /* 3. TV */
10452
10453 index = GetOEMTVPtr661(SiS_Pr);
10454 if((SiS_Pr->SiS_ROMNew) && (index != 0xffff)) {
10455 romptr = SISGETROMW(0x106);
10456 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10457 delay = ROMAddr[romptr + index];
10458 } else {
10459 delay = 0x04;
10460 if(index > 3 || index == 0xffff) delay = 0;
10461 }
10462
10463 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10464
10465 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10466
10467 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10468 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10469
10470 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10471
10472 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10473 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10474 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10475
10476 } else {
10477
10478 /* TMDS: Set our own, since BIOS has no idea */
10479 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10480 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10481 switch(SiS_Pr->SiS_LCDResInfo) {
10482 case Panel_1024x768: delay = 0x0008; break;
10483 case Panel_1280x720: delay = 0x0004; break;
10484 case Panel_1280x768:
10485 case Panel_1280x768_2:delay = 0x0004; break;
10486 case Panel_1280x800:
10487 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10488 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10489 case Panel_1280x1024: delay = 0x1e04; break;
10490 case Panel_1400x1050: delay = 0x0004; break;
10491 case Panel_1600x1200: delay = 0x0400; break;
10492 case Panel_1680x1050: delay = 0x0e04; break;
10493 default:
10494 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10495 delay = 0x0008;
10496 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10497 delay = 0x1e04;
10498 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10499 delay = 0x0004;
10500 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10501 delay = 0x0400;
10502 } else
10503 delay = 0x0e04;
10504 break;
10505 }
10506 }
10507
10508 /* Override by detected or user-set values */
10509 /* (but only if, for some reason, we can't read value from BIOS) */
10510 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10511 delay = SiS_Pr->PDC & 0x1f;
10512 }
10513 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10514 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10515 }
10516
10517 }
10518
10519 }
10520
10521 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10522 delay >>= 8;
10523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10524 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10525 } else {
10526 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10527 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10528 }
10529 }
10530
10531 static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10532 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10533 {
10534 unsigned short infoflag;
10535 unsigned char temp;
10536
10537 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10538
10539 if(ModeNo <= 0x13) {
10540 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10541 } else if(SiS_Pr->UseCustomMode) {
10542 infoflag = SiS_Pr->CInfoFlag;
10543 } else {
10544 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10545 }
10546
10547 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10548 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10549 }
10550
10551 infoflag &= 0xc0;
10552
10553 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10554 temp = (infoflag >> 6) | 0x0c;
10555 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10556 temp ^= 0x04;
10557 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10558 }
10559 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10560 } else {
10561 temp = 0x30;
10562 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10563 temp |= infoflag;
10564 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10565 temp = 0;
10566 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10567 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10568 }
10569 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10570 }
10571
10572 }
10573 }
10574
10575 static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10576 SetPanelParms661(struct SiS_Private *SiS_Pr)
10577 {
10578 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10579 unsigned short romptr, temp1, temp2;
10580
10581 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10582 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10583 }
10584
10585 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10586 if(SiS_Pr->LVDSHL != -1) {
10587 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10588 }
10589 }
10590
10591 if(SiS_Pr->SiS_ROMNew) {
10592
10593 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10594 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10595 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10596 temp2 = 0xfc;
10597 if(SiS_Pr->LVDSHL != -1) {
10598 temp1 &= 0xfc;
10599 temp2 = 0xf3;
10600 }
10601 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10602 }
10603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10604 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10605 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10606 }
10607 }
10608
10609 }
10610 }
10611
10612 static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10613 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10614 {
10615 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10616 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10617 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10618 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10619 SetPanelParms661(SiS_Pr);
10620 }
10621 } else {
10622 SetDelayComp(SiS_Pr,ModeNo);
10623 }
10624
10625 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10626 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10627 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10628 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10629 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10630 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10631 }
10632 }
10633 }
10634
10635 static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10636 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10637 unsigned short ModeIdIndex, unsigned short RRTI)
10638 {
10639 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10640
10641 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10642
10643 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10644 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10645 SetPanelParms661(SiS_Pr);
10646 }
10647
10648 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10649 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10650 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10651 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10652 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10653 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10654 }
10655 }
10656 }
10657 }
10658
10659 /* FinalizeLCD
10660 * This finalizes some CRT2 registers for the very panel used.
10661 * If we have a backup if these registers, we use it; otherwise
10662 * we set the register according to most BIOSes. However, this
10663 * function looks quite different in every BIOS, so you better
10664 * pray that we have a backup...
10665 */
10666 static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10667 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10668 {
10669 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10670 unsigned short resinfo,modeflag;
10671
10672 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10673 if(SiS_Pr->SiS_ROMNew) return;
10674
10675 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10676 if(SiS_Pr->LVDSHL != -1) {
10677 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10678 }
10679 }
10680
10681 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10682 if(SiS_Pr->UseCustomMode) return;
10683
10684 switch(SiS_Pr->SiS_CustomT) {
10685 case CUT_COMPAQ1280:
10686 case CUT_COMPAQ12802:
10687 case CUT_CLEVO1400:
10688 case CUT_CLEVO14002:
10689 return;
10690 }
10691
10692 if(ModeNo <= 0x13) {
10693 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10694 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10695 } else {
10696 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10697 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10698 }
10699
10700 if(IS_SIS650) {
10701 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10702 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10703 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10704 } else {
10705 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10706 }
10707 }
10708 }
10709
10710 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10711 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10712 /* Maybe all panels? */
10713 if(SiS_Pr->LVDSHL == -1) {
10714 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10715 }
10716 return;
10717 }
10718 }
10719
10720 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10721 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10722 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10723 if(SiS_Pr->LVDSHL == -1) {
10724 /* Maybe all panels? */
10725 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10726 }
10727 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10728 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10729 if(tempch == 3) {
10730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10731 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10733 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10734 }
10735 }
10736 return;
10737 }
10738 }
10739 }
10740
10741 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10742 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10743 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10744 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10745 #ifdef SET_EMI
10746 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10747 #endif
10748 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10749 }
10750 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10751 if(SiS_Pr->LVDSHL == -1) {
10752 /* Maybe ACER only? */
10753 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10754 }
10755 }
10756 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10757 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10758 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10759 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10760 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10761 if(tempch == 0x03) {
10762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10763 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10766 }
10767 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
10768 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10769 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10771 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10772 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10775 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10777 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10778 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10780 if(ModeNo <= 0x13) {
10781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10782 if((resinfo == 0) || (resinfo == 2)) return;
10783 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10784 if((resinfo == 1) || (resinfo == 3)) return;
10785 }
10786 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10787 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10788 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10789 #if 0
10790 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10791 tempbx--;
10792 temp = tempbx & 0xff;
10793 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10794 temp = (tempbx >> 8) & 0x03;
10795 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10796 #endif
10797 }
10798 } else if(ModeNo <= 0x13) {
10799 if(ModeNo <= 1) {
10800 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10801 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10802 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10804 }
10805 if(!(modeflag & HalfDCLK)) {
10806 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10807 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10808 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10809 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10810 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10812 if(ModeNo == 0x12) {
10813 switch(tempch) {
10814 case 0:
10815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10820 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10821 break;
10822 case 2:
10823 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10824 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10825 break;
10826 case 3:
10827 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10828 break;
10829 }
10830 }
10831 }
10832 }
10833 }
10834 } else {
10835 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10836 tempcl &= 0x0f;
10837 tempbh &= 0x70;
10838 tempbh >>= 4;
10839 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10840 tempbx = (tempbh << 8) | tempbl;
10841 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10842 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10843 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10844 tempbx = 770;
10845 } else {
10846 if(tempbx > 770) tempbx = 770;
10847 if(SiS_Pr->SiS_VGAVDE < 600) {
10848 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10849 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10850 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10851 tempbx -= tempax;
10852 }
10853 }
10854 } else return;
10855 }
10856 temp = tempbx & 0xff;
10857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10858 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10859 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10860 }
10861 }
10862 }
10863
10864 #endif
10865
10866 /* ================= SiS 300 O.E.M. ================== */
10867
10868 #ifdef SIS300
10869
10870 static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10871 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10872 unsigned short RefTabIndex)
10873 {
10874 unsigned short crt2crtc=0, modeflag, myindex=0;
10875 unsigned char temp;
10876 int i;
10877
10878 if(ModeNo <= 0x13) {
10879 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10880 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10881 } else {
10882 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10883 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10884 }
10885
10886 crt2crtc &= 0x3f;
10887
10888 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10889 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10890 }
10891
10892 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10893 if(modeflag & HalfDCLK) myindex = 1;
10894
10895 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10896 for(i=0; i<7; i++) {
10897 if(barco_p1[myindex][crt2crtc][i][0]) {
10898 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10899 barco_p1[myindex][crt2crtc][i][0],
10900 barco_p1[myindex][crt2crtc][i][2],
10901 barco_p1[myindex][crt2crtc][i][1]);
10902 }
10903 }
10904 }
10905 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10906 if(temp & 0x80) {
10907 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10908 temp++;
10909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10910 }
10911 }
10912 }
10913
10914 static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10915 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10916 {
10917 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10918 unsigned short tempbx=0,romptr=0;
10919 static const unsigned char customtable300[] = {
10920 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10921 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10922 };
10923 static const unsigned char customtable630[] = {
10924 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10925 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
10926 };
10927
10928 if(SiS_Pr->ChipType == SIS_300) {
10929
10930 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
10931 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
10932 tempbx -= 2;
10933 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
10934 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10935 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
10936 }
10937 if(SiS_Pr->SiS_UseROM) {
10938 if(ROMAddr[0x235] & 0x80) {
10939 tempbx = SiS_Pr->SiS_LCDTypeInfo;
10940 if(Flag) {
10941 romptr = SISGETROMW(0x255);
10942 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10943 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
10944 if(tempbx == 0xFF) return 0xFFFF;
10945 }
10946 tempbx <<= 1;
10947 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
10948 }
10949 }
10950
10951 } else {
10952
10953 if(Flag) {
10954 if(SiS_Pr->SiS_UseROM) {
10955 romptr = SISGETROMW(0x255);
10956 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
10957 else tempbx = 0xff;
10958 } else {
10959 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
10960 }
10961 if(tempbx == 0xFF) return 0xFFFF;
10962 tempbx <<= 2;
10963 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10964 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10965 return tempbx;
10966 }
10967 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
10968 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
10969 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
10970
10971 }
10972
10973 return tempbx;
10974 }
10975
10976 static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10977 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10978 {
10979 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10980 unsigned short index,temp,romptr=0;
10981
10982 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10983
10984 if(SiS_Pr->SiS_UseROM) {
10985 if(!(ROMAddr[0x237] & 0x01)) return;
10986 if(!(ROMAddr[0x237] & 0x02)) return;
10987 romptr = SISGETROMW(0x24b);
10988 }
10989
10990 /* The Panel Compensation Delay should be set according to tables
10991 * here. Unfortunately, various BIOS versions don't care about
10992 * a uniform way using eg. ROM byte 0x220, but use different
10993 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
10994 * Thus we don't set this if the user selected a custom pdc or if
10995 * we otherwise detected a valid pdc.
10996 */
10997 if(SiS_Pr->PDC != -1) return;
10998
10999 temp = GetOEMLCDPtr(SiS_Pr, 0);
11000
11001 if(SiS_Pr->UseCustomMode)
11002 index = 0;
11003 else
11004 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11005
11006 if(SiS_Pr->ChipType != SIS_300) {
11007 if(romptr) {
11008 romptr += (temp * 2);
11009 romptr = SISGETROMW(romptr);
11010 romptr += index;
11011 temp = ROMAddr[romptr];
11012 } else {
11013 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11014 temp = SiS300_OEMLCDDelay2[temp][index];
11015 } else {
11016 temp = SiS300_OEMLCDDelay3[temp][index];
11017 }
11018 }
11019 } else {
11020 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11021 if(romptr) {
11022 romptr += (temp * 2);
11023 romptr = SISGETROMW(romptr);
11024 romptr += index;
11025 temp = ROMAddr[romptr];
11026 } else {
11027 temp = SiS300_OEMLCDDelay5[temp][index];
11028 }
11029 } else {
11030 if(SiS_Pr->SiS_UseROM) {
11031 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11032 if(romptr) {
11033 romptr += (temp * 2);
11034 romptr = SISGETROMW(romptr);
11035 romptr += index;
11036 temp = ROMAddr[romptr];
11037 } else {
11038 temp = SiS300_OEMLCDDelay4[temp][index];
11039 }
11040 } else {
11041 temp = SiS300_OEMLCDDelay4[temp][index];
11042 }
11043 }
11044 }
11045 temp &= 0x3c;
11046 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11047 }
11048
11049 static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11050 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11051 {
11052 #if 0 /* Unfinished; Data table missing */
11053 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11054 unsigned short index,temp;
11055
11056 if((SiS_Pr->SiS_UseROM) {
11057 if(!(ROMAddr[0x237] & 0x01)) return;
11058 if(!(ROMAddr[0x237] & 0x04)) return;
11059 /* No rom pointer in BIOS header! */
11060 }
11061
11062 temp = GetOEMLCDPtr(SiS_Pr, 1);
11063 if(temp == 0xFFFF) return;
11064
11065 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11066 for(i=0x14, j=0; i<=0x17; i++, j++) {
11067 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11068 }
11069 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11070
11071 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11072 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11073 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11074 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11075 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11076 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11077 }
11078 #endif
11079 }
11080
11081 static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)11082 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11083 {
11084 unsigned short index;
11085
11086 index = 0;
11087 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11088 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11090 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11091 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11092 } else {
11093 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11094 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11095 }
11096 return index;
11097 }
11098
11099 static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11100 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11101 {
11102 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11103 unsigned short index,temp,romptr=0;
11104
11105 if(SiS_Pr->SiS_UseROM) {
11106 if(!(ROMAddr[0x238] & 0x01)) return;
11107 if(!(ROMAddr[0x238] & 0x02)) return;
11108 romptr = SISGETROMW(0x241);
11109 }
11110
11111 temp = GetOEMTVPtr(SiS_Pr);
11112
11113 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11114
11115 if(romptr) {
11116 romptr += (temp * 2);
11117 romptr = SISGETROMW(romptr) + index;
11118 temp = ROMAddr[romptr];
11119 } else {
11120 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11121 temp = SiS300_OEMTVDelay301[temp][index];
11122 } else {
11123 temp = SiS300_OEMTVDelayLVDS[temp][index];
11124 }
11125 }
11126 temp &= 0x3c;
11127 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11128 }
11129
11130 static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11131 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11132 {
11133 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11134 unsigned short index,temp,romptr=0;
11135
11136 if(SiS_Pr->SiS_UseROM) {
11137 if(!(ROMAddr[0x238] & 0x01)) return;
11138 if(!(ROMAddr[0x238] & 0x04)) return;
11139 romptr = SISGETROMW(0x243);
11140 }
11141
11142 temp = GetOEMTVPtr(SiS_Pr);
11143
11144 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11145
11146 if(romptr) {
11147 romptr += (temp * 2);
11148 romptr = SISGETROMW(romptr);
11149 romptr += index;
11150 temp = ROMAddr[romptr];
11151 } else {
11152 temp = SiS300_OEMTVFlicker[temp][index];
11153 }
11154 temp &= 0x70;
11155 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11156 }
11157
11158 static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11159 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11160 {
11161 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11162 unsigned short index,i,j,temp,romptr=0;
11163
11164 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11165
11166 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11167
11168 if(SiS_Pr->SiS_UseROM) {
11169 if(!(ROMAddr[0x238] & 0x01)) return;
11170 if(!(ROMAddr[0x238] & 0x08)) return;
11171 romptr = SISGETROMW(0x245);
11172 }
11173
11174 temp = GetOEMTVPtr(SiS_Pr);
11175
11176 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11177
11178 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11179 for(i=0x31, j=0; i<=0x34; i++, j++) {
11180 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11181 }
11182 } else {
11183 if(romptr) {
11184 romptr += (temp * 2);
11185 romptr = SISGETROMW(romptr);
11186 romptr += (index * 4);
11187 for(i=0x31, j=0; i<=0x34; i++, j++) {
11188 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11189 }
11190 } else {
11191 for(i=0x31, j=0; i<=0x34; i++, j++) {
11192 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11193 }
11194 }
11195 }
11196 }
11197
11198 static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11199 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11200 {
11201 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11202 unsigned short index,temp,i,j,romptr=0;
11203
11204 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11205
11206 if(SiS_Pr->SiS_UseROM) {
11207 if(!(ROMAddr[0x238] & 0x01)) return;
11208 if(!(ROMAddr[0x238] & 0x10)) return;
11209 romptr = SISGETROMW(0x247);
11210 }
11211
11212 temp = GetOEMTVPtr(SiS_Pr);
11213
11214 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11215 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11216 /* NTSCJ uses NTSC filters */
11217
11218 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11219
11220 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11221 for(i=0x35, j=0; i<=0x38; i++, j++) {
11222 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11223 }
11224 for(i=0x48; i<=0x4A; i++, j++) {
11225 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11226 }
11227 } else {
11228 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11229 romptr += (temp * 2);
11230 romptr = SISGETROMW(romptr);
11231 romptr += (index * 4);
11232 for(i=0x35, j=0; i<=0x38; i++, j++) {
11233 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11234 }
11235 } else {
11236 for(i=0x35, j=0; i<=0x38; i++, j++) {
11237 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11238 }
11239 }
11240 }
11241 }
11242
11243 static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11244 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11245 {
11246 unsigned short ModeIdIndex;
11247 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11248
11249 if(*ModeNo <= 5) *ModeNo |= 1;
11250
11251 for(ModeIdIndex=0; ; ModeIdIndex++) {
11252 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11253 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11254 }
11255
11256 if(*ModeNo != 0x07) {
11257 if(*ModeNo > 0x03) return ModeIdIndex;
11258 if(VGAINFO & 0x80) return ModeIdIndex;
11259 ModeIdIndex++;
11260 }
11261
11262 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11263 /* else 350 lines */
11264 return ModeIdIndex;
11265 }
11266
11267 static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11268 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11269 unsigned short RefTableIndex)
11270 {
11271 unsigned short OEMModeIdIndex = 0;
11272
11273 if(!SiS_Pr->UseCustomMode) {
11274 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11275 if(!(OEMModeIdIndex)) return;
11276 }
11277
11278 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11279 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11280 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11281 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11282 }
11283 }
11284 if(SiS_Pr->UseCustomMode) return;
11285 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11286 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11287 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11288 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11289 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11290 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11291 }
11292 }
11293 }
11294 #endif
11295
11296